diff --git a/.gitignore b/.gitignore index 66b179d245..0642927510 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ cargo-registry target +build Cargo.lock .idea +.venv +.cache .DS_Store -Podfile.lock - +Podfile.lock \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index b51b21a540..e95f284856 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "indy-sdk" +name = "indy" version = "0.1.1" authors = [ "Sergej Pupykin ", @@ -29,6 +29,7 @@ pair_milagro = ["milagro-crypto"] pair_amcl = ["amcl"] hash_openssl = ["openssl"] local_nodes_pool = [] +interoperability_tests = [] [dependencies] amcl = { version = "0.1.0", optional = true } @@ -47,7 +48,7 @@ serde_json = "1.0" serde_derive = "1.0" sodiumoxide = {version = "0.0.14", optional = true} time = "0.1.36" -zmq-pw = "0.9.5" +zmq-pw = "0.9.7" lazy_static = "0.2" byteorder = "1.0.0" [dependencies.uuid] diff --git a/Jenkinsfile b/Jenkinsfile index d74654c3fa..cc35f7be2d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,13 +12,26 @@ try { // 1. TEST stage('Test') { - parallel 'ubuntu-test': { + + def tests = [:] + + tests['ubuntu-test'] = { node('ubuntu') { stage('Ubuntu Test') { testUbuntu() } } } + + tests['redhat-test'] = { + node('ubuntu') { + stage('RedHat Test') { + testRedHat() + } + } + } + + parallel(tests) } if (!publishBranch) { @@ -33,6 +46,20 @@ try { } } + // 3. PUBLISH RPMS TO repo.evernym.com + stage('Publish RPM Files') { + node('ubuntu') { + publishRpmFiles() + } + } + + // 4. PUBLISH DEB TO repo.evernym.com + stage('Publish DEB Files') { + node('ubuntu') { + publishDebFiles() + } + } + } catch (e) { currentBuild.result = "FAILED" node('ubuntu-master') { @@ -51,66 +78,78 @@ try { } } -def testUbuntu() { +def testPipeline(file, env_name, run_interoperability_tests) { def poolInst def network_name = "pool_network" try { - echo 'Ubuntu Test: Checkout csm' + echo "${env_name} Test: Checkout csm" checkout scm - echo "Ubuntu Test: Create docker network (${network_name}) for nodes pool and test image" + echo "${env_name} Test: Create docker network (${network_name}) for nodes pool and test image" sh "docker network create --subnet=10.0.0.0/8 ${network_name}" - echo 'Ubuntu Test: Build docker image for nodes pool' + echo "${env_name} Test: Build docker image for nodes pool" def poolEnv = dockerHelpers.build('indy_pool', 'ci/indy-pool.dockerfile ci') - echo 'Ubuntu Test: Run nodes pool' + echo "${env_name} Test: Run nodes pool" poolInst = poolEnv.run("--ip=\"10.0.0.2\" --network=${network_name}") - echo 'Ubuntu Test: Build docker image' - def testEnv = dockerHelpers.build(name) + echo "${env_name} Test: Build docker image" + def testEnv = dockerHelpers.build(name, file) testEnv.inside("--ip=\"10.0.0.3\" --network=${network_name}") { - echo 'Ubuntu Test: Test' + echo "${env_name} Test: Test" + sh 'chmod -R 777 /home/indy/' + sh 'cargo update' - sh 'cargo update' - - try { - sh 'RUST_BACKTRACE=1 RUST_TEST_THREADS=1 cargo test' - /* TODO FIXME restore after xunit will be fixed - sh 'RUST_TEST_THREADS=1 cargo test-xunit' - */ - } - finally { - /* TODO FIXME restore after xunit will be fixed - junit 'test-results.xml' + try { + if (run_interoperability_tests) { + sh 'RUST_BACKTRACE=1 RUST_TEST_THREADS=1 cargo test --features "interoperability_tests"' + } + else { + sh 'RUST_BACKTRACE=1 RUST_TEST_THREADS=1 cargo test' + } + /* TODO FIXME restore after xunit will be fixed + sh 'RUST_TEST_THREADS=1 cargo test-xunit' */ - } + } + finally { + /* TODO FIXME restore after xunit will be fixed + junit 'test-results.xml' + */ + } } } finally { - echo 'Ubuntu Test: Cleanup' + echo "${env_name} Test: Cleanup" try { sh "docker network inspect ${network_name}" - } catch (ignore) { + } catch (err) { + echo "${env_name} Tests: error while inspect network ${network_name} - ${err}" } try { - if (poolInst) { - echo 'Ubuntu Test: stop pool' - poolInst.stop() - } + echo "${env_name} Test: stop pool" + poolInst.stop() } catch (err) { - echo "Ubuntu Tests: error while stop pool ${err}" + echo "${env_name} Tests: error while stop pool ${err}" } try { - echo "Ubuntu Test: remove pool network ${network_name}" + echo "${env_name} Test: remove pool network ${network_name}" sh "docker network rm ${network_name}" } catch (err) { - echo "Ubuntu Test: error while delete ${network_name} - ${err}" + echo "${env_name} Test: error while delete ${network_name} - ${err}" } step([$class: 'WsCleanup']) } } +def testUbuntu() { + testPipeline("ci/ubuntu.dockerfile ci", "Ubuntu", true) +} + +def testRedHat() { + testPipeline("ci/amazon.dockerfile ci", "RedHat", false) +} + def publishToCargo() { try { echo 'Publish to Cargo: Checkout csm' @@ -140,4 +179,54 @@ def publishToCargo() { echo 'Publish to cargo: Cleanup' step([$class: 'WsCleanup']) } +} + +def publishRpmFiles() { + try { + echo 'Publish Rpm files: Checkout csm' + checkout scm + + echo 'Publish Rpm: Build docker image' + def testEnv = dockerHelpers.build(name, 'ci/amazon.dockerfile ci') + + testEnv.inside('-u 0:0') { + + commit = sh(returnStdout: true, script: 'git rev-parse HEAD').trim() + + sh 'chmod -R 777 ci' + + withCredentials([file(credentialsId: 'EvernymRepoSSHKey', variable: 'evernym_repo_key')]) { + sh "./ci/rpm-build-and-upload.sh $commit $evernym_repo_key" + } + } + } + finally { + echo 'Publish RPM: Cleanup' + step([$class: 'WsCleanup']) + } +} + +def publishDebFiles() { + try { + echo 'Publish Deb files: Checkout csm' + checkout scm + + echo 'Publish Deb: Build docker image' + def testEnv = dockerHelpers.build(name) + + testEnv.inside('-u 0:0') { + + commit = sh(returnStdout: true, script: 'git rev-parse HEAD').trim() + + sh 'chmod -R 777 ci' + + withCredentials([file(credentialsId: 'EvernymRepoSSHKey', variable: 'evernym_repo_key')]) { + sh "./ci/deb-build-and-upload.sh $commit $evernym_repo_key" + } + } + } + finally { + echo 'Publish Deb: Cleanup' + step([$class: 'WsCleanup']) + } } \ No newline at end of file diff --git a/ci/amazon.dockerfile b/ci/amazon.dockerfile index 182a54bfed..bbf3f9e637 100644 --- a/ci/amazon.dockerfile +++ b/ci/amazon.dockerfile @@ -6,15 +6,20 @@ RUN \ yum clean all \ && yum upgrade -y \ && yum groupinstall -y "Development Tools" \ + && yum install -y epel-release \ + && yum-config-manager --enable epel \ && yum install -y \ wget \ cmake \ pkgconfig \ openssl-devel \ - sqlite-devel + sqlite-devel \ + libsodium-devel \ + spectool + RUN cd /tmp && \ - curl https://download.libsodium.org/libsodium/releases/libsodium-1.0.12.tar.gz | tar -xz && \ + curl https://download.libsodium.org/libsodium/releases/libsodium-1.0.12.tar.gz | tar -xz && \ cd /tmp/libsodium-1.0.12 && \ ./configure && \ make && \ @@ -24,15 +29,6 @@ RUN cd /tmp && \ ENV PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib -RUN cd /tmp && \ - wget https://github.com/zeromq/libzmq/releases/download/v4.2.2/zeromq-4.2.2.tar.gz && \ - tar xfz zeromq-4.2.2.tar.gz && rm zeromq-4.2.2.tar.gz && \ - cd /tmp/zeromq-4.2.2 && \ - ./configure && \ - make && \ - make install && \ - rm -rf /tmp/zeromq-4.2.2 - ENV RUST_ARCHIVE=rust-1.16.0-x86_64-unknown-linux-gnu.tar.gz ENV RUST_DOWNLOAD_URL=https://static.rust-lang.org/dist/$RUST_ARCHIVE @@ -50,4 +46,6 @@ ENV PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/.ca RUN useradd -ms /bin/bash -u $uid indy USER indy -WORKDIR /home/indy +RUN cargo install --git https://github.com/DSRCorporation/cargo-test-xunit + +WORKDIR /home/sorvin \ No newline at end of file diff --git a/ci/deb-build-and-upload.sh b/ci/deb-build-and-upload.sh new file mode 100755 index 0000000000..a65b0b508f --- /dev/null +++ b/ci/deb-build-and-upload.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +if [ "$1" = "--help" ] ; then + echo "Usage: $0 $1 " +fi + +commit="$1" +key="$2" + +version=$(wget -q https://raw.githubusercontent.com/hyperledger/indy-sdk/$commit/Cargo.toml -O - | grep -E '^version =' | head -n1 | cut -f2 -d= | tr -d '" ') + +[ -z $version ] && exit 1 +[ -z $commit ] && exit 2 +[ -z $key ] && exit 3 + +dpkg-buildpackage + +cat <> /etc/apt/sources.lis RUN useradd -ms /bin/bash -u $uid sovrin RUN apt-get update -y && apt-get install -y \ - python3-state-trie=0.2.3 \ - python3-stp=0.2.40 \ - python3-ledger=0.3.48 \ - python3-plenum=0.4.19 \ - python3-sovrin-common=0.3.17 \ - sovrin-node=0.4.13 + indy-plenum=0.4.44 \ + indy-anoncreds=0.4.12 \ + indy-node=0.4.29 RUN echo '[supervisord]\n\ logfile = /tmp/supervisord.log\n\ diff --git a/ci/java.dockerfile b/ci/java.dockerfile new file mode 100644 index 0000000000..ab75104456 --- /dev/null +++ b/ci/java.dockerfile @@ -0,0 +1,21 @@ +FROM ubuntu:16.04 + +ARG uid=1000 + +RUN apt-get update && apt-get install openjdk-8-jdk -y + +ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64 + +RUN apt-get install -y \ + maven \ + gdebi \ + apt-utils + +ADD https://repo.evernym.com/deb/indy-sdk/0.1.1/indy-sdk_0.1.1_amd64.deb . + +RUN gdebi -n indy-sdk_0.1.1_amd64.deb + +RUN useradd -ms /bin/bash -u $uid indy +USER indy + +WORKDIR /home/indy \ No newline at end of file diff --git a/ci/python.dockerfile b/ci/python.dockerfile new file mode 100644 index 0000000000..0005b6d7ae --- /dev/null +++ b/ci/python.dockerfile @@ -0,0 +1,28 @@ +FROM ubuntu:16.04 + +ARG uid=1000 + +RUN apt-get update && \ + apt-get install -y \ + gdebi \ + apt-utils \ + software-properties-common + +RUN add-apt-repository ppa:jonathonf/python-3.6 + +RUN apt-get update && \ + apt-get install -y \ + python3.6 \ + python3-pip + +ADD https://repo.evernym.com/deb/indy-sdk/0.1.1/indy-sdk_0.1.1_amd64.deb . + +RUN gdebi -n indy-sdk_0.1.1_amd64.deb + +RUN useradd -ms /bin/bash -u $uid indy +USER indy + +WORKDIR /home/indy + + + diff --git a/ci/rpm-build-and-upload.sh b/ci/rpm-build-and-upload.sh new file mode 100755 index 0000000000..e8269df124 --- /dev/null +++ b/ci/rpm-build-and-upload.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +if [ "$1" = "--help" ] ; then + echo "Usage: $0 $1 " +fi + +commit="$1" +key="$2" + +mkdir -p /usr/src/rpm/SOURCES/ + +version=$(wget -q https://raw.githubusercontent.com/hyperledger/indy-sdk/$commit/Cargo.toml -O - | grep -E '^version =' | head -n1 | cut -f2 -d= | tr -d '" ') + +[ -z $version ] && exit 1 +[ -z $commit ] && exit 2 +[ -z $key ] && exit 3 + +cd ci + +sed \ + -e "s|@commit@|$commit|g" \ + -e "s|@version@|$version.$commit|g" \ + indy-sdk.spec.in >indy-sdk.spec + +chown root.root indy-sdk.spec + +spectool -g -R indy-sdk.spec || exit 4 +rpmbuild -ba indy-sdk.spec || exit 5 + +cat <indy-sdk.spec - -spectool -g -R indy-sdk.spec || exit 3 -rpmbuild -ba indy-sdk.spec || exit 4 diff --git a/ci/ubuntu.dockerfile b/ci/ubuntu.dockerfile index 3bf0b84000..ac35d9ba22 100644 --- a/ci/ubuntu.dockerfile +++ b/ci/ubuntu.dockerfile @@ -5,13 +5,31 @@ ARG uid=1000 RUN apt-get update && \ apt-get install -y \ pkg-config \ - libzmq3-dev \ libssl-dev \ + libgmp3-dev \ curl \ build-essential \ libsqlite3-dev \ libsodium-dev \ - cmake + cmake \ + git \ + python3.5 \ + python3-pip \ + python-setuptools \ + apt-transport-https \ + ca-certificates \ + debhelper \ + wget + +RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BD33704C +RUN echo "deb https://repo.evernym.com/deb xenial master" >> /etc/apt/sources.list +RUN apt-get update -y && apt-get install -y \ + python3-charm-crypto + +RUN pip3 install -U \ + pip \ + setuptools \ + virtualenv ENV RUST_ARCHIVE=rust-1.16.0-x86_64-unknown-linux-gnu.tar.gz ENV RUST_DOWNLOAD_URL=https://static.rust-lang.org/dist/$RUST_ARCHIVE @@ -32,4 +50,16 @@ USER indy RUN cargo install --git https://github.com/DSRCorporation/cargo-test-xunit -WORKDIR /home/sovrin \ No newline at end of file +WORKDIR /home/indy + +RUN git clone https://github.com/hyperledger/indy-anoncreds.git +RUN virtualenv -p python3.5 /home/indy/test +RUN cp -r /usr/local/lib/python3.5/dist-packages/Charm_Crypto-0.0.0.egg-info /home/indy/test/lib/python3.5/site-packages/Charm_Crypto-0.0.0.egg-info +RUN cp -r /usr/local/lib/python3.5/dist-packages/charm /home/indy/test/lib/python3.5/site-packages/charm +USER root +RUN ln -sf /home/indy/test/bin/python /usr/local/bin/python3 +RUN ln -sf /home/indy/test/bin/pip /usr/local/bin/pip3 +USER indy +RUN pip3 install \ + /home/indy/indy-anoncreds \ + pytest \ No newline at end of file diff --git a/debian/control b/debian/control index d335f8e522..1a7fe39a10 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: indy-sdk Section: devel Priority: optional Maintainer: Hyperledger -Build-Depends: libssl-dev, libsodium-dev, libsqlite0-dev +Build-Depends: libssl-dev, libsodium-dev, libsqlite3-dev Standards-Version: 0.1.1 Vcs-Git: https://github.com/hyperledger/indy-sdk/ Vcs-Browser: https://github.com/hyperledger/indy-sdk/ @@ -10,7 +10,7 @@ Vcs-Browser: https://github.com/hyperledger/indy-sdk/ Package: indy-sdk Architecture: amd64 -Depends: libssl, libsodium, libsqlite0 +Depends: libssl1.0.0, libsodium18, libsqlite0 Suggests: build-essential Description: This is the official SDK for Hyperledger Indy, which provides a distributed-ledger-based foundation for self-sovereign identity. diff --git a/debian/rules b/debian/rules index 304d0abf88..d06c47ff6a 100755 --- a/debian/rules +++ b/debian/rules @@ -1,7 +1,7 @@ #!/usr/bin/make -f # -export PATH=/usr/local/bin:/usr/bin:/bin +export PATH=/usr/local/bin:/usr/bin:/bin:/root/.cargo/bin %: dh $@ diff --git a/doc/mac-build.md b/doc/mac-build.md index daede3e5b3..4dc5f64b53 100644 --- a/doc/mac-build.md +++ b/doc/mac-build.md @@ -1,26 +1,27 @@ # Setup Indy SDK build environment for MacOS 1. Install Rust and rustup (https://www.rust-lang.org/install.html). -1. Install required native libraries and utilities +2. Install required native libraries and utilities ``` brew install libsodium - brew install zeromq + brew install automake + brew install autoconf brew install cmake brew install openssl ``` -1. Setup environment variables: +3. Setup environment variables: ``` export PKG_CONFIG_ALLOW_CROSS=1 export CARGO_INCREMENTAL=1 export RUST_LOG=indy=trace export RUST_TEST_THREADS=1 ``` -1. Setup OPENSSL_DIR variable: path to installed openssl library +4. Setup OPENSSL_DIR variable: path to installed openssl library ``` export OPENSSL_DIR=/usr/local/Cellar/openssl/1.0.2k ``` -1. Checkout and build the library: +5. Checkout and build the library: ``` git clone https://github.com/hyperledger/indy-sdk.git cd ./indy-sdk diff --git a/doc/rhel-build.md b/doc/rhel-build.md index efc107c0a5..15191ca7ea 100644 --- a/doc/rhel-build.md +++ b/doc/rhel-build.md @@ -28,18 +28,7 @@ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ``` -1. Build and install modern version of libzmq from sources: - ``` - cd /tmp - wget https://github.com/zeromq/libzmq/releases/download/v4.2.2/zeromq-4.2.2.tar.gz - tar xfz zeromq-4.2.2.tar.gz && rm zeromq-4.2.2.tar.gz - cd /tmp/zeromq-4.2.2 - ./configure - make - make install - rm -rf /tmp/zeromq-4.2.2 - ``` 1. Checkout and build the library: ``` diff --git a/doc/ubuntu-build.md b/doc/ubuntu-build.md index 20acad131b..e5562dccdc 100644 --- a/doc/ubuntu-build.md +++ b/doc/ubuntu-build.md @@ -9,7 +9,6 @@ build-essential \ pkg-config \ cmake \ - libzmq3-dev \ libssl-dev \ libsqlite3-dev \ libsodium-dev diff --git a/include/indy_mod.h b/include/indy_mod.h index 01905bbb72..44c3a6e395 100644 --- a/include/indy_mod.h +++ b/include/indy_mod.h @@ -11,101 +11,101 @@ typedef enum CommonInvalidParam1 = 100, // Caller passed invalid value as param 2 (null, invalid json and etc..) - CommonInvalidParam2, + CommonInvalidParam2 = 101, // Caller passed invalid value as param 3 (null, invalid json and etc..) - CommonInvalidParam3, + CommonInvalidParam3 = 102, // Caller passed invalid value as param 4 (null, invalid json and etc..) - CommonInvalidParam4, + CommonInvalidParam4 = 103, // Caller passed invalid value as param 5 (null, invalid json and etc..) - CommonInvalidParam5, + CommonInvalidParam5 = 104, // Caller passed invalid value as param 6 (null, invalid json and etc..) - CommonInvalidParam6, + CommonInvalidParam6 = 105, // Caller passed invalid value as param 7 (null, invalid json and etc..) - CommonInvalidParam7, + CommonInvalidParam7 = 106, // Caller passed invalid value as param 8 (null, invalid json and etc..) - CommonInvalidParam8, + CommonInvalidParam8 = 107, // Caller passed invalid value as param 9 (null, invalid json and etc..) - CommonInvalidParam9, + CommonInvalidParam9 = 108, // Caller passed invalid value as param 10 (null, invalid json and etc..) - CommonInvalidParam10, + CommonInvalidParam10 = 109, // Caller passed invalid value as param 11 (null, invalid json and etc..) - CommonInvalidParam11, + CommonInvalidParam11 = 110, // Caller passed invalid value as param 12 (null, invalid json and etc..) - CommonInvalidParam12, + CommonInvalidParam12 = 111, // Invalid library state was detected in runtime. It signals library bug - CommonInvalidState, + CommonInvalidState = 112, // Object (json, config, key, claim and etc...) passed by library caller has invalid structure - CommonInvalidStructure, + CommonInvalidStructure = 113, // IO Error - CommonIOError, + CommonIOError = 114, // Wallet errors // Caller passed invalid wallet handle WalletInvalidHandle = 200, // Unknown type of wallet was passed on create_wallet - WalletUnknownTypeError, + WalletUnknownTypeError = 201, // Attempt to register already existing wallet type - WalletTypeAlreadyRegisteredError, + WalletTypeAlreadyRegisteredError = 202, // Attempt to create wallet with name used for another exists wallet - WalletAlreadyExistsError, + WalletAlreadyExistsError = 203, // Requested entity id isn't present in wallet - WalletNotFoundError, + WalletNotFoundError = 204, // Trying to use wallet with pool that has different name - WalletIncompatiblePoolError, + WalletIncompatiblePoolError = 205, // Trying to open wallet that was opened already - WalletAlreadyOpenedError, + WalletAlreadyOpenedError = 206, // Ledger errors // Trying to open pool ledger that wasn't created before PoolLedgerNotCreatedError = 300, // Caller passed invalid pool ledger handle - PoolLedgerInvalidPoolHandle, + PoolLedgerInvalidPoolHandle = 301, // Pool ledger terminated - PoolLedgerTerminated, + PoolLedgerTerminated = 302, // No concensus during ledger operation - LedgerNoConsensusError, + LedgerNoConsensusError = 303, // Attempt to send unknown or incomplete transaction message - LedgerInvalidTransaction, + LedgerInvalidTransaction = 304, // Attempt to send transaction without the necessary privileges - LedgerSecurityError, + LedgerSecurityError = 305, // Revocation registry is full and creation of new registry is necessary AnoncredsRevocationRegistryFullError = 400, - AnoncredsInvalidUserRevocIndex, + AnoncredsInvalidUserRevocIndex = 401, - AnoncredsAccumulatorIsFull, + AnoncredsAccumulatorIsFull = 402, - AnoncredsNotIssuedError, + AnoncredsNotIssuedError = 403, // Attempt to generate master secret with dupplicated name - AnoncredsMasterSecretDuplicateNameError, + AnoncredsMasterSecretDuplicateNameError = 404, - AnoncredsProofRejected, + AnoncredsProofRejected = 405, // Signus errors // Unknown format of DID entity keys diff --git a/include/indy_wallet.h b/include/indy_wallet.h index 2a8f3f34c5..08847e7875 100644 --- a/include/indy_wallet.h +++ b/include/indy_wallet.h @@ -154,30 +154,6 @@ extern "C" { const char* credentials, void (*fn)(indy_handle_t xcommand_handle, indy_error_t err) ); - - /// Sets a seq_no (the corresponding Ledger transaction unique sequence number) for the a value - /// in a secure wallet identified by the given string. - /// The string identifying the value in the wallet is returned when the value is stored in the wallet. - /// - /// #Params - /// wallet_handle: wallet handler (created by open_wallet). - /// command_handle: command handle to map callback to user context. - /// wallet_key: unique string identifying the value in the wallet. - /// seq_no: transaction sequence number. - /// - /// #Returns - /// Error code - /// - /// #Errors - /// Common* - /// Wallet* - - extern indy_error_t indy_wallet_set_seq_no_for_value(indy_handle_t command_handle, - indy_handle_t wallet_handle, - const char* wallet_key, - indy_i32_t seq_no, - void (*fn)(indy_handle_t xcommand_handle, indy_error_t err) - ); #ifdef __cplusplus } diff --git a/indy-sdk.spec b/indy-sdk.spec new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/api/agent.rs b/src/api/agent.rs index c7e4786c70..bae4bb1dcd 100644 --- a/src/api/agent.rs +++ b/src/api/agent.rs @@ -131,10 +131,10 @@ pub extern fn indy_agent_listen(command_handle: i32, message_cb: Option) -> ErrorCode { - check_useful_c_str!(endpoint, ErrorCode::CommonInvalidParam3); - check_useful_c_callback!(listener_cb, ErrorCode::CommonInvalidParam4); - check_useful_c_callback!(connection_cb, ErrorCode::CommonInvalidParam5); - check_useful_c_callback!(message_cb, ErrorCode::CommonInvalidParam6); + check_useful_c_str!(endpoint, ErrorCode::CommonInvalidParam2); + check_useful_c_callback!(listener_cb, ErrorCode::CommonInvalidParam3); + check_useful_c_callback!(connection_cb, ErrorCode::CommonInvalidParam4); + check_useful_c_callback!(message_cb, ErrorCode::CommonInvalidParam5); let cmd = Command::Agent(AgentCommand::Listen( endpoint, diff --git a/src/api/anoncreds.rs b/src/api/anoncreds.rs index b3f1b2a01d..8a220d53e4 100644 --- a/src/api/anoncreds.rs +++ b/src/api/anoncreds.rs @@ -201,7 +201,6 @@ pub extern fn indy_issuer_create_claim(command_handle: i32, /// #Params /// wallet_handle: wallet handler (created by open_wallet). /// command_handle: command handle to map callback to user context. -/// issuer_did: a DID of the issuer signing transactions to the Ledger /// revoc_reg_seq_no: seq no of a revocation registry transaction in Ledger /// user_revoc_index: index of the user in the revocation registry /// cb: Callback that takes command result as parameter. @@ -633,6 +632,7 @@ pub extern fn indy_prover_get_claims_for_proof_req(command_handle: i32, /// "claim3_uuid_in_wallet": , /// } /// +/// master_secret_name: the name of the master secret stored in the wallet /// claim_def_jsons: all claim definition jsons participating in the proof request /// { /// "claim1_uuid_in_wallet": , diff --git a/src/api/ledger.rs b/src/api/ledger.rs index 0bf2c4f8e6..f509cae1b9 100644 --- a/src/api/ledger.rs +++ b/src/api/ledger.rs @@ -143,7 +143,7 @@ pub extern fn indy_build_get_ddo_request(command_handle: i32, /// submitter_did: Id of Identity stored in secured Wallet. /// target_did: Id of Identity stored in secured Wallet. /// verkey: verification key -/// alias +/// alias: alias /// role: Role of a user NYM record /// cb: Callback that takes command result as parameter. /// diff --git a/src/api/mod.rs b/src/api/mod.rs index aa802e6798..b3d385eb8e 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -21,101 +21,101 @@ pub enum ErrorCode CommonInvalidParam1 = 100, // Caller passed invalid value as param 2 (null, invalid json and etc..) - CommonInvalidParam2, + CommonInvalidParam2 = 101, // Caller passed invalid value as param 3 (null, invalid json and etc..) - CommonInvalidParam3, + CommonInvalidParam3 = 102, // Caller passed invalid value as param 4 (null, invalid json and etc..) - CommonInvalidParam4, + CommonInvalidParam4 = 103, // Caller passed invalid value as param 5 (null, invalid json and etc..) - CommonInvalidParam5, + CommonInvalidParam5 = 104, // Caller passed invalid value as param 6 (null, invalid json and etc..) - CommonInvalidParam6, + CommonInvalidParam6 = 105, // Caller passed invalid value as param 7 (null, invalid json and etc..) - CommonInvalidParam7, + CommonInvalidParam7 = 106, // Caller passed invalid value as param 8 (null, invalid json and etc..) - CommonInvalidParam8, + CommonInvalidParam8 = 107, // Caller passed invalid value as param 9 (null, invalid json and etc..) - CommonInvalidParam9, + CommonInvalidParam9 = 108, // Caller passed invalid value as param 10 (null, invalid json and etc..) - CommonInvalidParam10, + CommonInvalidParam10 = 109, // Caller passed invalid value as param 11 (null, invalid json and etc..) - CommonInvalidParam11, + CommonInvalidParam11 = 110, // Caller passed invalid value as param 11 (null, invalid json and etc..) - CommonInvalidParam12, + CommonInvalidParam12 = 111, // Invalid library state was detected in runtime. It signals library bug - CommonInvalidState, + CommonInvalidState = 112, // Object (json, config, key, claim and etc...) passed by library caller has invalid structure - CommonInvalidStructure, + CommonInvalidStructure = 113, // IO Error - CommonIOError, + CommonIOError = 114, // Wallet errors // Caller passed invalid wallet handle WalletInvalidHandle = 200, // Unknown type of wallet was passed on create_wallet - WalletUnknownTypeError, + WalletUnknownTypeError = 201, // Attempt to register already existing wallet type - WalletTypeAlreadyRegisteredError, + WalletTypeAlreadyRegisteredError = 202, // Attempt to create wallet with name used for another exists wallet - WalletAlreadyExistsError, + WalletAlreadyExistsError = 203, // Requested entity id isn't present in wallet - WalletNotFoundError, + WalletNotFoundError = 204, // Trying to use wallet with pool that has different name - WalletIncompatiblePoolError, + WalletIncompatiblePoolError = 205, // Trying to open wallet that was opened already - WalletAlreadyOpenedError, + WalletAlreadyOpenedError = 206, // Ledger errors // Trying to open pool ledger that wasn't created before PoolLedgerNotCreatedError = 300, // Caller passed invalid pool ledger handle - PoolLedgerInvalidPoolHandle, + PoolLedgerInvalidPoolHandle = 301, // Pool ledger terminated - PoolLedgerTerminated, + PoolLedgerTerminated = 302, // No concensus during ledger operation - LedgerNoConsensusError, + LedgerNoConsensusError = 303, // Attempt to send unknown or incomplete transaction message - LedgerInvalidTransaction, + LedgerInvalidTransaction = 304, // Attempt to send transaction without the necessary privileges - LedgerSecurityError, + LedgerSecurityError = 305, // Revocation registry is full and creation of new registry is necessary AnoncredsRevocationRegistryFullError = 400, - AnoncredsInvalidUserRevocIndex, + AnoncredsInvalidUserRevocIndex = 401, - AnoncredsAccumulatorIsFull, + AnoncredsAccumulatorIsFull = 402, - AnoncredsNotIssuedError, + AnoncredsNotIssuedError = 403, // Attempt to generate master secret with dupplicated name - AnoncredsMasterSecretDuplicateNameError, + AnoncredsMasterSecretDuplicateNameError = 404, - AnoncredsProofRejected, + AnoncredsProofRejected = 405, // Signus errors // Unknown format of DID entity keys diff --git a/src/api/signus.rs b/src/api/signus.rs index 24871adb0d..341b0347d6 100644 --- a/src/api/signus.rs +++ b/src/api/signus.rs @@ -211,8 +211,7 @@ pub extern fn indy_sign(command_handle: i32, /// command_handle: command handle to map callback to user context. /// pool_handle: pool handle. /// did: DID that signed the message -/// msg: message -/// signature: a signature to be verified +/// signed_msg: message /// cb: Callback that takes command result as parameter. /// /// #Returns @@ -260,6 +259,7 @@ pub extern fn indy_verify_signature(command_handle: i32, /// #Params /// wallet_handle: wallet handler (created by open_wallet). /// command_handle: command handle to map callback to user context. +/// pool_handle: pool handle. /// my_did: encrypting DID /// did: encrypting DID /// msg: a message to be signed diff --git a/src/api/wallet.rs b/src/api/wallet.rs index 3b6701ac3f..1360df1d37 100644 --- a/src/api/wallet.rs +++ b/src/api/wallet.rs @@ -248,44 +248,5 @@ pub extern fn indy_delete_wallet(command_handle: i32, }) ))); - result_to_err_code!(result) -} - -/// Sets a seq_no (the corresponding Ledger transaction unique sequence number) for the a value -/// in a secure wallet identified by the given string. -/// The string identifying the value in the wallet is returned when the value is stored in the wallet. -/// -/// #Params -/// wallet_handle: wallet handler (created by open_wallet). -/// command_handle: command handle to map callback to user context. -/// wallet_key: unique string identifying the value in the wallet. -/// seq_no: transaction sequence number. -/// -/// #Returns -/// Error code -/// -/// #Errors -/// Common* -/// Wallet* -#[no_mangle] -pub extern fn indy_wallet_set_seq_no_for_value(command_handle: i32, - wallet_handle: i32, - wallet_key: *const c_char, - seq_no: i32, - cb: Option) -> ErrorCode { - check_useful_c_str!(wallet_key, ErrorCode::CommonInvalidParam3); - check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam5); - - let result = CommandExecutor::instance() - .send(Command::Wallet(WalletCommand::SetSeqNoForValue( - wallet_handle, - wallet_key, - seq_no, - Box::new(move |result| { - let err = result_to_err_code!(result); - cb(command_handle, err) - }) - ))); - result_to_err_code!(result) } \ No newline at end of file diff --git a/src/commands/agent.rs b/src/commands/agent.rs index 44d54e4737..dd2a52a566 100644 --- a/src/commands/agent.rs +++ b/src/commands/agent.rs @@ -25,6 +25,7 @@ use services::wallet::WalletService; use utils::crypto::ed25519::ED25519; use utils::json::JsonDecodable; use utils::sequence::SequenceUtils; +use utils::crypto::verkey_builder::build_full_verkey; pub type AgentConnectCB = Box) + Send>; pub type AgentMessageCB = Box) + Send>; @@ -464,11 +465,13 @@ impl AgentCommandExecutor { trace!("parsed get_nym_result_data {:?}", gen_nym_result_data); - let verkey = gen_nym_result_data.verkey.unwrap_or(gen_nym_result_data.dest); + let pk = ED25519::vk_to_curve25519( + build_full_verkey(&gen_nym_result_data.dest, &gen_nym_result_data.verkey) + .unwrap() + .as_slice()) + .unwrap().to_base58(); - let verkey = ED25519::vk_to_curve25519(verkey.from_base58().unwrap().as_slice()).unwrap().to_base58(); - - Ok(verkey) + Ok(pk) }); self.do_check_connect(listener_handle, did.as_str(), pk.as_str(), res.ok().as_ref().map(String::as_str)); } diff --git a/src/commands/wallet.rs b/src/commands/wallet.rs index 86da8b367c..8f1f316382 100644 --- a/src/commands/wallet.rs +++ b/src/commands/wallet.rs @@ -49,11 +49,7 @@ pub enum WalletCommand { Box) + Send>), Delete(String, // name Option, // wallet credentials - Box) + Send>), - SetSeqNoForValue(i32, // wallet handle - String, // wallet key - i32, // sequence number - Box) + Send>) + Box) + Send>) } pub struct WalletCommandExecutor { @@ -94,10 +90,6 @@ impl WalletCommandExecutor { info!(target: "wallet_command_executor", "Delete command received"); self.delete(&name, credentials.as_ref().map(String::as_str), cb); } - WalletCommand::SetSeqNoForValue(handle, key, seq_no, cb) => { - info!(target: "wallet_command_executor", "SetSeqNoForValue command received"); - self.set_seq_no_for_value(handle, &key, seq_no, cb); - } }; } @@ -173,13 +165,4 @@ impl WalletCommandExecutor { cb(self.wallet_service.delete(handle, credentials) .map_err(|err| IndyError::WalletError(err))); } - - fn set_seq_no_for_value(&self, - handle: i32, - key: &str, - seq_no: i32, - cb: Box) + Send>) { - cb(self.wallet_service.set(handle, &format!("seq_no::{}", seq_no), key) - .map_err(|err| IndyError::WalletError(err))); - } } \ No newline at end of file diff --git a/src/utils/crypto/mod.rs b/src/utils/crypto/mod.rs index 60fc8755c1..5fea09c377 100644 --- a/src/utils/crypto/mod.rs +++ b/src/utils/crypto/mod.rs @@ -26,4 +26,6 @@ pub mod xsalsa20; #[path = "hash/openssl.rs"] pub mod hash; -pub mod signature_serializer; \ No newline at end of file +pub mod signature_serializer; + +pub mod verkey_builder; \ No newline at end of file diff --git a/src/utils/crypto/verkey_builder.rs b/src/utils/crypto/verkey_builder.rs new file mode 100644 index 0000000000..82ade12e0a --- /dev/null +++ b/src/utils/crypto/verkey_builder.rs @@ -0,0 +1,18 @@ +extern crate rust_base58; + +use self::rust_base58::base58::{FromBase58, FromBase58Error}; + +pub fn build_full_verkey(dest: &String, verkey: &Option) + -> Result, FromBase58Error> { + if let &Some(ref verkey) = verkey { + if verkey.starts_with("~") { + let mut result = dest.from_base58()?; + let mut end = verkey[1..].from_base58()?; + result.append(&mut end); + return Ok(result); + } else { + return verkey.from_base58(); + } + } + dest.from_base58() +} diff --git a/tests/agent.rs b/tests/agent.rs index b8f68d73b8..9969e1f8e9 100644 --- a/tests/agent.rs +++ b/tests/agent.rs @@ -62,7 +62,7 @@ mod high_cases { let listener_wallet = WalletUtils::create_and_open_wallet("indy_agent_connect_works_for_remote_data", None).unwrap(); let trustee_wallet = WalletUtils::create_and_open_wallet("indy_agent_connect_works_for_remote_data", None).unwrap(); let (listener_did, listener_ver_key, listener_pub_key) = SignusUtils::create_and_store_my_did(listener_wallet, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(trustee_wallet, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(trustee_wallet, Some("000000000000000000000000Trustee1")).unwrap(); let sender_did = trustee_did.clone(); let sender_wallet = trustee_wallet; @@ -89,7 +89,7 @@ mod high_cases { let wallet_handle = WalletUtils::create_and_open_wallet("pool1", None).expect("create wallet"); - let seed: Option = Some("sovrin_agent_connect_works_for_a".to_string()); + let seed: Option<&str> = Some("sovrin_agent_connect_works_for_a"); let (did, ver_key, pub_key) = SignusUtils::create_and_store_my_did(wallet_handle, seed).unwrap(); let endpoint = "127.0.0.1:9702"; @@ -129,7 +129,7 @@ mod high_cases { let wallet_handle = WalletUtils::create_and_open_wallet("pool2", None).expect("create wallet"); - let seed: Option = Some("sovrin_agent_listen_works_for_al".to_string()); + let seed: Option<&str> = Some("sovrin_agent_listen_works_for_al"); let (did, ver_key, pub_key) = SignusUtils::create_and_store_my_did(wallet_handle, seed).unwrap(); let endpoint = "127.0.0.1:9703"; SignusUtils::store_their_did_from_parts(wallet_handle, did.as_str(), pub_key.as_str(), ver_key.as_str(), endpoint).unwrap(); @@ -380,7 +380,7 @@ mod medium_cases { let listener_wallet = WalletUtils::create_and_open_wallet("indy_agent_add_identity_works_for_incoming_connection_require_ledger_request_but_pool_handle_is_invalid", None).unwrap(); let trustee_wallet = WalletUtils::create_and_open_wallet("indy_agent_add_identity_works_for_incoming_connection_require_ledger_request_but_pool_handle_is_invalid", None).unwrap(); let (listener_did, listener_ver_key, listener_pub_key) = SignusUtils::create_and_store_my_did(listener_wallet, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(trustee_wallet, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(trustee_wallet, Some("000000000000000000000000Trustee1")).unwrap(); let sender_did = trustee_did.clone(); let sender_wallet = trustee_wallet; diff --git a/tests/anoncreds.rs b/tests/anoncreds.rs index bb61796637..553fe10638 100644 --- a/tests/anoncreds.rs +++ b/tests/anoncreds.rs @@ -62,7 +62,7 @@ mod high_cases { let schema = AnoncredsUtils::get_gvt_schema_json(1); - let invalid_wallet_handle = wallet_handle + 1; + let invalid_wallet_handle = wallet_handle + 100; let res = AnoncredsUtils::issuer_create_claim_definition(invalid_wallet_handle, &ISSUER_DID, &schema, None, false); assert_eq!(res.unwrap_err(), ErrorCode::WalletInvalidHandle); } @@ -96,7 +96,7 @@ mod high_cases { let claim_offer_json = AnoncredsUtils::get_claim_offer(&ISSUER_DID, 1); - let invalid_wallet_handle = wallet_handle + 1; + let invalid_wallet_handle = wallet_handle + 100; let res = AnoncredsUtils::prover_store_claim_offer(invalid_wallet_handle, &claim_offer_json); assert_eq!(res.unwrap_err(), ErrorCode::WalletInvalidHandle); } @@ -164,7 +164,7 @@ mod high_cases { fn prover_get_claim_offers_works_for_invalid_wallet_handle() { let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); - let invalid_wallet_handle = wallet_handle + 1; + let invalid_wallet_handle = wallet_handle + 100; let res = AnoncredsUtils::prover_get_claim_offers(invalid_wallet_handle, r#"{"schema_seq_no":"1"}"#); assert_eq!(res.unwrap_err(), ErrorCode::WalletInvalidHandle); } @@ -184,7 +184,7 @@ mod high_cases { fn prover_create_master_secret_works_invalid_wallet_handle() { let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); - let invalid_wallet_handle = wallet_handle + 1; + let invalid_wallet_handle = wallet_handle + 100; let res = AnoncredsUtils::prover_create_master_secret(invalid_wallet_handle, "master_secret_name2"); assert_eq!(res.unwrap_err(), ErrorCode::WalletInvalidHandle); } @@ -217,7 +217,7 @@ mod high_cases { let claim_offer_json = AnoncredsUtils::get_claim_offer(ISSUER_DID, 1); - let invalid_wallet_handle = wallet_handle + 1; + let invalid_wallet_handle = wallet_handle + 100; let res = AnoncredsUtils::prover_create_and_store_claim_req(invalid_wallet_handle, "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW", &claim_offer_json, @@ -294,7 +294,7 @@ mod high_cases { let claim_json = AnoncredsUtils::get_gvt_claim_json(); - let invalid_wallet_handle = wallet_handle + 1; + let invalid_wallet_handle = wallet_handle + 100; let res = AnoncredsUtils::issuer_create_claim(invalid_wallet_handle, &claim_req, &claim_json); assert_eq!(res.unwrap_err(), ErrorCode::WalletInvalidHandle); } @@ -306,10 +306,13 @@ mod high_cases { #[test] fn prover_store_claim_works() { let (wallet_handle, claim_def_json) = AnoncredsUtils::init_common_wallet(); + let prover_wallet_handle = WalletUtils::create_and_open_wallet("proverWallet", None).unwrap(); let claim_offer_json = AnoncredsUtils::get_claim_offer(ISSUER_DID, 1); - let claim_req = AnoncredsUtils::prover_create_and_store_claim_req(wallet_handle, + AnoncredsUtils::prover_create_master_secret(prover_wallet_handle, COMMON_MASTER_SECRET).unwrap(); + + let claim_req = AnoncredsUtils::prover_create_and_store_claim_req(prover_wallet_handle, "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW", &claim_offer_json, &claim_def_json, @@ -318,7 +321,7 @@ mod high_cases { let claim_json = AnoncredsUtils::get_gvt_claim_json(); let (_, xclaim_json) = AnoncredsUtils::issuer_create_claim(wallet_handle, &claim_req, &claim_json).unwrap(); - AnoncredsUtils::prover_store_claim(wallet_handle, &xclaim_json).unwrap(); + AnoncredsUtils::prover_store_claim(prover_wallet_handle, &xclaim_json).unwrap(); } #[test] @@ -336,7 +339,7 @@ mod high_cases { let claim_json = AnoncredsUtils::get_gvt_claim_json(); let (_, claim_json) = AnoncredsUtils::issuer_create_claim(wallet_handle, &claim_req, &claim_json).unwrap(); - let invalid_wallet_handle = wallet_handle + 1; + let invalid_wallet_handle = wallet_handle + 100; let res = AnoncredsUtils::prover_store_claim(invalid_wallet_handle, &claim_json); assert_eq!(res.unwrap_err(), ErrorCode::WalletInvalidHandle); } @@ -389,7 +392,7 @@ mod high_cases { fn prover_get_claims_works_for_invalid_wallet_handle() { let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); - let invalid_wallet_handle = wallet_handle + 1; + let invalid_wallet_handle = wallet_handle + 100; let res = AnoncredsUtils::prover_get_claims(invalid_wallet_handle, r#"{}"#); assert_eq!(res.unwrap_err(), ErrorCode::WalletInvalidHandle); } @@ -533,7 +536,7 @@ mod high_cases { "requested_predicates":{"predicate1_uuid":{"attr_name":"age","p_type":"GE","value":58}} }"#; - let invalid_wallet_handle = wallet_handle + 1; + let invalid_wallet_handle = wallet_handle + 100; let res = AnoncredsUtils::prover_get_claims_for_proof_req(invalid_wallet_handle, &proof_req); assert_eq!(res.unwrap_err(), ErrorCode::WalletInvalidHandle); } @@ -644,7 +647,7 @@ mod high_cases { let claim_defs_json = format!(r#"{{"{}":{}}}"#, claim_for_attr.claim_uuid, claim_def_json); let revoc_regs_jsons = "{}"; - let invalid_wallet_handle = wallet_handle + 1; + let invalid_wallet_handle = wallet_handle + 100; let res = AnoncredsUtils::prover_create_proof(invalid_wallet_handle, &proof_req, &requested_claims_json, @@ -755,12 +758,22 @@ mod medium_cases { fn issuer_create_and_store_claim_def_works_for_invalid_schema() { let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); - let schema = r#"{"seqNo":1, "name":"name","version":"1.0", "keys":[]}"#; + let schema = r#"{"seqNo":1, "name":"name","version":"1.0", "keys":["name"]}"#; let res = AnoncredsUtils::issuer_create_claim_definition(wallet_handle, ISSUER_DID, &schema, None, false); assert_eq!(res.unwrap_err(), ErrorCode::CommonInvalidStructure); } + #[test] + fn issuer_create_and_store_claim_def_works_for_invalid_did() { + let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); + + let schema = r#"{"seqNo":1, "data":{"name":"name","version":"1.0","keys":[]}}"#; + + let res = AnoncredsUtils::issuer_create_claim_definition(wallet_handle, "invalid_base58_String", &schema, None, false); + assert_eq!(res.unwrap_err(), ErrorCode::CommonInvalidStructure); + } + #[test] fn issuer_create_and_store_claim_def_works_for_empty_schema_keys() { let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); @@ -771,6 +784,16 @@ mod medium_cases { assert_eq!(res.unwrap_err(), ErrorCode::CommonInvalidStructure); } + #[test] + fn issuer_create_and_store_claim_def_works_for_correct_signature_type() { + let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); + + let schema = AnoncredsUtils::get_gvt_schema_json(1); + + let res = AnoncredsUtils::issuer_create_claim_definition(wallet_handle, &schema, ISSUER_DID, Some("CL"), false); + assert_eq!(res.unwrap_err(), ErrorCode::CommonInvalidStructure); + } + #[test] fn issuer_create_and_store_claim_def_works_for_invalid_signature_type() { let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); @@ -841,6 +864,14 @@ mod medium_cases { let res = AnoncredsUtils::prover_create_master_secret(wallet_handle, "master_secret_name_duplicate"); assert_eq!(res.unwrap_err(), ErrorCode::AnoncredsMasterSecretDuplicateNameError); } + + #[test] + fn prover_create_master_secret_works_for_empty_name() { + let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); + + let res = AnoncredsUtils::prover_create_master_secret(wallet_handle, ""); + assert_eq!(res.unwrap_err(), ErrorCode::CommonInvalidParam3); + } } mod prover_create_and_store_claim_req { @@ -1038,6 +1069,72 @@ mod medium_cases { assert_eq!(claims_for_attr_1.len(), 0); } + #[test] + fn prover_get_claims_for_proof_req_works_for_revealed_attr_for_specific_issuer() { + let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); + + let proof_req = r#"{"nonce":"123432421212", + "name":"proof_req_1", + "version":"0.1", + "requested_attrs":{"attr1_uuid":{"issuer_did":"NcYxiDXkpYi6ov5FcYDi1e", "name":"name"}}, + "requested_predicates":{} + }"#; + + let claims_json = AnoncredsUtils::prover_get_claims_for_proof_req(wallet_handle, &proof_req).unwrap(); + + let claims: ProofClaimsJson = serde_json::from_str(&claims_json).unwrap(); + + assert_eq!(claims.attrs.len(), 1); + assert_eq!(claims.predicates.len(), 0); + + let claims_for_attr_1 = claims.attrs.get("attr1_uuid").unwrap(); + assert_eq!(claims_for_attr_1.len(), 1); + } + + #[test] + fn prover_get_claims_for_proof_req_works_for_revealed_attr_with_other_issuer() { + let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); + + let proof_req = r#"{"nonce":"123432421212", + "name":"proof_req_1", + "version":"0.1", + "requested_attrs":{"attr1_uuid":{"issuer_did":"Ac23dAXkpYi6ov5FcYDi1e", "name":"name"}}, + "requested_predicates":{} + }"#; + + let claims_json = AnoncredsUtils::prover_get_claims_for_proof_req(wallet_handle, &proof_req).unwrap(); + + let claims: ProofClaimsJson = serde_json::from_str(&claims_json).unwrap(); + + assert_eq!(claims.attrs.len(), 1); + assert_eq!(claims.predicates.len(), 0); + + let claims_for_attr_1 = claims.attrs.get("attr1_uuid").unwrap(); + assert_eq!(claims_for_attr_1.len(), 0); + } + + #[test] + fn prover_get_claims_for_proof_req_works_for_satisfy_predicate_by_specific_issuer_and_schema() { + let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); + + let proof_req = r#"{"nonce":"123432421212", + "name":"proof_req_1", + "version":"0.1", + "requested_attrs":{}, + "requested_predicates":{"predicate1_uuid":{"attr_name":"age","p_type":"GE","value":18,"schema_seq_no":1,"issuer_did":"NcYxiDXkpYi6ov5FcYDi1e"}} + }"#; + + let claims_json = AnoncredsUtils::prover_get_claims_for_proof_req(wallet_handle, &proof_req).unwrap(); + + let claims: ProofClaimsJson = serde_json::from_str(&claims_json).unwrap(); + + assert_eq!(claims.attrs.len(), 0); + assert_eq!(claims.predicates.len(), 1); + + let claims_for_predicate_1 = claims.predicates.get("predicate1_uuid").unwrap(); + assert_eq!(claims_for_predicate_1.len(), 1); + } + #[test] fn prover_get_claims_for_proof_req_works_for_invalid_predicate() { let (wallet_handle, _) = AnoncredsUtils::init_common_wallet(); @@ -1308,6 +1405,332 @@ mod medium_cases { mod demos { use super::*; + #[cfg(feature = "interoperability_tests")] + use utils::types::ClaimDefinitionData; + #[cfg(feature = "interoperability_tests")] + use std::process::Command; + #[cfg(feature = "interoperability_tests")] + use std::io::prelude::*; + #[cfg(feature = "interoperability_tests")] + use std::net::TcpStream; + #[cfg(feature = "interoperability_tests")] + use std::{thread, time}; + + #[cfg(feature = "interoperability_tests")] + #[test] + fn interoperability_test_pysovrin_is_issuer() { + TestUtils::cleanup_storage(); + + let pool_name = "pool1"; + let xtype = "default"; + + //1. Create Prover wallet, get wallet handle + let prover_wallet_handle = WalletUtils::create_and_open_wallet(pool_name, Some(xtype)).unwrap(); + + let schema_seq_no = 1; + let schema = AnoncredsUtils::get_gvt_schema_json(schema_seq_no); + + //2. Prover create Master Secret + let master_secret_name = "prover_master_secret"; + + AnoncredsUtils::prover_create_master_secret(prover_wallet_handle, master_secret_name).unwrap(); + + //3. Prover store Claim Offer received from Issuer + let claim_offer_json = AnoncredsUtils::get_claim_offer(ISSUER_DID, schema_seq_no); + + AnoncredsUtils::prover_store_claim_offer(prover_wallet_handle, &claim_offer_json).unwrap(); + + //4. Prover get Claim Offers + let filter_json = format!(r#"{{"issuer_did":"{}"}}"#, ISSUER_DID); + + let claim_offers_json = AnoncredsUtils::prover_get_claim_offers(prover_wallet_handle, &filter_json).unwrap(); + + let claim_offers: Vec = serde_json::from_str(&claim_offers_json).unwrap(); + assert!(claim_offers.len() == 1); + let claim_offer_json = serde_json::to_string(&claim_offers[0]).unwrap(); + + Command::new("python3") + .arg("/home/indy/indy-anoncreds/anoncreds/test/test_interoperability_with_libsovrin_pysovrin_is_issuer.py") + .spawn().expect("failed to execute process"); + thread::sleep(time::Duration::from_millis(3000)); + + let mut stream = TcpStream::connect("127.0.0.1:1234").unwrap(); + + let _ = stream.write(r#"{"type":"get_claim_def"}"#.as_bytes()); + let mut buf = vec![0; 10240]; + stream.read(&mut buf).unwrap(); + buf.retain(|&element| element != 0); + + let claim_def_data: ClaimDefinitionData = serde_json::from_str(&String::from_utf8(buf).unwrap()).unwrap(); + + let claim_def = ClaimDefinition { + issuer_did: ISSUER_DID.to_string(), + signature_type: "CL".to_string(), + schema_seq_no: schema_seq_no, + data: claim_def_data + }; + + let claim_def_json = serde_json::to_string(&claim_def).unwrap(); + + //5. Prover create Claim Request + let prover_did = "BzfFCYk"; + let claim_req = AnoncredsUtils::prover_create_and_store_claim_req(prover_wallet_handle, + prover_did, + &claim_offer_json, + &claim_def_json, + master_secret_name).unwrap(); + + let _ = stream.write(format!(r#"{{"type":"issue_claim", "data": {}}}"#, claim_req).as_bytes()); + let mut buf = vec![0; 10240]; + stream.read(&mut buf).unwrap(); + let _ = stream.write(r#"{"type":"close"}"#.as_bytes()); + buf.retain(|&element| element != 0); + + let mut claim_json: ClaimJson = serde_json::from_str(&String::from_utf8(buf).unwrap()).unwrap(); + claim_json.schema_seq_no = Some(schema_seq_no); + claim_json.issuer_did = Some(ISSUER_DID.to_string()); + + // 6. Prover store received Claim + AnoncredsUtils::prover_store_claim(prover_wallet_handle, &serde_json::to_string(&claim_json).unwrap()).unwrap(); + + // 7. Prover gets Claims for Proof Request + let proof_req_json = format!(r#"{{ + "nonce":"123432421212", + "name":"proof_req_1", + "version":"0.1", + "requested_attrs":{{"attr1_uuid":{{"schema_seq_no":{},"name":"name"}}, + "attr2_uuid":{{"schema_seq_no":{},"name":"sex"}}}}, + "requested_predicates":{{"predicate1_uuid":{{"attr_name":"age","p_type":"GE","value":18}}}} + }}"#, schema_seq_no, schema_seq_no); + + let claims_json = AnoncredsUtils::prover_get_claims_for_proof_req(prover_wallet_handle, &proof_req_json).unwrap(); + let claims: ProofClaimsJson = serde_json::from_str(&claims_json).unwrap(); + info!("claims_json: {}", &claims_json); + let claims_for_attr_1 = claims.attrs.get("attr1_uuid").unwrap(); + assert_eq!(1, claims_for_attr_1.len()); + let claim = claims_for_attr_1[0].clone(); + + // 8. Prover create Proof + let self_attested_value = "value"; + let requested_claims_json = format!(r#"{{ + "self_attested_attributes":{{"self1":"{}"}}, + "requested_attrs":{{"attr1_uuid":["{}",true], + "attr2_uuid":["{}", false]}}, + "requested_predicates":{{"predicate1_uuid":"{}"}} + }}"#, self_attested_value, claim.claim_uuid, claim.claim_uuid, claim.claim_uuid); + + let schemas_json = format!(r#"{{"{}":{}}}"#, claim.claim_uuid, schema); + let claim_defs_json = format!(r#"{{"{}":{}}}"#, claim.claim_uuid, claim_def_json); + let revoc_regs_jsons = "{}"; + + let proof_json = AnoncredsUtils::prover_create_proof(prover_wallet_handle, + &proof_req_json, + &requested_claims_json, + &schemas_json, + &master_secret_name, + &claim_defs_json, + &revoc_regs_jsons).unwrap(); + + let proof: ProofJson = serde_json::from_str(&proof_json).unwrap(); + + let &(_, ref value, _) = proof.requested_proof.revealed_attrs.get("attr1_uuid").unwrap(); + assert_eq!(value, "Alex"); + + proof.requested_proof.unrevealed_attrs.get("attr2_uuid").unwrap(); + + let value = proof.requested_proof.self_attested_attrs.get("self1").unwrap(); + assert_eq!(value, self_attested_value); + + // 9. Verifier verify proof + let valid = AnoncredsUtils::verifier_verify_proof(&proof_req_json, + &proof_json, + &schemas_json, + &claim_defs_json, + &revoc_regs_jsons).unwrap(); + assert!(valid); + + TestUtils::cleanup_storage(); + } + + #[cfg(feature = "interoperability_tests")] + #[test] + fn interoperability_test_pysovrin_is_verifier() { + TestUtils::cleanup_storage(); + + let pool_name = "pool1"; + let xtype = "default"; + + //1. Create Issuer wallet, get wallet handle + let issuer_wallet_handle = WalletUtils::create_and_open_wallet(pool_name, Some(xtype)).unwrap(); + + //2. Create Prover wallet, get wallet handle + let prover_wallet_handle = WalletUtils::create_and_open_wallet(pool_name, Some(xtype)).unwrap(); + + //3. Issuer create claim definition + let schema_seq_no = 1; + let schema = AnoncredsUtils::get_gvt_schema_json(schema_seq_no); + + let claim_def_json = AnoncredsUtils::issuer_create_claim_definition(issuer_wallet_handle, &ISSUER_DID, &schema, None, false).unwrap(); + + Command::new("python3") + .arg("/home/indy/indy-anoncreds/anoncreds/test/test_interoperability_with_libsovrin_pysovrin_is_verifier.py") + .spawn().expect("failed to execute process"); + thread::sleep(time::Duration::from_millis(3000)); + + let mut stream = TcpStream::connect("127.0.0.1:1234").unwrap(); + + let _ = stream.write(format!(r#"{{"type":"receive_claim_def", "data": {}}}"#, claim_def_json).as_bytes()); + + //4. Prover create Master Secret + let master_secret_name = "prover_master_secret"; + + AnoncredsUtils::prover_create_master_secret(prover_wallet_handle, master_secret_name).unwrap(); + + //5. Prover store Claim Offer received from Issuer + let claim_offer_json = AnoncredsUtils::get_claim_offer(ISSUER_DID, schema_seq_no); + + AnoncredsUtils::prover_store_claim_offer(prover_wallet_handle, &claim_offer_json).unwrap(); + + //6. Prover get Claim Offers + let filter_json = format!(r#"{{"issuer_did":"{}"}}"#, ISSUER_DID); + + let claim_offers_json = AnoncredsUtils::prover_get_claim_offers(prover_wallet_handle, &filter_json).unwrap(); + + let claim_offers: Vec = serde_json::from_str(&claim_offers_json).unwrap(); + assert!(claim_offers.len() == 1); + let claim_offer_json = serde_json::to_string(&claim_offers[0]).unwrap(); + + //7. Prover create Claim Request + let prover_did = "BzfFCYk"; + let claim_req = AnoncredsUtils::prover_create_and_store_claim_req(prover_wallet_handle, + prover_did, + &claim_offer_json, + &claim_def_json, + master_secret_name).unwrap(); + + //8. Issuer create Claim + let claim_json = AnoncredsUtils::get_gvt_claim_json(); + let (_, xclaim_json) = AnoncredsUtils::issuer_create_claim(issuer_wallet_handle, + &claim_req, + &claim_json).unwrap(); + + // 9. Prover store received Claim + AnoncredsUtils::prover_store_claim(prover_wallet_handle, &xclaim_json).unwrap(); + + let _ = stream.write(r#"{"type":"get_proof_request"}"#.as_bytes()); + let mut buf = vec![0; 10240]; + stream.read(&mut buf).unwrap(); + buf.retain(|&element| element != 0); + + let proof_req_json = String::from_utf8(buf).unwrap(); + + let claims_json = AnoncredsUtils::prover_get_claims_for_proof_req(prover_wallet_handle, &proof_req_json).unwrap(); + let claims: ProofClaimsJson = serde_json::from_str(&claims_json).unwrap(); + + let claims_for_attr = claims.attrs.get("attr_uuid").unwrap(); + assert_eq!(1, claims_for_attr.len()); + let claim = claims_for_attr[0].clone(); + + // 11. Prover create Proof + let self_attested_value = "value"; + let requested_claims_json = format!(r#"{{ + "self_attested_attributes":{{"self1":"{}"}}, + "requested_attrs":{{"attr_uuid":["{}",true]}}, + "requested_predicates":{{"predicate_uuid":"{}"}} + }}"#, self_attested_value, claim.claim_uuid, claim.claim_uuid); + + let schemas_json = format!(r#"{{"{}":{}}}"#, claim.claim_uuid, schema); + let claim_defs_json = format!(r#"{{"{}":{}}}"#, claim.claim_uuid, claim_def_json); + let revoc_regs_jsons = "{}"; + + let proof_json = AnoncredsUtils::prover_create_proof(prover_wallet_handle, + &proof_req_json, + &requested_claims_json, + &schemas_json, + &master_secret_name, + &claim_defs_json, + &revoc_regs_jsons).unwrap(); + + let _ = stream.write(format!(r#"{{"type":"check_proof", "data": {}}}"#, proof_json).as_bytes()); + let mut buf = vec![0; 102400]; + stream.read(&mut buf).unwrap(); + let _ = stream.write(r#"{"type":"close"}"#.as_bytes()); + buf.retain(|&element| element != 0); + + let valid = String::from_utf8(buf).unwrap(); + assert_eq!("true", valid); + + TestUtils::cleanup_storage(); + } + + #[cfg(feature = "interoperability_tests")] + #[test] + fn interoperability_test_pysovrin_is_prover() { + TestUtils::cleanup_storage(); + + let schema_seq_no = 1; + let schema = AnoncredsUtils::get_gvt_schema_json(schema_seq_no); + + Command::new("python3") + .arg("/home/indy/indy-anoncreds/anoncreds/test/test_interoperability_with_libsovrin_pysovrin_is_prover.py") + .spawn().expect("failed to execute process"); + thread::sleep(time::Duration::from_millis(3000)); + + let mut stream = TcpStream::connect("127.0.0.1:1234").unwrap(); + + let _ = stream.write(r#"{"type":"get_claim_def"}"#.as_bytes()); + let mut buf = vec![0; 10240]; + stream.read(&mut buf).unwrap(); + buf.retain(|&element| element != 0); + + let claim_def_data: ClaimDefinitionData = serde_json::from_str(&String::from_utf8(buf).unwrap()).unwrap(); + + let claim_def = ClaimDefinition { + issuer_did: ISSUER_DID.to_string(), + signature_type: "CL".to_string(), + schema_seq_no: schema_seq_no, + data: claim_def_data + }; + + let claim_def_json = serde_json::to_string(&claim_def).unwrap(); + + // 7. Prover gets Claims for Proof Request + let proof_req_json = format!(r#"{{ + "nonce":"123432421212", + "name":"proof_req_1", + "version":"0.1", + "requested_attrs":{{"attr_uuid":{{"schema_seq_no":{},"name":"name"}}}}, + "requested_predicates":{{"predicate_uuid":{{"attr_name":"age","p_type":"GE","value":18}}}} + }}"#, schema_seq_no); + + let _ = stream.write(format!(r#"{{"type":"get_proof", "data": {}}}"#, proof_req_json).as_bytes()); + let mut buf = vec![0; 102400]; + stream.read(&mut buf).unwrap(); + buf.retain(|&element| element != 0); + + let proof: ProofJson = serde_json::from_str(&String::from_utf8(buf).unwrap()).unwrap(); + println!("proof: {:?}", proof); + + let _ = stream.write(r#"{"type":"close"}"#.as_bytes()); + let schemas_json = format!(r#"{{"{}":{}}}"#, 1, schema); + + let &(_, ref value, _) = proof.requested_proof.revealed_attrs.get("attr_uuid").unwrap(); + assert_eq!(value, "Alex"); + + let proof_json = serde_json::to_string(&proof).unwrap(); + let claim_defs_json = format!(r#"{{"{}":{}}}"#, 1, claim_def_json); + let revoc_regs_jsons = "{}"; + + // 9. Verifier verify proof + let valid = AnoncredsUtils::verifier_verify_proof(&proof_req_json, + &proof_json, + &schemas_json, + &claim_defs_json, + &revoc_regs_jsons).unwrap(); + assert!(valid); + + TestUtils::cleanup_storage(); + } #[test] fn verifier_verify_proof_works_for_proof_does_not_correspond_proof_request() { @@ -1471,7 +1894,7 @@ mod demos { let self_attested_value = "value"; let requested_claims_json = format!(r#"{{ "self_attested_attributes":{{"self1":"{}"}}, - "requested_attrs":{{"attr1_uuid":["{}",true], + "requested_attrs":{{"attr1_uuid":["{}", true], "attr2_uuid":["{}", false]}}, "requested_predicates":{{"predicate1_uuid":"{}"}} }}"#, self_attested_value, claim.claim_uuid, claim.claim_uuid, claim.claim_uuid); @@ -1538,7 +1961,7 @@ mod demos { claim_defs.insert(ISSUER_DID.to_string(), gvt_claim_def_json.clone()); - //5. Issuer1 create claim definition by xyz schema + //5. Issuer2 create claim definition by xyz schema let xyz_schema_seq_no = 2; let xyz_schema = AnoncredsUtils::get_xyz_schema_json(xyz_schema_seq_no); diff --git a/tests/demo.rs b/tests/demo.rs index 80f59920de..18d203543c 100644 --- a/tests/demo.rs +++ b/tests/demo.rs @@ -5,6 +5,7 @@ use indy::api as api; #[macro_use] extern crate serde_derive; +#[macro_use] extern crate serde_json; #[macro_use] extern crate lazy_static; @@ -50,17 +51,297 @@ use indy::api::signus::{ indy_verify_signature, indy_store_their_did }; +use indy::api::agent::{ + indy_agent_listen, + indy_agent_add_identity, + indy_agent_connect, + indy_agent_send +}; use utils::callback::CallbackUtils; use std::ptr::null; -use std::sync::mpsc::{channel}; -use std::ffi::{CString}; +use std::sync::mpsc::channel; +use std::ffi::CString; use utils::types::ProofClaimsJson; #[cfg(feature = "local_nodes_pool")] use std::thread; +#[test] +fn agent_demo_works() { + TestUtils::cleanup_storage(); + + let endpoint = "127.0.0.1:9801"; + let pool_name = "indy_agent_connect_works_for_remote_data"; + + let listener_wallet_name = "listener_wallet"; + let trustee_wallet_name = "trustee_wallet"; + let wallet_type = "default"; + let c_pool_name = CString::new(pool_name).unwrap(); + + let (submit_sender, submit_receiver) = channel(); + let (create_sender, create_receiver) = channel(); + let (open_sender, open_receiver) = channel(); + let (create_listener_wallet_sender, create_listener_wallet_receiver) = channel(); + let (create_trustee_wallet_sender, create_trustee_wallet_receiver) = channel(); + let (open_listener_wallet_sender, open_listener_wallet_receiver) = channel(); + let (open_trustee_wallet_sender, open_trustee_wallet_receiver) = channel(); + let (create_and_store_listener_did_sender, create_and_store_listener_did_receiver) = channel(); + let (create_and_store_trustee_did_sender, create_and_store_trustee_did_receiver) = channel(); + let (attrib_sender, attrib_receiver) = channel(); + let (listen_sender, listen_receiver) = channel(); + let (add_identity_sender, add_identity_receiver) = channel(); + let (connect_sender, connect_receiver) = channel(); + let (send_sender, send_receiver) = channel(); + + let create_cb = Box::new(move |err| { create_sender.send(err).unwrap(); }); + let open_cb = Box::new(move |err, pool_handle| { open_sender.send((err, pool_handle)).unwrap(); }); + let send_cb = Box::new(move |err, resp| { submit_sender.send((err, resp)).unwrap(); }); + let create_listener_wallet_cb = Box::new(move |err| { create_listener_wallet_sender.send(err).unwrap(); }); + let create_trustee_wallet_cb = Box::new(move |err| { create_trustee_wallet_sender.send(err).unwrap(); }); + let open_listener_wallet_cb = Box::new(move |err, handle| { open_listener_wallet_sender.send((err, handle)).unwrap(); }); + let open_trustee_wallet_cb = Box::new(move |err, handle| { open_trustee_wallet_sender.send((err, handle)).unwrap(); }); + let create_and_store_listener_did_cb = Box::new(move |err, did, verkey, public_key| { create_and_store_listener_did_sender.send((err, did, verkey, public_key)).unwrap(); }); + let create_and_store_trustee_did_cb = Box::new(move |err, did, verkey, public_key| { create_and_store_trustee_did_sender.send((err, did, verkey, public_key)).unwrap(); }); + let listen_cb = Box::new(move |err, listener_handle| listen_sender.send((err, listener_handle)).unwrap()); + let add_identity_cb = Box::new(move |err_code| add_identity_sender.send(err_code).unwrap()); + let connect_cb = Box::new(move |err, connection_handle| { connect_sender.send((err, connection_handle)).unwrap(); }); + let agent_send_cb = Box::new(move |err_code| send_sender.send(err_code).unwrap()); + + let (open_command_handle, open_callback) = CallbackUtils::closure_to_open_pool_ledger_cb(open_cb); + let (create_command_handle, create_callback) = CallbackUtils::closure_to_create_pool_ledger_cb(create_cb); + let (send_command_handle, send_callback) = CallbackUtils::closure_to_send_tx_cb(send_cb); + let (create_listener_wallet_command_handle, create_listener_wallet_callback) = CallbackUtils::closure_to_create_wallet_cb(create_listener_wallet_cb); + let (create_trustee_wallet_command_handle, create_trustee_wallet_callback) = CallbackUtils::closure_to_create_wallet_cb(create_trustee_wallet_cb); + let (open_listener_wallet_command_handle, open_listener_wallet_callback) = CallbackUtils::closure_to_open_wallet_cb(open_listener_wallet_cb); + let (open_trustee_wallet_command_handle, open_trustee_wallet_callback) = CallbackUtils::closure_to_open_wallet_cb(open_trustee_wallet_cb); + let (create_and_store_listener_did_command_handle, create_and_store_listener_did_callback) = CallbackUtils::closure_to_create_and_store_my_did_cb(create_and_store_listener_did_cb); + let (create_and_store_trustee_did_command_handle, create_and_store_trustee_did_callback) = CallbackUtils::closure_to_create_and_store_my_did_cb(create_and_store_trustee_did_cb); + let (attrib_command_handle, attrib_callback) = CallbackUtils::closure_to_sign_and_submit_request_cb(Box::new(move |err, request_result_json| { + attrib_sender.send((err, request_result_json)).unwrap(); + })); + let (listen_command_handle, listen_callback) = CallbackUtils::closure_to_agent_listen_cb(listen_cb); + let (add_identity_command_handle, add_identity_cb) = CallbackUtils::closure_to_agent_add_identity_cb(add_identity_cb); + let (connect_command_hamdle, connect_callback) = CallbackUtils::closure_to_agent_connect_cb(connect_cb); + let (agent_send_command_handle, agent_send_callback) = CallbackUtils::closure_to_agent_send_cb(agent_send_cb); + + // 1. Create ledger config from genesis txn file + PoolUtils::create_genesis_txn_file(format!("{}.txn", pool_name).as_str(), None); + let pool_config = CString::new(PoolUtils::create_default_pool_config(pool_name)).unwrap(); + let err = indy_create_pool_ledger_config(create_command_handle, + c_pool_name.as_ptr(), + pool_config.as_ptr(), + create_callback); + assert_eq!(err, ErrorCode::Success); + let err = create_receiver.recv_timeout(TimeoutUtils::short_timeout()).unwrap(); + assert_eq!(err, ErrorCode::Success); + + // 2. Open pool ledger + let err = indy_open_pool_ledger(open_command_handle, + c_pool_name.as_ptr(), + null(), + open_callback); + assert_eq!(err, ErrorCode::Success); + let (err, pool_handle) = open_receiver.recv_timeout(TimeoutUtils::short_timeout()).unwrap(); + assert_eq!(err, ErrorCode::Success); + thread::sleep(TimeoutUtils::short_timeout()); + + // 3. Create Listener Wallet + let err = + indy_create_wallet(create_listener_wallet_command_handle, + c_pool_name.as_ptr(), + CString::new(listener_wallet_name).unwrap().as_ptr(), + CString::new(wallet_type).unwrap().as_ptr(), + null(), + null(), + create_listener_wallet_callback); + + assert_eq!(ErrorCode::Success, err); + let err = create_listener_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); + assert_eq!(ErrorCode::Success, err); + + // 4. Open Listener Wallet. Gets My wallet handle + let err = + indy_open_wallet(open_listener_wallet_command_handle, + CString::new(listener_wallet_name).unwrap().as_ptr(), + null(), + null(), + open_listener_wallet_callback); + + assert_eq!(ErrorCode::Success, err); + let (err, listener_wallet) = open_listener_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); + assert_eq!(ErrorCode::Success, err); + + + // 5. Create Their Wallet (trustee, sender) + let err = + indy_create_wallet(create_trustee_wallet_command_handle, + CString::new(pool_name).unwrap().as_ptr(), + CString::new(trustee_wallet_name).unwrap().as_ptr(), + CString::new(wallet_type).unwrap().as_ptr(), + null(), + null(), + create_trustee_wallet_callback); + + assert_eq!(ErrorCode::Success, err); + let err = create_trustee_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); + assert_eq!(ErrorCode::Success, err); + + // 6. Open Their Wallet. Gets Their wallet handle + let err = + indy_open_wallet(open_trustee_wallet_command_handle, + CString::new(trustee_wallet_name).unwrap().as_ptr(), + null(), + null(), + open_trustee_wallet_callback); + + assert_eq!(ErrorCode::Success, err); + let (err, trustee_wallet) = open_trustee_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); + assert_eq!(ErrorCode::Success, err); + + // 7. Create My DID + let listener_did_json = "{}"; + let err = + indy_create_and_store_my_did(create_and_store_listener_did_command_handle, + listener_wallet, + CString::new(listener_did_json).unwrap().as_ptr(), + create_and_store_listener_did_callback); + + assert_eq!(ErrorCode::Success, err); + let (err, listener_did, listener_vk, listener_pk) = create_and_store_listener_did_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); + info!("listener did {:?}", listener_did); + info!("listener verkey {:?}", listener_vk); + info!("listener pk {:?}", listener_pk); + assert_eq!(ErrorCode::Success, err); + let listener_did_c = CString::new(listener_did.clone()).unwrap(); + + // 8. Create Their DID from Trustee1 seed + let trustee_did_json = r#"{"seed":"000000000000000000000000Trustee1"}"#; + let err = + indy_create_and_store_my_did(create_and_store_trustee_did_command_handle, + trustee_wallet, + CString::new(trustee_did_json).unwrap().as_ptr(), + create_and_store_trustee_did_callback); + + assert_eq!(ErrorCode::Success, err); + let (err, trustee_did, trustee_verkey, trustee_pk) = create_and_store_trustee_did_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); + info!("sender (trustee) did {:?}", trustee_did); + info!("sender (trustee) verkey {:?}", trustee_verkey); + info!("sender (trustee) pk {:?}", trustee_pk); + assert_eq!(ErrorCode::Success, err); + let trustee_did_c = CString::new(trustee_did.clone()).unwrap(); + + // 9. Prepare NYM transaction + let nym_req_id = PoolUtils::get_req_id(); + let nym_txn_req = json!({ + "identifier": trustee_did, + "operation": { + "dest": listener_did, + "verkey": listener_vk, + "type": "1", + }, + "reqId": nym_req_id, + }); + + // 10. Send NYM request with signing + let msg = serde_json::to_string(&nym_txn_req).unwrap(); + let req = CString::new(msg).unwrap(); + let err = indy_sign_and_submit_request(send_command_handle, + pool_handle, + trustee_wallet, + trustee_did_c.as_ptr(), + req.as_ptr(), + send_callback); + assert_eq!(err, ErrorCode::Success); + let (err, _) = submit_receiver.recv_timeout(TimeoutUtils::medium_timeout()).unwrap(); + assert_eq!(err, ErrorCode::Success); + + let sender_did = trustee_did.clone(); + let sender_wallet = trustee_wallet; + + //10. Prepare and send attrib for listener (will be requested from ledger and used by sender at start connection) + let req_id = PoolUtils::get_req_id(); + let listener_attrib_json = json!({ + "identifier": listener_did, + "operation": { + "dest": listener_did, + "raw": format!("{{\"endpoint\":{{\"ha\":\"{}\", \"verkey\":\"{}\"}}}}", endpoint, listener_pk), + "type": "100", + }, + "reqId": req_id + }); + let listener_attrib_json = serde_json::to_string(&listener_attrib_json).unwrap(); + let listener_attrib_json = CString::new(listener_attrib_json).unwrap(); + let err = + indy_sign_and_submit_request(attrib_command_handle, + pool_handle, + listener_wallet, + listener_did_c.as_ptr(), + listener_attrib_json.as_ptr(), + attrib_callback); + assert_eq!(err, ErrorCode::Success); + let (err, _) = attrib_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); + assert_eq!(err, ErrorCode::Success); + + // 10. start listener on endpoint + let (wait_msg_from_srv_send, wait_msg_from_srv_recv) = channel(); + let on_msg = Box::new(move |conn_handle, err, msg| { + info!("On connection {} received (with error {:?}) agent message (CLI->SRV): {}", conn_handle, err, msg); + wait_msg_from_srv_send.send(msg).unwrap(); + }); + let (on_msg_cb_id, on_msg_callback) = CallbackUtils::closure_to_agent_message_cb(on_msg); + + let on_connect_cb = Box::new(move |listener_handle, err, conn_handle, sender_did, receiver_did| { + CallbackUtils::closure_map_ids(on_msg_cb_id, conn_handle); + info!("New connection {} on listener {}, err {:?}, sender DID {}, receiver DID {}", conn_handle, listener_handle, err, sender_did, receiver_did); + }); + let (on_connect_cb_id, on_connect_callback) = CallbackUtils::closure_to_agent_connected_cb(on_connect_cb); + + let endpoint = CString::new(endpoint).unwrap(); + + let err = indy_agent_listen(listen_command_handle, endpoint.as_ptr(), listen_callback, on_connect_callback, on_msg_callback); + assert_eq!(err, ErrorCode::Success); + let (err, agent_listener_handle) = listen_receiver.recv_timeout(TimeoutUtils::short_timeout()).unwrap(); + assert_eq!(err, ErrorCode::Success); + + CallbackUtils::closure_map_ids(on_connect_cb_id, agent_listener_handle); + + // 11. Allow listener accept incoming connection for specific DID (listener_did) + let listener_did = CString::new(listener_did.clone()).unwrap(); + let err = indy_agent_add_identity(add_identity_command_handle, agent_listener_handle, pool_handle, listener_wallet, listener_did.as_ptr(), add_identity_cb); + assert_eq!(err, ErrorCode::Success); + let err = add_identity_receiver.recv_timeout(TimeoutUtils::short_timeout()).unwrap(); + assert_eq!(err, ErrorCode::Success); + + // 12. Initiate connection from sender to listener + let (msg_cb_id, msg_callback) = CallbackUtils::closure_to_agent_message_cb(Box::new(move |conn_handle, err, msg| { + info!("On connection {} received (with error {:?}) agent message (SRV->CLI): {}", conn_handle, err, msg); + })); + let sender_did = CString::new(sender_did).unwrap(); + + let err = indy_agent_connect(connect_command_hamdle, pool_handle, sender_wallet, sender_did.as_ptr(), listener_did.as_ptr(), connect_callback, msg_callback); + assert_eq!(err, ErrorCode::Success); + let (err, conn_handle_sender_to_listener) = connect_receiver.recv_timeout(TimeoutUtils::medium_timeout()).unwrap(); + assert_eq!(err, ErrorCode::Success); + + CallbackUtils::closure_map_ids(msg_cb_id, conn_handle_sender_to_listener); + + // 13. Send test message from sender to listener + let message = "msg_from_sender_to_listener"; + let msg = CString::new(message).unwrap(); + + let res = indy_agent_send(agent_send_command_handle, conn_handle_sender_to_listener, msg.as_ptr(), agent_send_callback); + assert_eq!(res, ErrorCode::Success); + let res = send_receiver.recv_timeout(TimeoutUtils::medium_timeout()).unwrap(); + assert_eq!(res, ErrorCode::Success); + + // 14. Check message received + assert_eq!(wait_msg_from_srv_recv.recv_timeout(TimeoutUtils::short_timeout()).unwrap(), message); + + TestUtils::cleanup_storage(); +} + #[test] fn anoncreds_demo_works() { TestUtils::cleanup_storage(); @@ -69,7 +350,6 @@ fn anoncreds_demo_works() { let (open_wallet_sender, open_wallet_receiver) = channel(); let (issuer_create_claim_definition_sender, issuer_create_claim_definition_receiver) = channel(); // TODO: uncomment this for revocation part - //let (wallet_set_seq_no_for_value_sender2, wallet_set_seq_no_for_value_receiver2) = channel(); //let (issuer_create_and_store_revoc_reg_sender, issuer_create_and_store_revoc_reg_receiver) = channel(); let (prover_create_master_secret_sender, prover_create_master_secret_receiver) = channel(); let (prover_create_claim_req_sender, prover_create_claim_req_receiver) = channel(); @@ -89,9 +369,6 @@ fn anoncreds_demo_works() { open_wallet_sender.send((err, handle)).unwrap(); }); // TODO: uncomment this for revocation part - // let wallet_set_seq_no_for_value_cb2 = Box::new(move |err| { - // wallet_set_seq_no_for_value_sender2.send(err).unwrap(); - // }); // let issuer_create_and_store_revoc_reg_cb = Box::new(move |err, revoc_reg_json, revoc_reg_uuid| { // issuer_create_and_store_revoc_reg_sender.send((err, revoc_reg_json, revoc_reg_uuid)).unwrap(); // }); @@ -121,7 +398,6 @@ fn anoncreds_demo_works() { let (create_wallet_command_handle, create_wallet_callback) = CallbackUtils::closure_to_create_wallet_cb(create_wallet_cb); let (open_wallet_command_handle, open_wallet_callback) = CallbackUtils::closure_to_open_wallet_cb(open_wallet_cb); // TODO: uncomment this for revocation part - // let (wallet_set_seq_no_for_value_command_handle2, wallet_set_seq_no_for_value_callback2) = CallbackUtils::closure_to_wallet_set_seq_no_for_value_cb(wallet_set_seq_no_for_value_cb2); // let (issuer_create_and_store_revoc_reg_command_handle, issuer_create_and_store_revoc_reg_callback) = CallbackUtils::closure_to_issuer_create_and_store_revoc_reg_cb(issuer_create_and_store_revoc_reg_cb); let (prover_create_master_secret_command_handle, prover_create_master_secret_callback) = CallbackUtils::closure_to_prover_create_master_secret_cb(prover_create_master_secret_cb); let (prover_create_claim_req_command_handle, prover_create_claim_req_callback) = CallbackUtils::closure_to_prover_create_claim_req_cb(prover_create_claim_req_cb); @@ -139,12 +415,12 @@ fn anoncreds_demo_works() { //1. Create Wallet let err = indy_create_wallet(create_wallet_command_handle, - CString::new(pool_name).unwrap().as_ptr(), - CString::new(wallet_name).unwrap().as_ptr(), - CString::new(xtype).unwrap().as_ptr(), - null(), - null(), - create_wallet_callback); + CString::new(pool_name).unwrap().as_ptr(), + CString::new(wallet_name).unwrap().as_ptr(), + CString::new(xtype).unwrap().as_ptr(), + null(), + null(), + create_wallet_callback); assert_eq!(ErrorCode::Success, err); let err = create_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -153,10 +429,10 @@ fn anoncreds_demo_works() { //2. Open Issuer Wallet. Gets Issuer wallet handle let err = indy_open_wallet(open_wallet_command_handle, - CString::new(wallet_name).unwrap().as_ptr(), - null(), - null(), - open_wallet_callback); + CString::new(wallet_name).unwrap().as_ptr(), + null(), + null(), + open_wallet_callback); assert_eq!(ErrorCode::Success, err); let (err, wallet_handle) = open_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -176,12 +452,12 @@ fn anoncreds_demo_works() { // 3. Issuer create Claim Definition for Schema let err = indy_issuer_create_and_store_claim_def(issuer_create_claim_definition_command_handle, - wallet_handle, - CString::new(issuer_did.clone()).unwrap().as_ptr(), - CString::new(schema.clone()).unwrap().as_ptr(), - null(), - false, - create_claim_definition_callback); + wallet_handle, + CString::new(issuer_did.clone()).unwrap().as_ptr(), + CString::new(schema.clone()).unwrap().as_ptr(), + null(), + false, + create_claim_definition_callback); assert_eq!(ErrorCode::Success, err); let (err, claim_def_json) = issuer_create_claim_definition_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -205,25 +481,13 @@ fn anoncreds_demo_works() { // info!("revocation_reg_json: {:?}", revoc_reg_json); // assert_eq!(ErrorCode::Success, err); // - // // Create relationship between revoc_reg_seq_no and revoc_reg_uuid in wallet - // let revoc_reg_seq_no = 2; - // - // let err = indy_wallet_set_seq_no_for_value(wallet_set_seq_no_for_value_command_handle2, - // wallet_handle, - // CString::new(revoc_reg_uuid).unwrap().as_ptr(), - // revoc_reg_seq_no, - // wallet_set_seq_no_for_value_callback2); - // - // assert_eq!(ErrorCode::Success, err); - // let err = wallet_set_seq_no_for_value_receiver2.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); - // assert_eq!(ErrorCode::Success, err); // 5. Prover create Master Secret let err = indy_prover_create_master_secret(prover_create_master_secret_command_handle, - wallet_handle, - CString::new(master_secret_name).unwrap().as_ptr(), - prover_create_master_secret_callback); + wallet_handle, + CString::new(master_secret_name).unwrap().as_ptr(), + prover_create_master_secret_callback); assert_eq!(ErrorCode::Success, err); let err = prover_create_master_secret_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -235,12 +499,12 @@ fn anoncreds_demo_works() { // 6. Prover create Claim Request let err = indy_prover_create_and_store_claim_req(prover_create_claim_req_command_handle, - wallet_handle, - CString::new(prover_did).unwrap().as_ptr(), - CString::new(claim_offer_json).unwrap().as_ptr(), - CString::new(claim_def_json.clone()).unwrap().as_ptr(), - CString::new(master_secret_name).unwrap().as_ptr(), - prover_create_claim_req_callback); + wallet_handle, + CString::new(prover_did).unwrap().as_ptr(), + CString::new(claim_offer_json).unwrap().as_ptr(), + CString::new(claim_def_json.clone()).unwrap().as_ptr(), + CString::new(master_secret_name).unwrap().as_ptr(), + prover_create_claim_req_callback); assert_eq!(ErrorCode::Success, err); let (err, claim_req_json) = prover_create_claim_req_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -257,12 +521,12 @@ fn anoncreds_demo_works() { // 7. Issuer create Claim for Claim Request let err = indy_issuer_create_claim(issuer_create_claim_command_handle, - wallet_handle, - CString::new(claim_req_json).unwrap().as_ptr(), - CString::new(claim_json).unwrap().as_ptr(), - -1, - -1, - issuer_create_claim_callback); + wallet_handle, + CString::new(claim_req_json).unwrap().as_ptr(), + CString::new(claim_json).unwrap().as_ptr(), + -1, + -1, + issuer_create_claim_callback); assert_eq!(ErrorCode::Success, err); let (err, _, xclaim_json) = issuer_create_claim_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -272,9 +536,9 @@ fn anoncreds_demo_works() { // 7. Prover process and store Claim let err = indy_prover_store_claim(prover_store_claim_command_handle, - wallet_handle, - CString::new(xclaim_json).unwrap().as_ptr(), - prover_store_claim_callback); + wallet_handle, + CString::new(xclaim_json).unwrap().as_ptr(), + prover_store_claim_callback); assert_eq!(ErrorCode::Success, err); let err = prover_store_claim_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -291,9 +555,9 @@ fn anoncreds_demo_works() { // 8. Prover gets Claims for Proof Request let err = indy_prover_get_claims_for_proof_req(prover_get_claims_for_proof_req_handle, - wallet_handle, - CString::new(proof_req_json.clone()).unwrap().as_ptr(), - prover_get_claims_for_proof_req_callback); + wallet_handle, + CString::new(proof_req_json.clone()).unwrap().as_ptr(), + prover_get_claims_for_proof_req_callback); assert_eq!(ErrorCode::Success, err); let (err, claims_json) = prover_get_claims_for_proof_req_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -320,14 +584,14 @@ fn anoncreds_demo_works() { // 9. Prover create Proof for Proof Request let err = indy_prover_create_proof(prover_create_proof_handle, - wallet_handle, - CString::new(proof_req_json.clone()).unwrap().as_ptr(), - CString::new(requested_claims_json).unwrap().as_ptr(), - CString::new(schemas_json.clone()).unwrap().as_ptr(), - CString::new(master_secret_name).unwrap().as_ptr(), - CString::new(claim_defs_json.clone()).unwrap().as_ptr(), - CString::new(revoc_regs_jsons.clone()).unwrap().as_ptr(), - prover_create_proof_callback); + wallet_handle, + CString::new(proof_req_json.clone()).unwrap().as_ptr(), + CString::new(requested_claims_json).unwrap().as_ptr(), + CString::new(schemas_json.clone()).unwrap().as_ptr(), + CString::new(master_secret_name).unwrap().as_ptr(), + CString::new(claim_defs_json.clone()).unwrap().as_ptr(), + CString::new(revoc_regs_jsons.clone()).unwrap().as_ptr(), + prover_create_proof_callback); assert_eq!(ErrorCode::Success, err); let (err, proof_json) = prover_create_proof_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -337,12 +601,12 @@ fn anoncreds_demo_works() { // 10. Verifier verify proof let err = indy_verifier_verify_proof(verifier_verify_proof_handle, - CString::new(proof_req_json).unwrap().as_ptr(), - CString::new(proof_json).unwrap().as_ptr(), - CString::new(schemas_json).unwrap().as_ptr(), - CString::new(claim_defs_json).unwrap().as_ptr(), - CString::new(revoc_regs_jsons).unwrap().as_ptr(), - verifier_verify_proof_callback); + CString::new(proof_req_json).unwrap().as_ptr(), + CString::new(proof_json).unwrap().as_ptr(), + CString::new(schemas_json).unwrap().as_ptr(), + CString::new(claim_defs_json).unwrap().as_ptr(), + CString::new(revoc_regs_jsons).unwrap().as_ptr(), + verifier_verify_proof_callback); assert_eq!(ErrorCode::Success, err); let (err, result) = verifier_verify_proof_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -400,18 +664,18 @@ fn ledger_demo_works() { PoolUtils::create_genesis_txn_file(format!("{}.txn", pool_name).as_str(), None); let pool_config = CString::new(PoolUtils::create_default_pool_config(pool_name)).unwrap(); let err = indy_create_pool_ledger_config(create_command_handle, - c_pool_name.as_ptr(), - pool_config.as_ptr(), - create_callback); + c_pool_name.as_ptr(), + pool_config.as_ptr(), + create_callback); assert_eq!(err, ErrorCode::Success); let err = create_receiver.recv_timeout(TimeoutUtils::short_timeout()).unwrap(); assert_eq!(err, ErrorCode::Success); // 2. Open pool ledger let err = indy_open_pool_ledger(open_command_handle, - c_pool_name.as_ptr(), - null(), - open_callback); + c_pool_name.as_ptr(), + null(), + open_callback); assert_eq!(err, ErrorCode::Success); let (err, pool_handle) = open_receiver.recv_timeout(TimeoutUtils::short_timeout()).unwrap(); assert_eq!(err, ErrorCode::Success); @@ -420,12 +684,12 @@ fn ledger_demo_works() { // 3. Create My Wallet let err = indy_create_wallet(create_my_wallet_command_handle, - CString::new(pool_name).unwrap().as_ptr(), - CString::new(my_wallet_name).unwrap().as_ptr(), - CString::new(wallet_type).unwrap().as_ptr(), - null(), - null(), - create_my_wallet_callback); + CString::new(pool_name).unwrap().as_ptr(), + CString::new(my_wallet_name).unwrap().as_ptr(), + CString::new(wallet_type).unwrap().as_ptr(), + null(), + null(), + create_my_wallet_callback); assert_eq!(ErrorCode::Success, err); let err = create_my_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -434,10 +698,10 @@ fn ledger_demo_works() { // 4. Open My Wallet. Gets My wallet handle let err = indy_open_wallet(open_my_wallet_command_handle, - CString::new(my_wallet_name).unwrap().as_ptr(), - null(), - null(), - open_my_wallet_callback); + CString::new(my_wallet_name).unwrap().as_ptr(), + null(), + null(), + open_my_wallet_callback); assert_eq!(ErrorCode::Success, err); let (err, my_wallet_handle) = open_my_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -447,12 +711,12 @@ fn ledger_demo_works() { // 5. Create Their Wallet let err = indy_create_wallet(create_their_wallet_command_handle, - CString::new(pool_name).unwrap().as_ptr(), - CString::new(their_wallet_name).unwrap().as_ptr(), - CString::new(wallet_type).unwrap().as_ptr(), - null(), - null(), - create_their_wallet_callback); + CString::new(pool_name).unwrap().as_ptr(), + CString::new(their_wallet_name).unwrap().as_ptr(), + CString::new(wallet_type).unwrap().as_ptr(), + null(), + null(), + create_their_wallet_callback); assert_eq!(ErrorCode::Success, err); let err = create_their_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -461,10 +725,10 @@ fn ledger_demo_works() { // 6. Open Their Wallet. Gets Their wallet handle let err = indy_open_wallet(open_their_wallet_command_handle, - CString::new(their_wallet_name).unwrap().as_ptr(), - null(), - null(), - open_their_wallet_callback); + CString::new(their_wallet_name).unwrap().as_ptr(), + null(), + null(), + open_their_wallet_callback); assert_eq!(ErrorCode::Success, err); let (err, their_wallet_handle) = open_their_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -474,9 +738,9 @@ fn ledger_demo_works() { let my_did_json = "{}"; let err = indy_create_and_store_my_did(create_and_store_my_did_command_handle, - my_wallet_handle, - CString::new(my_did_json).unwrap().as_ptr(), - create_and_store_my_did_callback); + my_wallet_handle, + CString::new(my_did_json).unwrap().as_ptr(), + create_and_store_my_did_callback); assert_eq!(ErrorCode::Success, err); let (err, my_did, my_verkey, my_pk) = create_and_store_my_did_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -489,9 +753,9 @@ fn ledger_demo_works() { let their_did_json = r#"{"seed":"000000000000000000000000Trustee1"}"#; let err = indy_create_and_store_my_did(create_and_store_their_did_command_handle, - their_wallet_handle, - CString::new(their_did_json).unwrap().as_ptr(), - create_and_store_their_did_callback); + their_wallet_handle, + CString::new(their_did_json).unwrap().as_ptr(), + create_and_store_their_did_callback); assert_eq!(ErrorCode::Success, err); let (err, their_did, their_verkey, their_pk) = create_and_store_their_did_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -508,9 +772,9 @@ fn ledger_demo_works() { their_did, their_pk, their_verkey); let err = indy_store_their_did(store_their_did_command_handle, - my_wallet_handle, - CString::new(their_identity_json).unwrap().as_ptr(), - store_their_did_callback); + my_wallet_handle, + CString::new(their_identity_json).unwrap().as_ptr(), + store_their_did_callback); assert_eq!(ErrorCode::Success, err); let err = store_their_did_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -519,7 +783,7 @@ fn ledger_demo_works() { // 10. Prepare NYM transaction let nym_req_id = PoolUtils::get_req_id(); let nym_txn_req = Request { - identifier: their_verkey.clone(), + identifier: their_did.clone(), operation: Operation { dest: my_did.clone(), type_: "1".to_string(), @@ -533,11 +797,11 @@ fn ledger_demo_works() { let req = CString::new(msg).unwrap(); let did_for_sign = CString::new(their_did).unwrap(); let err = indy_sign_and_submit_request(send_command_handle, - pool_handle, - their_wallet_handle, - did_for_sign.as_ptr(), - req.as_ptr(), - send_callback); + pool_handle, + their_wallet_handle, + did_for_sign.as_ptr(), + req.as_ptr(), + send_callback); assert_eq!(err, ErrorCode::Success); let (err, resp) = submit_receiver.recv_timeout(TimeoutUtils::medium_timeout()).unwrap(); assert_eq!(err, ErrorCode::Success); @@ -560,9 +824,9 @@ fn ledger_demo_works() { let request = serde_json::to_string(&get_nym_txn).unwrap(); let req = CString::new(request).unwrap(); let err = indy_submit_request(get_nym_command_handle, - pool_handle, - req.as_ptr(), - get_nym_callback); + pool_handle, + req.as_ptr(), + get_nym_callback); assert_eq!(err, ErrorCode::Success); let (err, resp) = get_nym_receiver.recv_timeout(TimeoutUtils::medium_timeout()).unwrap(); assert_eq!(err, ErrorCode::Success); @@ -675,12 +939,12 @@ fn signus_demo_works() { //1. Create My Wallet let err = indy_create_wallet(create_my_wallet_command_handle, - CString::new(pool_name).unwrap().as_ptr(), - CString::new(my_wallet_name).unwrap().as_ptr(), - CString::new(xtype).unwrap().as_ptr(), - null(), - null(), - create_my_wallet_callback); + CString::new(pool_name).unwrap().as_ptr(), + CString::new(my_wallet_name).unwrap().as_ptr(), + CString::new(xtype).unwrap().as_ptr(), + null(), + null(), + create_my_wallet_callback); assert_eq!(ErrorCode::Success, err); let err = create_my_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -689,10 +953,10 @@ fn signus_demo_works() { //2. Open My Wallet. Gets My wallet handle let err = indy_open_wallet(open_my_wallet_command_handle, - CString::new(my_wallet_name).unwrap().as_ptr(), - null(), - null(), - open_my_wallet_callback); + CString::new(my_wallet_name).unwrap().as_ptr(), + null(), + null(), + open_my_wallet_callback); assert_eq!(ErrorCode::Success, err); let (err, my_wallet_handle) = open_my_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -702,12 +966,12 @@ fn signus_demo_works() { //3. Create Their Wallet let err = indy_create_wallet(create_their_wallet_command_handle, - CString::new(pool_name).unwrap().as_ptr(), - CString::new(their_wallet_name).unwrap().as_ptr(), - CString::new(xtype).unwrap().as_ptr(), - null(), - null(), - create_their_wallet_callback); + CString::new(pool_name).unwrap().as_ptr(), + CString::new(their_wallet_name).unwrap().as_ptr(), + CString::new(xtype).unwrap().as_ptr(), + null(), + null(), + create_their_wallet_callback); assert_eq!(ErrorCode::Success, err); let err = create_their_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -716,10 +980,10 @@ fn signus_demo_works() { //4. Open Their Wallet. Gets Their wallet handle let err = indy_open_wallet(open_their_wallet_command_handle, - CString::new(their_wallet_name).unwrap().as_ptr(), - null(), - null(), - open_their_wallet_callback); + CString::new(their_wallet_name).unwrap().as_ptr(), + null(), + null(), + open_their_wallet_callback); assert_eq!(ErrorCode::Success, err); let (err, their_wallet_handle) = open_their_wallet_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -729,9 +993,9 @@ fn signus_demo_works() { let my_did_json = "{}"; let err = indy_create_and_store_my_did(create_and_store_my_did_command_handle, - my_wallet_handle, - CString::new(my_did_json).unwrap().as_ptr(), - create_and_store_my_did_callback); + my_wallet_handle, + CString::new(my_did_json).unwrap().as_ptr(), + create_and_store_my_did_callback); assert_eq!(ErrorCode::Success, err); let (err, my_did, my_verkey, my_pk) = create_and_store_my_did_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -744,9 +1008,9 @@ fn signus_demo_works() { let their_did_json = "{}"; let err = indy_create_and_store_my_did(create_and_store_their_did_command_handle, - their_wallet_handle, - CString::new(their_did_json).unwrap().as_ptr(), - create_and_store_their_did_callback); + their_wallet_handle, + CString::new(their_did_json).unwrap().as_ptr(), + create_and_store_their_did_callback); assert_eq!(ErrorCode::Success, err); let (err, their_did, their_verkey, their_pk) = create_and_store_their_did_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -763,9 +1027,9 @@ fn signus_demo_works() { their_did, their_pk, their_verkey); let err = indy_store_their_did(store_their_did_command_handle, - my_wallet_handle, - CString::new(their_identity_json).unwrap().as_ptr(), - store_their_did_callback); + my_wallet_handle, + CString::new(their_identity_json).unwrap().as_ptr(), + store_their_did_callback); assert_eq!(ErrorCode::Success, err); let err = store_their_did_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -783,10 +1047,10 @@ fn signus_demo_works() { }"#; let err = indy_sign(sign_command_handle, - their_wallet_handle, - CString::new(their_did.clone()).unwrap().as_ptr(), - CString::new(message.clone()).unwrap().as_ptr(), - sign_callback); + their_wallet_handle, + CString::new(their_did.clone()).unwrap().as_ptr(), + CString::new(message.clone()).unwrap().as_ptr(), + sign_callback); assert_eq!(ErrorCode::Success, err); let (err, signed_msg) = sign_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); @@ -796,11 +1060,11 @@ fn signus_demo_works() { // 9. I Verify message let err = indy_verify_signature(verify_command_handle, - my_wallet_handle, - 1, - CString::new(their_did).unwrap().as_ptr(), - CString::new(signed_msg).unwrap().as_ptr(), - verify_callback); + my_wallet_handle, + 1, + CString::new(their_did).unwrap().as_ptr(), + CString::new(signed_msg).unwrap().as_ptr(), + verify_callback); assert_eq!(ErrorCode::Success, err); let (err, valid) = verify_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); diff --git a/tests/ledger.rs b/tests/ledger.rs index be04b30623..4a28580875 100644 --- a/tests/ledger.rs +++ b/tests/ledger.rs @@ -37,8 +37,7 @@ use utils::types::{ Reply, SchemaResult, GetTxnResult, - SchemaData, - Schema + SchemaData }; use std::collections::{HashSet}; // TODO: FIXME: create_my_did doesn't support CID creation, but this trustee has CID as DID. So it is rough workaround for this issue. @@ -60,7 +59,7 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let get_nym_request = LedgerUtils::build_get_nym_request(&my_did.clone(), &my_did.clone()).unwrap(); @@ -80,8 +79,8 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), None, None, None).unwrap(); @@ -101,8 +100,8 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), None, None, None).unwrap(); @@ -121,9 +120,9 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config("pool1").unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet("pool2", None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), None, None, None).unwrap(); let res = LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &trustee_did, &nym_request); @@ -145,7 +144,7 @@ mod high_cases { "identifier":"Th7MpTaRZVRYnPiabds81Y", "operation":{ "type":"105", - "dest":"FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4" + "dest":"Th7MpTaRZVRYnPiabds81Y" }, "signature":"4o86XfkiJ4e2r3J6Ufoi17UU3W5Zi9sshV6FjBjkVw4sgEQFQov9dxqDEtLbAJAWffCWd5KfAk164QVo7mYwKkiV"}"#; @@ -156,9 +155,9 @@ mod high_cases { result: GetNymReplyResult { _type: "105".to_string(), req_id: 1491566332010860, - data: Some(r#"{"dest":"FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4","identifier":"GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL","role":"2","verkey":null}"#.to_string()), + data: Some(r#"{"dest":"Th7MpTaRZVRYnPiabds81Y","identifier":"V4SGRU86Z58d6TV7PBUe6f","role":"2","verkey":"~7TYfekw4GUagBnBVCqPjiC"}"#.to_string()), identifier: "Th7MpTaRZVRYnPiabds81Y".to_string(), - dest: "FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4".to_string(), + dest: "Th7MpTaRZVRYnPiabds81Y".to_string(), } }; let act_reply: Reply = serde_json::from_str(resp.unwrap().as_str()).unwrap(); @@ -175,8 +174,8 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), None, None, None).unwrap(); LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &trustee_did, &nym_request).unwrap(); @@ -257,7 +256,7 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); let nym_request = LedgerUtils::build_nym_request(&my_did.clone(), &my_did.clone(), None, None, None).unwrap(); @@ -277,7 +276,7 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let get_nym_request = LedgerUtils::build_get_nym_request(&my_did.clone(), &my_did.clone()).unwrap(); @@ -297,8 +296,8 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); - let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); + let (my_did, my_verkey, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), Some(&my_verkey.clone()), None, None).unwrap(); @@ -381,7 +380,7 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let attrib_request = LedgerUtils::build_attrib_request(&my_did.clone(), &my_did.clone(), @@ -405,8 +404,8 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); - let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); + let (my_did, my_verkey, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), Some(&my_verkey.clone()), None, None).unwrap(); LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &trustee_did, &nym_request).unwrap(); @@ -470,7 +469,7 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let schema_data = "{\"name\":\"gvt2\",\ \"version\":\"2.0\",\ @@ -494,7 +493,7 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, "{}").unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), Some(&my_verkey.clone()), None, None).unwrap(); @@ -530,9 +529,9 @@ mod high_cases { fn indy_build_node_request_works_for_correct_data_json() { let identifier = "identifier"; let dest = "dest"; - let data = r#"{"node_ip":"ip", "node_port": 1, "client_ip": "ip", "client_port": 1, "alias":"some", "services": ["VALIDATOR"]}"#; + let data = r#"{"node_ip":"10.0.0.100", "node_port": 1, "client_ip": "10.0.0.100", "client_port": 1, "alias":"some", "services": ["VALIDATOR"]}"#; - let expected_result = r#""identifier":"identifier","operation":{"type":"0","dest":"dest","data":{"node_ip":"ip","node_port":1,"client_ip":"ip","client_port":1,"alias":"some","services":["VALIDATOR"]}}"#; + let expected_result = r#""identifier":"identifier","operation":{"type":"0","dest":"dest","data":{"node_ip":"10.0.0.100","node_port":1,"client_ip":"10.0.0.100","client_port":1,"alias":"some","services":["VALIDATOR"]}}"#; let node_request = LedgerUtils::build_node_request(identifier, dest, data).unwrap(); assert!(node_request.contains(expected_result)); @@ -548,7 +547,7 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Steward1","cid":true}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Steward1")).unwrap(); let node_data = "{\"node_ip\":\"10.0.0.100\",\ \"node_port\":9710, \ @@ -576,8 +575,8 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); - let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1","cid":true}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); + let (my_did, my_verkey, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); let role = "STEWARD"; let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), Some(&my_verkey), None, Some(role)).unwrap(); @@ -629,6 +628,51 @@ mod high_cases { assert!(get_claim_def_request.contains(expected_result)); } + #[test] + #[cfg(feature = "local_nodes_pool")] + fn indy_claim_def_request_works_without_signature() { + TestUtils::cleanup_storage(); + let pool_name = "indy_claim_def_request_works_without_signature"; + + let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); + let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); + + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); + let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, "{}").unwrap(); + + let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), Some(&my_verkey.clone()), None, None).unwrap(); + LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &trustee_did, &nym_request).unwrap(); + + let schema_data = "{\"name\":\"gvt2\",\ + \"version\":\"2.0\",\ + \"keys\": [\"name\", \"male\"]}"; + let schema_request = LedgerUtils::build_schema_request(&my_did.clone(), schema_data).unwrap(); + LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &my_did, &schema_request).unwrap(); + + let get_schema_data = "{\"name\":\"gvt2\",\"version\":\"2.0\"}"; + let get_schema_request = LedgerUtils::build_get_schema_request(&my_did.clone(), &my_did, get_schema_data).unwrap(); + let get_schema_response = PoolUtils::send_request(pool_handle, &get_schema_request).unwrap(); + + let get_schema_response: Reply = serde_json::from_str(&get_schema_response).unwrap(); + + let claim_def_json = AnoncredsUtils::get_gvt_claim_def(); + + let claim_def: ClaimDefinition = serde_json::from_str(&claim_def_json).unwrap(); + let claim_def_data = ClaimDefinitionData { + public_key: claim_def.data.public_key, + public_key_revocation: claim_def.data.public_key_revocation + }; + let claim_def_data_json = serde_json::to_string(&claim_def_data).unwrap(); + + let claim_def_request = LedgerUtils::build_claim_def_txn(&my_did.clone(), get_schema_response.result.seq_no.unwrap(), + &claim_def.signature_type, &claim_def_data_json).unwrap(); + + let res = PoolUtils::send_request(pool_handle, &claim_def_request); + assert_eq!(res.unwrap_err(), ErrorCode::LedgerInvalidTransaction); + + TestUtils::cleanup_storage(); + } + #[test] #[cfg(feature = "local_nodes_pool")] fn indy_claim_def_requests_works() { @@ -638,7 +682,7 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, "{}").unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), Some(&my_verkey.clone()), None, None).unwrap(); @@ -656,9 +700,7 @@ mod high_cases { let get_schema_response: Reply = serde_json::from_str(&get_schema_response).unwrap(); - let claim_def_json = AnoncredsUtils::issuer_create_claim_definition(wallet_handle, "NcYxiDXkpYi6ov5FcYDi1e", - &serde_json::to_string(&get_schema_response.result).unwrap(), None, false).unwrap(); - info!("claim_def_json {:}", claim_def_json); + let claim_def_json = AnoncredsUtils::get_gvt_claim_def(); let claim_def: ClaimDefinition = serde_json::from_str(&claim_def_json).unwrap(); let claim_def_data = ClaimDefinitionData { @@ -702,7 +744,6 @@ mod high_cases { } #[test] - #[ignore]//Delete it after merge https://github.com/hyperledger/indy-plenum/pull/265 #[cfg(feature = "local_nodes_pool")] fn indy_get_txn_request_works() { TestUtils::cleanup_storage(); @@ -711,7 +752,7 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let mut keys: HashSet = HashSet::new(); keys.insert("name".to_string()); @@ -721,7 +762,7 @@ mod high_cases { version: "3.0".to_string(), keys: keys }; - let schema_data_json = serde_json::to_string(&schema_data).unwrap(); + let schema_data_json = serde_json::to_string(&schema_data).unwrap(); let schema_request = LedgerUtils::build_schema_request(&my_did.clone(), &schema_data_json).unwrap(); let schema_response = LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &my_did, &schema_request).unwrap(); let schema_response: Reply = serde_json::from_str(&schema_response).unwrap(); @@ -733,20 +774,21 @@ mod high_cases { let seq_no = schema_response.result.seq_no; let get_txn_request = LedgerUtils::build_get_txn_request(&my_did, seq_no).unwrap(); - let get_txn_response = LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &my_did, &get_txn_request).unwrap(); + let get_txn_response = LedgerUtils::submit_request(pool_handle, &get_txn_request).unwrap(); let get_txn_response: Reply = serde_json::from_str(&get_txn_response).unwrap(); - assert!(get_txn_response.result.data.is_some()); - let get_txn_schema: Schema = serde_json::from_str(&get_txn_response.result.data.unwrap()).unwrap(); + let get_txn_schema_result: SchemaResult = serde_json::from_str(&get_txn_response.result.data).unwrap(); + assert!(get_txn_schema_result.data.is_some()); + + let get_txn_schema_data: SchemaData = serde_json::from_str(&get_txn_schema_result.data.unwrap()).unwrap(); - assert_eq!(schema_data, get_txn_schema.data); + assert_eq!(schema_data, get_txn_schema_data); TestUtils::cleanup_storage(); } #[test] - #[ignore]//Delete it after merge https://github.com/hyperledger/indy-plenum/pull/265 #[cfg(feature = "local_nodes_pool")] fn indy_get_txn_request_works_for_invalid_seq_no() { TestUtils::cleanup_storage(); @@ -755,7 +797,7 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let mut keys: HashSet = HashSet::new(); keys.insert("name".to_string()); @@ -765,7 +807,7 @@ mod high_cases { version: "3.0".to_string(), keys: keys }; - let schema_data_json = serde_json::to_string(&schema_data).unwrap(); + let schema_data_json = serde_json::to_string(&schema_data).unwrap(); let schema_request = LedgerUtils::build_schema_request(&my_did.clone(), &schema_data_json).unwrap(); let schema_response = LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &my_did, &schema_request).unwrap(); let schema_response: Reply = serde_json::from_str(&schema_response).unwrap(); @@ -774,9 +816,9 @@ mod high_cases { let get_txn_request = LedgerUtils::build_get_txn_request(&my_did, seq_no).unwrap(); - let get_txn_response = LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &my_did, &get_txn_request).unwrap(); + let get_txn_response = LedgerUtils::submit_request(pool_handle, &get_txn_request).unwrap(); let get_txn_response: Reply = serde_json::from_str(&get_txn_response).unwrap(); - assert!(get_txn_response.result.data.is_none()); + assert_eq!(get_txn_response.result.data, "{}".to_string()); /* FIXME: unify with other GET_ transactions (data.is_none()) */ TestUtils::cleanup_storage(); } @@ -798,12 +840,12 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); - let trustee_did = "trusteedid"; - let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), None, None, None).unwrap(); + let signer_did = "Fjc4fCrwGxBq2BkqGs5wEu"; + let nym_request = LedgerUtils::build_nym_request(&signer_did.clone(), &my_did.clone(), None, None, None).unwrap(); - let res = LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &trustee_did, &nym_request); + let res = LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &signer_did, &nym_request); assert_eq!(res.unwrap_err(), ErrorCode::WalletNotFoundError); TestUtils::cleanup_storage(); @@ -834,7 +876,7 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let request = r#"request"#; let res = LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &trustee_did, &request); @@ -856,8 +898,8 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), None, None, None).unwrap(); @@ -876,9 +918,9 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); - let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (my_did, my_verkey, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); let role = "STEWARD"; let alias = "some_alias"; @@ -912,7 +954,7 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, "{\"cid\":true}").unwrap(); @@ -939,7 +981,7 @@ mod medium_cases { let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee9","cid":true}"#).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), None, None, None).unwrap(); let res = LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &trustee_did, &nym_request); @@ -1004,7 +1046,7 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, None).unwrap(); let attrib_request = LedgerUtils::build_attrib_request(&my_did.clone(), &my_did.clone(), @@ -1050,7 +1092,7 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let get_attrib_request = LedgerUtils::build_get_attrib_request(&my_did.clone(), &my_did.clone(), "some_attribute").unwrap(); @@ -1150,11 +1192,10 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let get_schema_data = "{\"name\":\"schema_name\",\"version\":\"2.0\"}"; let get_schema_request = LedgerUtils::build_get_schema_request(&my_did.clone(), &my_did.clone(), get_schema_data).unwrap(); - ; let get_schema_response = PoolUtils::send_request(pool_handle, &get_schema_request).unwrap(); let get_schema_response: Reply = serde_json::from_str(&get_schema_response).unwrap(); @@ -1171,7 +1212,7 @@ mod medium_cases { fn indy_build_node_request_works_for_missed_field_in_data_json() { let identifier = "identifier"; let dest = "dest"; - let data = r#"{"node_ip":"ip", "node_port": 1, "client_ip": "ip", "client_port": 1}"#; + let data = r#"{"node_ip":"10.0.0.100", "node_port": 1, "client_ip": "10.0.0.100", "client_port": 1}"#; let res = LedgerUtils::build_node_request(identifier, dest, data); assert!(res.is_err()); @@ -1182,7 +1223,7 @@ mod medium_cases { fn indy_build_node_request_works_for_wrong_service() { let identifier = "identifier"; let dest = "dest"; - let data = r#"{"node_ip":"ip", "node_port": 1, "client_ip": "ip", "client_port": 1, "alias":"some", "services": ["SERVICE"]}"#; + let data = r#"{"node_ip":"10.0.0.100", "node_port": 1, "client_ip": "10.0.0.100", "client_port": 1, "alias":"some", "services": ["SERVICE"]}"#; let res = LedgerUtils::build_node_request(identifier, dest, data); assert!(res.is_err()); @@ -1198,7 +1239,7 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let node_data = "{\"node_ip\":\"10.0.0.100\",\ \"node_port\":9710, \ @@ -1224,7 +1265,7 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Steward1","cid":true}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Steward1")).unwrap(); let node_data = "{\"node_ip\":\"10.0.0.100\",\ \"node_port\":9710, \ diff --git a/tests/pool.rs b/tests/pool.rs index fdad008679..07ee6a8ad8 100644 --- a/tests/pool.rs +++ b/tests/pool.rs @@ -131,8 +131,8 @@ mod high_cases { let pool_name = "open_pool_ledger_works_for_two_nodes"; let nodes = format!("{}\n{}\n", - "{\"data\":{\"alias\":\"Node1\",\"client_ip\":\"10.0.0.2\",\"client_port\":9702,\"node_ip\":\"10.0.0.2\",\"node_port\":9701,\"services\":[\"VALIDATOR\"]},\"dest\":\"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv\",\"identifier\":\"FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4\",\"txnId\":\"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62\",\"type\":\"0\"}", - "{\"data\":{\"alias\":\"Node2\",\"client_ip\":\"10.0.0.2\",\"client_port\":9704,\"node_ip\":\"10.0.0.2\",\"node_port\":9703,\"services\":[\"VALIDATOR\"]},\"dest\":\"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb\",\"identifier\":\"8QhFxKxyaFsJy4CyxeYX34dFH8oWqyBv1P4HLQCsoeLy\",\"txnId\":\"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc\",\"type\":\"0\"}"); + "{\"data\":{\"alias\":\"Node1\",\"client_ip\":\"10.0.0.2\",\"client_port\":9702,\"node_ip\":\"10.0.0.2\",\"node_port\":9701,\"services\":[\"VALIDATOR\"]},\"dest\":\"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv\",\"identifier\":\"Th7MpTaRZVRYnPiabds81Y\",\"txnId\":\"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62\",\"type\":\"0\"}", + "{\"data\":{\"alias\":\"Node2\",\"client_ip\":\"10.0.0.2\",\"client_port\":9704,\"node_ip\":\"10.0.0.2\",\"node_port\":9703,\"services\":[\"VALIDATOR\"]},\"dest\":\"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb\",\"identifier\":\"EbP4aYNeTHL6q385GuVpRV\",\"txnId\":\"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc\",\"type\":\"0\"}"); PoolUtils::create_pool_ledger_config(pool_name, Some(nodes), None, None).unwrap(); @@ -149,9 +149,9 @@ mod high_cases { let pool_name = "open_pool_ledger_works_for_three_nodes"; let nodes = format!("{}\n{}\n{}\n", - "{\"data\":{\"alias\":\"Node1\",\"client_ip\":\"10.0.0.2\",\"client_port\":9702,\"node_ip\":\"10.0.0.2\",\"node_port\":9701,\"services\":[\"VALIDATOR\"]},\"dest\":\"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv\",\"identifier\":\"FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4\",\"txnId\":\"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62\",\"type\":\"0\"}", - "{\"data\":{\"alias\":\"Node2\",\"client_ip\":\"10.0.0.2\",\"client_port\":9704,\"node_ip\":\"10.0.0.2\",\"node_port\":9703,\"services\":[\"VALIDATOR\"]},\"dest\":\"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb\",\"identifier\":\"8QhFxKxyaFsJy4CyxeYX34dFH8oWqyBv1P4HLQCsoeLy\",\"txnId\":\"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc\",\"type\":\"0\"}", - "{\"data\":{\"alias\":\"Node3\",\"client_ip\":\"10.0.0.2\",\"client_port\":9706,\"node_ip\":\"10.0.0.2\",\"node_port\":9705,\"services\":[\"VALIDATOR\"]},\"dest\":\"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya\",\"identifier\":\"2yAeV5ftuasWNgQwVYzeHeTuM7LwwNtPR3Zg9N4JiDgF\",\"txnId\":\"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4\",\"type\":\"0\"}"); + "{\"data\":{\"alias\":\"Node1\",\"client_ip\":\"10.0.0.2\",\"client_port\":9702,\"node_ip\":\"10.0.0.2\",\"node_port\":9701,\"services\":[\"VALIDATOR\"]},\"dest\":\"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv\",\"identifier\":\"Th7MpTaRZVRYnPiabds81Y\",\"txnId\":\"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62\",\"type\":\"0\"}", + "{\"data\":{\"alias\":\"Node2\",\"client_ip\":\"10.0.0.2\",\"client_port\":9704,\"node_ip\":\"10.0.0.2\",\"node_port\":9703,\"services\":[\"VALIDATOR\"]},\"dest\":\"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb\",\"identifier\":\"EbP4aYNeTHL6q385GuVpRV\",\"txnId\":\"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc\",\"type\":\"0\"}", + "{\"data\":{\"alias\":\"Node3\",\"client_ip\":\"10.0.0.2\",\"client_port\":9706,\"node_ip\":\"10.0.0.2\",\"node_port\":9705,\"services\":[\"VALIDATOR\"]},\"dest\":\"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya\",\"identifier\":\"4cU41vWW82ArfxJxHkzXPG\",\"txnId\":\"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4\",\"type\":\"0\"}"); PoolUtils::create_pool_ledger_config(pool_name, Some(nodes), None, None).unwrap(); @@ -319,10 +319,10 @@ mod medium_cases { let pool_name = "open_pool_ledger_works_for_invalid_nodes_file"; let nodes = format!("{}\n{}\n{}\n{}\n", - "{\"data\":{\"client_port\":9702,\"client_ip\":\"10.0.0.2\",\"node_ip\":\"10.0.0.2\",\"node_port\":9701,\"services\":[\"VALIDATOR\"]},\"dest\":\"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv\",\"identifier\":\"FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4\",\"txnId\":\"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62\",\"type\":\"0\"}", - "{\"data\":{\"client_port\":9704,\"client_ip\":\"10.0.0.2\",\"node_ip\":\"10.0.0.2\",\"node_port\":9703,\"services\":[\"VALIDATOR\"]},\"dest\":\"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb\",\"identifier\":\"8QhFxKxyaFsJy4CyxeYX34dFH8oWqyBv1P4HLQCsoeLy\",\"txnId\":\"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc\",\"type\":\"0\"}", - "{\"data\":{\"client_port\":9706,\"client_ip\":\"10.0.0.2\",\"node_ip\":\"10.0.0.2\",\"node_port\":9705,\"services\":[\"VALIDATOR\"]},\"dest\":\"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya\",\"identifier\":\"2yAeV5ftuasWNgQwVYzeHeTuM7LwwNtPR3Zg9N4JiDgF\",\"txnId\":\"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4\",\"type\":\"0\"}", - "{\"data\":{\"client_port\":9708,\"client_ip\":\"10.0.0.2\",\"node_ip\":\"10.0.0.2\",\"node_port\":9707,\"services\":[\"VALIDATOR\"]},\"dest\":\"4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA\",\"identifier\":\"FTE95CVthRtrBnK2PYCBbC9LghTcGwi9Zfi1Gz2dnyNx\",\"txnId\":\"aa5e817d7cc626170eca175822029339a444eb0ee8f0bd20d3b0b76e566fb008\",\"type\":\"0\"}"); + "{\"data\":{\"client_ip\":\"10.0.0.2\",\"client_port\":9702,\"node_ip\":\"10.0.0.2\",\"node_port\":9701,\"services\":[\"VALIDATOR\"]},\"dest\":\"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv\",\"identifier\":\"Th7MpTaRZVRYnPiabds81Y\",\"txnId\":\"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62\",\"type\":\"0\"}", + "{\"data\":{\"client_ip\":\"10.0.0.2\",\"client_port\":9704,\"node_ip\":\"10.0.0.2\",\"node_port\":9703,\"services\":[\"VALIDATOR\"]},\"dest\":\"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb\",\"identifier\":\"EbP4aYNeTHL6q385GuVpRV\",\"txnId\":\"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc\",\"type\":\"0\"}", + "{\"data\":{\"client_ip\":\"10.0.0.2\",\"client_port\":9706,\"node_ip\":\"10.0.0.2\",\"node_port\":9705,\"services\":[\"VALIDATOR\"]},\"dest\":\"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya\",\"identifier\":\"4cU41vWW82ArfxJxHkzXPG\",\"txnId\":\"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4\",\"type\":\"0\"}", + "{\"data\":{\"client_ip\":\"10.0.0.2\",\"client_port\":9708,\"node_ip\":\"10.0.0.2\",\"node_port\":9707,\"services\":[\"VALIDATOR\"]},\"dest\":\"4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA\",\"identifier\":\"TWwCRQRZ2ZHMJFn9TzLp7W\",\"txnId\":\"aa5e817d7cc626170eca175822029339a444eb0ee8f0bd20d3b0b76e566fb008\",\"type\":\"0\"}"); PoolUtils::create_pool_ledger_config(pool_name, Some(nodes), None, None).unwrap(); @@ -339,10 +339,10 @@ mod medium_cases { let pool_name = "open_pool_ledger_works_for_wrong_alias"; let nodes = format!("{}\n{}\n{}\n{}\n", - "{\"data\":{\"alias\":\"Node1\",\"client_ip\":\"10.0.0.2\",\"client_port\":9702,\"node_ip\":\"10.0.0.2\",\"node_port\":9701,\"services\":[\"VALIDATOR\"]},\"dest\":\"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv\",\"identifier\":\"FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4\",\"txnId\":\"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62\",\"type\":\"0\"}", - "{\"data\":{\"alias\":\"Node2\",\"client_ip\":\"10.0.0.2\",\"client_port\":9704,\"node_ip\":\"10.0.0.2\",\"node_port\":9703,\"services\":[\"VALIDATOR\"]},\"dest\":\"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb\",\"identifier\":\"8QhFxKxyaFsJy4CyxeYX34dFH8oWqyBv1P4HLQCsoeLy\",\"txnId\":\"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc\",\"type\":\"0\"}", - "{\"data\":{\"alias\":\"Node3\",\"client_ip\":\"10.0.0.2\",\"client_port\":9706,\"node_ip\":\"10.0.0.2\",\"node_port\":9705,\"services\":[\"VALIDATOR\"]},\"dest\":\"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya\",\"identifier\":\"2yAeV5ftuasWNgQwVYzeHeTuM7LwwNtPR3Zg9N4JiDgF\",\"txnId\":\"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4\",\"type\":\"0\"}", - "{\"data\":{\"alias\":\"ALIAS_NODE\",\"client_ip\":\"10.0.0.2\",\"client_port\":9708,\"node_ip\":\"10.0.0.2\",\"node_port\":9707,\"services\":[\"VALIDATOR\"]},\"dest\":\"4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA\",\"identifier\":\"FTE95CVthRtrBnK2PYCBbC9LghTcGwi9Zfi1Gz2dnyNx\",\"txnId\":\"aa5e817d7cc626170eca175822029339a444eb0ee8f0bd20d3b0b76e566fb008\",\"type\":\"0\"}"); + "{\"data\":{\"alias\":\"Node1\",\"client_ip\":\"10.0.0.2\",\"client_port\":9702,\"node_ip\":\"10.0.0.2\",\"node_port\":9701,\"services\":[\"VALIDATOR\"]},\"dest\":\"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv\",\"identifier\":\"Th7MpTaRZVRYnPiabds81Y\",\"txnId\":\"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62\",\"type\":\"0\"}", + "{\"data\":{\"alias\":\"Node2\",\"client_ip\":\"10.0.0.2\",\"client_port\":9704,\"node_ip\":\"10.0.0.2\",\"node_port\":9703,\"services\":[\"VALIDATOR\"]},\"dest\":\"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb\",\"identifier\":\"EbP4aYNeTHL6q385GuVpRV\",\"txnId\":\"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc\",\"type\":\"0\"}", + "{\"data\":{\"alias\":\"Node3\",\"client_ip\":\"10.0.0.2\",\"client_port\":9706,\"node_ip\":\"10.0.0.2\",\"node_port\":9705,\"services\":[\"VALIDATOR\"]},\"dest\":\"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya\",\"identifier\":\"4cU41vWW82ArfxJxHkzXPG\",\"txnId\":\"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4\",\"type\":\"0\"}", + "{\"data\":{\"alias\":\"ALIAS_NODE\",\"client_ip\":\"10.0.0.2\",\"client_port\":9708,\"node_ip\":\"10.0.0.2\",\"node_port\":9707,\"services\":[\"VALIDATOR\"]},\"dest\":\"4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA\",\"identifier\":\"TWwCRQRZ2ZHMJFn9TzLp7W\",\"txnId\":\"aa5e817d7cc626170eca175822029339a444eb0ee8f0bd20d3b0b76e566fb008\",\"type\":\"0\"}"); PoolUtils::create_pool_ledger_config(pool_name, Some(nodes), None, None).unwrap(); diff --git a/tests/signus.rs b/tests/signus.rs index 6868929fec..a3903ce332 100644 --- a/tests/signus.rs +++ b/tests/signus.rs @@ -90,6 +90,17 @@ mod high_cases { TestUtils::cleanup_storage(); } + #[test] + fn indy_create_my_did_works_for_exists_crypto_type() { + TestUtils::cleanup_storage(); + + let wallet_handle = WalletUtils::create_and_open_wallet("pool1", None).unwrap(); + + SignusUtils::create_my_did(wallet_handle, r#"{"crypto_type":"ed25519"}"#).unwrap(); + + TestUtils::cleanup_storage(); + } + #[test] fn indy_create_my_did_works_for_invalid_wallet_handle() { TestUtils::cleanup_storage(); @@ -113,9 +124,11 @@ mod high_cases { let wallet_handle = WalletUtils::create_and_open_wallet("pool1", None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, "{}").unwrap(); + let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, "{}").unwrap(); + + let (new_verkey, _) = SignusUtils::replace_keys(wallet_handle, &my_did, "{}").unwrap(); - SignusUtils::replace_keys(wallet_handle, &my_did, "{}").unwrap(); + assert!(new_verkey != my_verkey); TestUtils::cleanup_storage(); } @@ -146,6 +159,22 @@ mod high_cases { TestUtils::cleanup_storage(); } + + #[test] + fn indy_replace_keys_works_for_seed() { + TestUtils::cleanup_storage(); + + let wallet_handle = WalletUtils::create_and_open_wallet("pool1", None).unwrap(); + + let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, "{}").unwrap(); + + let (new_verkey, _) = SignusUtils::replace_keys(wallet_handle, &my_did, r#"{"seed":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}"#).unwrap(); + assert_eq!(new_verkey, "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW"); + + assert!(my_verkey != new_verkey); + + TestUtils::cleanup_storage(); + } } mod store_their_did { @@ -201,6 +230,31 @@ mod high_cases { TestUtils::cleanup_storage(); } + + #[test] + fn indy_store_their_did_works_without_did() { + TestUtils::cleanup_storage(); + + let wallet_handle = WalletUtils::create_and_open_wallet("pool1", None).unwrap(); + + let identity_json = r#"{"verkey":"GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa"}"#; + let res = SignusUtils::store_their_did(wallet_handle, identity_json); + assert_eq!(res.unwrap_err(), ErrorCode::CommonInvalidStructure); + + TestUtils::cleanup_storage(); + } + + #[test] + fn indy_store_their_did_works_for_correct_crypto_type() { + TestUtils::cleanup_storage(); + + let wallet_handle = WalletUtils::create_and_open_wallet("pool1", None).unwrap(); + + let identity_json = r#"{"did":"8wZcEriaNLNKtteJvx7f8i", "verkey":"GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa", "crypto_type": "ed25519"}"#; + SignusUtils::store_their_did(wallet_handle, identity_json).unwrap(); + + TestUtils::cleanup_storage(); + } } mod sign { @@ -212,7 +266,7 @@ mod high_cases { let wallet_handle = WalletUtils::create_and_open_wallet("pool1", None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1"}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let message = r#"{ "reqId":1496822211362017764, @@ -240,7 +294,7 @@ mod high_cases { let message = r#"{"reqId":1495034346617224651}"#; - let res = SignusUtils::sign(wallet_handle, "some_did", message); + let res = SignusUtils::sign(wallet_handle, "did", message); assert_eq!(res.unwrap_err(), ErrorCode::WalletNotFoundError); TestUtils::cleanup_storage(); @@ -252,7 +306,7 @@ mod high_cases { let wallet_handle = WalletUtils::create_and_open_wallet("pool1", None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{}"#).unwrap(); let message = r#"{"reqId":1495034346617224651,}"#; @@ -275,7 +329,7 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (did, verkey, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1"}"#).unwrap(); + let (did, verkey, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let identity_json = format!(r#"{{"did":"{}", "verkey":"{}"}}"#, did, verkey); SignusUtils::store_their_did(wallet_handle, &identity_json).unwrap(); @@ -306,8 +360,8 @@ mod high_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); - let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); + let (my_did, my_verkey, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("00000000000000000000000000000My1")).unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), Some(&my_verkey), None, None).unwrap(); LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &trustee_did, &nym_request).unwrap(); @@ -334,8 +388,8 @@ mod high_cases { WalletUtils::create_wallet(pool_name, "wallet1", None, None).unwrap(); let wallet_handle = WalletUtils::open_wallet("wallet1", Some(r#"{"freshness_time":1}"#)).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); - let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); + let (my_did, my_verkey, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("00000000000000000000000000000My1")).unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), Some(&my_verkey), None, None).unwrap(); LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &trustee_did, &nym_request).unwrap(); @@ -393,6 +447,41 @@ mod high_cases { TestUtils::cleanup_storage(); } + + #[test] + fn indy_verify_works_for_other_signer() { + TestUtils::cleanup_storage(); + let pool_name = "indy_verify_works_for_other_signer"; + + let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); + let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); + + let (did, verkey, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1"}"#).unwrap(); + let (other_did, other_verkey, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Steward1"}"#).unwrap(); + + let identity_json = format!(r#"{{"did":"{}", "verkey":"{}"}}"#, did, verkey); + SignusUtils::store_their_did(wallet_handle, &identity_json).unwrap(); + + let identity_json = format!(r#"{{"did":"{}", "verkey":"{}"}}"#, other_did, other_verkey); + SignusUtils::store_their_did(wallet_handle, &identity_json).unwrap(); + + let message = r#"{ + "reqId":1496822211362017764, + "identifier":"GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL", + "operation":{ + "type":"1", + "dest":"VsKV7grR1BUE29mG2Fm2kX", + "verkey":"GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa" + } + }"#; + + let msg = SignusUtils::sign(wallet_handle, &did, message).unwrap(); + + let valid = SignusUtils::verify(wallet_handle, pool_handle, &other_did, &msg).unwrap(); + assert!(!valid); + + TestUtils::cleanup_storage(); + } } } @@ -465,6 +554,35 @@ mod medium_cases { TestUtils::cleanup_storage(); } + + #[test] + fn indy_replace_keys_works_for_correct_crypto_type() { + TestUtils::cleanup_storage(); + + let wallet_handle = WalletUtils::create_and_open_wallet("pool1", None).unwrap(); + + let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, "{}").unwrap(); + + let (new_verkey, _) = SignusUtils::replace_keys(wallet_handle, &my_did, r#"{"crypto_type":"ed25519"}"#).unwrap(); + + assert!(my_verkey != new_verkey); + + TestUtils::cleanup_storage(); + } + + #[test] + fn indy_replace_keys_works_for_invalid_crypto_type() { + TestUtils::cleanup_storage(); + + let wallet_handle = WalletUtils::create_and_open_wallet("pool1", None).unwrap(); + + let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, "{}").unwrap(); + + let res = SignusUtils::replace_keys(wallet_handle, &my_did, r#"{"crypto_type":"type"}"#); + assert_eq!(res.unwrap_err(), ErrorCode::SignusUnknownCryptoError); + + TestUtils::cleanup_storage(); + } } mod store_their_did { @@ -544,12 +662,13 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (did, verkey, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1"}"#).unwrap(); + let (did, verkey, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let identity_json = format!(r#"{{"did":"{}", "verkey":"{}"}}"#, did, verkey); SignusUtils::store_their_did(wallet_handle, &identity_json).unwrap(); - let message = r#"1496822211362017764"#; + let message = r#""reqId":1496822211362017764, + "signature":"tibTuE59pZn1sCeZpNL5rDzpkpqV3EkDmRpFTizys9Gr3ZieLdGEGyq4h8jsVWW9zSaXSRnfYcVb1yTjUJ7vJai""#; let res = SignusUtils::verify(wallet_handle, pool_handle, &did, message); assert_eq!(res.unwrap_err(), ErrorCode::CommonInvalidStructure); @@ -565,7 +684,7 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (did, verkey, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1"}"#).unwrap(); + let (did, verkey, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); let identity_json = format!(r#"{{"did":"{}", "verkey":"{}"}}"#, did, verkey); SignusUtils::store_their_did(wallet_handle, &identity_json).unwrap(); @@ -590,7 +709,7 @@ mod medium_cases { let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet("other_pool_name", None).unwrap(); - let (my_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (my_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("00000000000000000000000000000My1")).unwrap(); let message = r#"{"reqId":1496822211362017764, "signature":"tibTuE59pZn1sCeZpNL5rDzpkpqV3EkDmRpFTizys9Gr3ZieLdGEGyq4h8jsVWW9zSaXSRnfYcVb1yTjUJ7vJai"}"#; @@ -605,10 +724,10 @@ mod medium_cases { } #[test] - fn indy_verify_works_for_get_unknow_nym_from_ledger() { + fn indy_verify_works_for_get_ledger_not_found_nym() { TestUtils::cleanup_storage(); - let pool_name = "indy_verify_works_for_get_unknow_nym_from_ledger"; + let pool_name = "indy_verify_works_for_get_ledger_not_found_nym"; let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); @@ -628,16 +747,16 @@ mod medium_cases { } #[test] - fn indy_verify_works_for_unknown_nym() { + fn indy_verify_works_for_no_nym_in_wallet() { TestUtils::cleanup_storage(); - let pool_name = "indy_verify_works_for_unknown_did"; + let pool_name = "indy_verify_works_for_no_nym_in_wallet"; let pool_handle = PoolUtils::create_and_open_pool_ledger_config(pool_name).unwrap(); let wallet_handle = WalletUtils::create_and_open_wallet(pool_name, None).unwrap(); - let (trustee_did, _, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"000000000000000000000000Trustee1","cid":true}"#).unwrap(); - let (my_did, my_verkey, _) = SignusUtils::create_my_did(wallet_handle, r#"{"seed":"00000000000000000000000000000My1"}"#).unwrap(); + let (trustee_did, _, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("000000000000000000000000Trustee1")).unwrap(); + let (my_did, my_verkey, _) = SignusUtils::create_and_store_my_did(wallet_handle, Some("00000000000000000000000000000My1")).unwrap(); let nym_request = LedgerUtils::build_nym_request(&trustee_did.clone(), &my_did.clone(), Some(&my_verkey), None, None).unwrap(); LedgerUtils::sign_and_submit_request(pool_handle, wallet_handle, &trustee_did, &nym_request).unwrap(); diff --git a/tests/utils/anoncreds.rs b/tests/utils/anoncreds.rs index db4d3c05dc..4748227b1f 100644 --- a/tests/utils/anoncreds.rs +++ b/tests/utils/anoncreds.rs @@ -444,6 +444,7 @@ impl AnoncredsUtils { r#"{ "ref":1, "signature_type":"CL", + "origin":"CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW", "data":{ "primary":{ "n":"83469852984476956871633111285697420678256060723156580163068122759469567425381600849138438902552107548539766861666590365174848381535291010418041757276710240953030842046122202402016906205924972182252295487319094577329593677544393592632224714613427822130473474379696616183721440743475053734247824037725487533789856061706740833324717788602268746116297029721621398888459529131593826880823126900285858832457134377949183677639585442886904844793608783831753240185678448312284269486845497720949217396146132958861735347072722092449280372574205841746312833280031873247525372459800132930201998084029506922484661426185450002143461", diff --git a/tests/utils/callback.rs b/tests/utils/callback.rs index 865e588894..e7a91acbc8 100644 --- a/tests/utils/callback.rs +++ b/tests/utils/callback.rs @@ -229,26 +229,6 @@ impl CallbackUtils { (command_handle, Some(open_wallet_callback)) } - pub fn closure_to_wallet_set_seq_no_for_value_cb(closure: Box) -> (i32, - Option) { - lazy_static! { - static ref WALLET_SET_SEQ_NO_FOR_VALUE_CALLBACKS: Mutex>> = Default::default(); - } - - extern "C" fn closure_to_wallet_set_seq_no_for_value_callback(command_handle: i32, err: ErrorCode) { - let mut callbacks = WALLET_SET_SEQ_NO_FOR_VALUE_CALLBACKS.lock().unwrap(); - let mut cb = callbacks.remove(&command_handle).unwrap(); - cb(err) - } - - let mut callbacks = WALLET_SET_SEQ_NO_FOR_VALUE_CALLBACKS.lock().unwrap(); - let command_handle = (COMMAND_HANDLE_COUNTER.fetch_add(1, Ordering::SeqCst) + 1) as i32; - callbacks.insert(command_handle, closure); - - (command_handle, Some(closure_to_wallet_set_seq_no_for_value_callback)) - } - pub fn closure_to_issuer_create_and_store_revoc_reg_cb(closure: Box) -> (i32, Option) -> Result<(String, String, String), ErrorCode> { + pub fn create_and_store_my_did(wallet_handle: i32, seed: Option<&str>) -> Result<(String, String, String), ErrorCode> { let (create_and_store_my_did_sender, create_and_store_my_did_receiver) = channel(); let create_and_store_my_did_cb = Box::new(move |err, did, verkey, public_key| { create_and_store_my_did_sender.send((err, did, verkey, public_key)).unwrap(); diff --git a/tests/utils/types.rs b/tests/utils/types.rs index 3ef21caa80..646ac9f026 100644 --- a/tests/utils/types.rs +++ b/tests/utils/types.rs @@ -120,10 +120,10 @@ pub struct GetTxnResult { #[serde(rename = "reqId")] pub req_id: u64, #[serde(rename = "seqNo")] - pub seq_no: i32, + pub seq_no: Option, #[serde(rename = "type")] pub _type: String, - pub data: Option + pub data: String } #[derive(Debug, Serialize, Deserialize)] @@ -165,6 +165,31 @@ pub struct ProofClaimsJson { pub predicates: HashMap> } +#[derive(Debug, Deserialize, Serialize)] +pub struct ProofRequestJson { + pub nonce: String, + pub name: String, + pub version: String, + pub requested_attrs: HashMap, + pub requested_predicates: HashMap +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct Predicate { + pub attr_name: String, + pub p_type: String, + pub value: i32, + pub schema_seq_no: Option, + pub issuer_did: Option +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct AttributeInfo { + pub name: String, + pub schema_seq_no: Option, + pub issuer_did: Option +} + #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)] pub struct ClaimInfo { pub claim_uuid: String, @@ -191,9 +216,9 @@ pub struct ClaimRequest { pub struct ClaimJson { pub claim: HashMap>, pub revoc_reg_seq_no: Option, - pub schema_seq_no: i32, + pub schema_seq_no: Option, pub signature: ClaimSignature, - pub issuer_did: String + pub issuer_did: Option } #[derive(Debug, Deserialize, Serialize)] @@ -212,9 +237,93 @@ pub struct PrimaryClaim { #[derive(Debug, Serialize, Deserialize)] pub struct ProofJson { + pub proofs: HashMap, + pub aggregated_proof: AggregatedProof, pub requested_proof: RequestedProofJson } +#[derive(Debug, Serialize, Deserialize)] +pub struct Proof { + pub primary_proof: PrimaryProof, + pub non_revoc_proof: Option +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct NonRevocProof { + pub x_list: NonRevocProofXList, + pub c_list: NonRevocProofCList +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct NonRevocProofCList { + pub e: String, + pub d: String, + pub a: String, + pub g: String, + pub w: String, + pub s: String, + pub u: String +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct NonRevocProofXList { + pub rho: String, + pub r: String, + pub r_prime: String, + pub r_prime_prime: String, + pub r_prime_prime_prime: String, + pub o: String, + pub o_prime: String, + pub m: String, + pub m_prime: String, + pub t: String, + pub t_prime: String, + pub m2: String, + pub s: String, + pub c: String +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct PrimaryProof { + pub eq_proof: PrimaryEqualProof, + pub ge_proofs: Vec +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct PrimaryPredicateGEProof { + pub u: HashMap, + pub r: HashMap, + pub mj: String, + pub alpha: String, + pub t: HashMap, + pub predicate: Predicate +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct PrimaryEqualProof { + pub revealed_attrs: HashMap, + pub a_prime: String, + pub e: String, + pub v: String, + pub m: HashMap, + pub m1: String, + pub m2: String +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct ClaimProof { + pub proof: Proof, + pub revoc_reg_seq_no: Option, + pub schema_seq_no: i32, + pub issuer_did: String +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct AggregatedProof { + pub c_hash: String, + pub c_list: Vec> +} + #[derive(Debug, Serialize, Deserialize)] pub struct RequestedProofJson { pub revealed_attrs: HashMap, diff --git a/tests/utils/wallet.rs b/tests/utils/wallet.rs index 1ecd2e4202..bd8e3f210a 100644 --- a/tests/utils/wallet.rs +++ b/tests/utils/wallet.rs @@ -3,7 +3,6 @@ use indy::api::wallet::{ indy_register_wallet_type, indy_create_wallet, indy_open_wallet, - indy_wallet_set_seq_no_for_value, indy_delete_wallet, indy_close_wallet }; @@ -23,14 +22,14 @@ pub struct WalletUtils {} impl WalletUtils { - pub fn register_wallet_type(xtype: &str) -> Result<(), ErrorCode> { + pub fn register_wallet_type(xtype: &str, force_create: bool) -> Result<(), ErrorCode> { lazy_static! { static ref REGISERED_WALLETS: Mutex> = Default::default(); } let mut wallets = REGISERED_WALLETS.lock().unwrap(); - if wallets.contains(xtype) { + if wallets.contains(xtype) & !force_create { // as registering of plugged wallet with return Ok(()) } @@ -202,39 +201,6 @@ impl WalletUtils { Ok(wallet_handle) } - pub fn wallet_set_seq_no_for_value(wallet_handle: i32, value: &str, seq_no: i32) -> Result<(), ErrorCode> { - let (sender, receiver) = channel(); - - - let cb = Box::new(move |err| { - sender.send(err).unwrap(); - }); - - let (command_handle, cb) = CallbackUtils::closure_to_wallet_set_seq_no_for_value_cb(cb); - - let value = CString::new(value).unwrap(); - - let err = - indy_wallet_set_seq_no_for_value(command_handle, - wallet_handle, - value.as_ptr(), - seq_no, - cb); - - if err != ErrorCode::Success { - return Err(err); - } - - let err = receiver.recv_timeout(TimeoutUtils::short_timeout()).unwrap(); - - if err != ErrorCode::Success { - return Err(err); - } - - Ok(()) - } - - pub fn delete_wallet(wallet_name: &str) -> Result<(), ErrorCode> { let (sender, receiver) = channel(); diff --git a/tests/wallet.rs b/tests/wallet.rs index 4b0519f3a4..e36d4ee2c1 100644 --- a/tests/wallet.rs +++ b/tests/wallet.rs @@ -16,7 +16,6 @@ mod utils; use utils::inmem_wallet::InmemWallet; use utils::wallet::WalletUtils; -use utils::signus::SignusUtils; use utils::test::TestUtils; use indy::api::ErrorCode; @@ -32,7 +31,7 @@ mod high_cases { TestUtils::cleanup_storage(); InmemWallet::cleanup(); - WalletUtils::register_wallet_type("inmem").unwrap(); + WalletUtils::register_wallet_type("inmem", false).unwrap(); TestUtils::cleanup_storage(); InmemWallet::cleanup(); @@ -64,7 +63,7 @@ mod high_cases { let wallet_name = "indy_create_wallet_works"; let xtype = "inmem"; - WalletUtils::register_wallet_type("inmem").unwrap(); + WalletUtils::register_wallet_type("inmem", false).unwrap(); WalletUtils::create_wallet(pool_name, wallet_name, Some(xtype), None).unwrap(); TestUtils::cleanup_storage(); @@ -129,6 +128,38 @@ mod high_cases { TestUtils::cleanup_storage(); } + #[test] + fn indy_delete_wallet_works_for_closed() { + TestUtils::cleanup_storage(); + + let pool_name = "indy_delete_wallet_works_for_closed"; + let wallet_name = "indy_delete_wallet_works_for_closed"; + + WalletUtils::create_wallet(pool_name, wallet_name, None, None).unwrap(); + let wallet_handle = WalletUtils::open_wallet(wallet_name, None).unwrap(); + WalletUtils::close_wallet(wallet_handle).unwrap(); + WalletUtils::delete_wallet(wallet_name).unwrap(); + WalletUtils::create_wallet(pool_name, wallet_name, None, None).unwrap(); + + TestUtils::cleanup_storage(); + } + + #[test] + #[ignore]//TODO FUX BUG. We can delete only closed wallet + fn indy_delete_wallet_works_for_opened() { + TestUtils::cleanup_storage(); + + let pool_name = "indy_delete_wallet_works_for_opened"; + let wallet_name = "indy_delete_wallet_works_for_opened"; + + WalletUtils::create_wallet(pool_name, wallet_name, None, None).unwrap(); + WalletUtils::open_wallet(wallet_name, None).unwrap(); + let res = WalletUtils::delete_wallet(wallet_name); + assert_eq!(res.unwrap_err(), ErrorCode::CommonIOError); + + TestUtils::cleanup_storage(); + } + #[test] fn indy_delete_wallet_works_for_plugged() { TestUtils::cleanup_storage(); @@ -138,7 +169,7 @@ mod high_cases { let wallet_name = "indy_delete_wallet_works_for_plugged"; let xtype = "inmem"; - WalletUtils::register_wallet_type(xtype).unwrap(); + WalletUtils::register_wallet_type(xtype, false).unwrap(); WalletUtils::create_wallet(pool_name, wallet_name, Some(xtype), None).unwrap(); WalletUtils::delete_wallet(wallet_name).unwrap(); WalletUtils::create_wallet(pool_name, wallet_name, Some(xtype), None).unwrap(); @@ -173,7 +204,7 @@ mod high_cases { let wallet_name = "indy_open_wallet_works_for_plugged"; let xtype = "inmem"; - WalletUtils::register_wallet_type(xtype).unwrap(); + WalletUtils::register_wallet_type(xtype, false).unwrap(); WalletUtils::create_wallet(pool_name, wallet_name, Some(xtype), None).unwrap(); WalletUtils::open_wallet(wallet_name, None).unwrap(); @@ -224,7 +255,7 @@ mod high_cases { let wallet_name = "indy_close_wallet_works_for_plugged"; let xtype = "inmem"; - WalletUtils::register_wallet_type(xtype).unwrap(); + WalletUtils::register_wallet_type(xtype, false).unwrap(); WalletUtils::create_wallet(pool_name, wallet_name, Some(xtype), None).unwrap(); let wallet_handle = WalletUtils::open_wallet(wallet_name, None).unwrap(); @@ -235,45 +266,116 @@ mod high_cases { InmemWallet::cleanup(); } } +} + +mod medium_cases { + extern crate libc; + use super::*; + use std::ffi::CString; + use self::libc::c_char; - mod set_seqno_wallet { + mod register_wallet_type { use super::*; + use indy::api::wallet::indy_register_wallet_type; #[test] - fn indy_wallet_set_seqno_works() { + fn indy_register_wallet_type_does_not_work_twice_with_same_name() { TestUtils::cleanup_storage(); + InmemWallet::cleanup(); - let wallet_handle = WalletUtils::create_and_open_wallet("indy_wallet_set_seqno_works", None).unwrap(); - - let (did, _, _) = SignusUtils::create_my_did(wallet_handle, "{}").unwrap(); - - WalletUtils::wallet_set_seq_no_for_value(wallet_handle, &did, 1).unwrap(); + WalletUtils::register_wallet_type("inmem", false).unwrap(); + let res = WalletUtils::register_wallet_type("inmem", true); + assert_eq!(res.unwrap_err(), ErrorCode::WalletTypeAlreadyRegisteredError); TestUtils::cleanup_storage(); + InmemWallet::cleanup(); } #[test] - fn indy_wallet_set_seqno_works_for_plugged() { + fn indy_register_wallet_type_does_not_work_with_null_params() { TestUtils::cleanup_storage(); InmemWallet::cleanup(); - let xtype = "inmem"; - - WalletUtils::register_wallet_type(xtype).unwrap(); - let wallet_handle = WalletUtils::create_and_open_wallet("indy_wallet_set_seqno_works_for_plugged", Some(xtype)).unwrap(); - - let (did, _, _) = SignusUtils::create_my_did(wallet_handle, "{}").unwrap(); - - WalletUtils::wallet_set_seq_no_for_value(wallet_handle, &did, 1).unwrap(); + let xtype = CString::new("inmem").unwrap(); + let res = indy_register_wallet_type(1, xtype.as_ptr(), None, None, None, None, None, + None, None, None, None, None); + assert_eq!(res, ErrorCode::CommonInvalidParam3); + + extern "C" fn callback(_: *const c_char, _: *const c_char, + _: *const c_char) -> ErrorCode { + ErrorCode::Success + } + + let res = indy_register_wallet_type(1, xtype.as_ptr(), Some(callback), None, None, None, + None, None, None, None, None, None); + assert_eq!(res, ErrorCode::CommonInvalidParam4); + + extern "C" fn callback1(_: *const c_char, _: *const c_char, _: *const c_char, + _: *const c_char, _: *mut i32) -> ErrorCode { + ErrorCode::Success + } + + let res = indy_register_wallet_type(1, xtype.as_ptr(), Some(callback), Some(callback1), + None, None, None, None, None, None, None, None); + assert_eq!(res, ErrorCode::CommonInvalidParam5); + + extern "C" fn callback2(_: i32, _: *const c_char, _: *const c_char) -> ErrorCode { + ErrorCode::Success + } + + let res = indy_register_wallet_type(1, xtype.as_ptr(), Some(callback), Some(callback1), + Some(callback2), None, None, None, None, None, + None, None); + assert_eq!(res, ErrorCode::CommonInvalidParam6); + + extern "C" fn callback3(_: i32, _: *const c_char, _: *mut *const c_char) -> ErrorCode { + ErrorCode::Success + } + + let res = indy_register_wallet_type(1, xtype.as_ptr(), Some(callback), Some(callback1), + Some(callback2), Some(callback3), None, None, None, + None, None, None); + assert_eq!(res, ErrorCode::CommonInvalidParam7); + + let res = indy_register_wallet_type(1, xtype.as_ptr(), Some(callback), Some(callback1), + Some(callback2), Some(callback3), Some(callback3), + None, None, None, None, None); + assert_eq!(res, ErrorCode::CommonInvalidParam8); + + let res = indy_register_wallet_type(1, xtype.as_ptr(), Some(callback), Some(callback1), + Some(callback2), Some(callback3), Some(callback3), + Some(callback3), None, None, None, None); + assert_eq!(res, ErrorCode::CommonInvalidParam9); + + extern "C" fn callback4(_: i32) -> ErrorCode { + ErrorCode::Success + } + + let res = indy_register_wallet_type(1, xtype.as_ptr(), Some(callback), Some(callback1), + Some(callback2), Some(callback3), Some(callback3), + Some(callback3), Some(callback4), None, None, None); + assert_eq!(res, ErrorCode::CommonInvalidParam10); + + let res = indy_register_wallet_type(1, xtype.as_ptr(), Some(callback), Some(callback1), + Some(callback2), Some(callback3), Some(callback3), + Some(callback3), Some(callback4), Some(callback), + None, None); + assert_eq!(res, ErrorCode::CommonInvalidParam11); + + extern "C" fn callback5(_: i32, _: *const c_char) -> ErrorCode { + ErrorCode::Success + } + + let res = indy_register_wallet_type(1, xtype.as_ptr(), Some(callback), Some(callback1), + Some(callback2), Some(callback3), Some(callback3), + Some(callback3), Some(callback4), Some(callback), + Some(callback5), None); + assert_eq!(res, ErrorCode::CommonInvalidParam12); TestUtils::cleanup_storage(); InmemWallet::cleanup(); } } -} - -mod medium_cases { - use super::*; mod create_wallet { use super::*; @@ -310,7 +412,7 @@ mod medium_cases { use super::*; #[test] - fn indy_delete_wallet_works_for_invalid_wallet_name() { + fn indy_delete_wallet_works_for_not_created() { TestUtils::cleanup_storage(); let res = WalletUtils::delete_wallet("indy_delete_wallet_works_for_invalid_wallet_name"); @@ -349,7 +451,6 @@ mod medium_cases { } #[test] - #[ignore] //TODO Check is not implemented fn indy_open_wallet_works_for_twice() { TestUtils::cleanup_storage(); @@ -360,7 +461,7 @@ mod medium_cases { WalletUtils::open_wallet(wallet_name, None).unwrap(); let res = WalletUtils::open_wallet(wallet_name, None); - assert_eq!(res.unwrap_err(), ErrorCode::CommonIOError); + assert_eq!(res.unwrap_err(), ErrorCode::WalletAlreadyOpenedError); TestUtils::cleanup_storage(); } @@ -423,34 +524,4 @@ mod medium_cases { TestUtils::cleanup_storage(); } } - - mod set_seqno { - use super::*; - - #[test] - fn indy_wallet_set_seqno_works_for_not_exists_key() { - TestUtils::cleanup_storage(); - - let wallet_handle = WalletUtils::create_and_open_wallet("indy_wallet_set_seqno_works_for_not_exists_key", None).unwrap(); - - //TODO may be we must return WalletNotFound in case if key not exists in wallet - WalletUtils::wallet_set_seq_no_for_value(wallet_handle, "key", 1).unwrap(); - - TestUtils::cleanup_storage(); - } - - #[test] - fn indy_wallet_set_seqno_works_for_invalid_wallet() { - TestUtils::cleanup_storage(); - - let wallet_handle = WalletUtils::create_and_open_wallet("indy_wallet_set_seqno_works_for_invalid_wallet", None).unwrap(); - - - let invalid_wallet_handle = wallet_handle + 1; - let res = WalletUtils::wallet_set_seq_no_for_value(invalid_wallet_handle, "key", 1); - assert_eq!(res.unwrap_err(), ErrorCode::WalletInvalidHandle); - - TestUtils::cleanup_storage(); - } - } } diff --git a/wrappers/java/.gitignore b/wrappers/java/.gitignore new file mode 100644 index 0000000000..1c08a5aa39 --- /dev/null +++ b/wrappers/java/.gitignore @@ -0,0 +1,6 @@ +.classpath +.project +/.settings/ +/target/ +/bin/ + diff --git a/wrappers/java/Jenkinsfile b/wrappers/java/Jenkinsfile new file mode 100644 index 0000000000..5c6c73d84e --- /dev/null +++ b/wrappers/java/Jenkinsfile @@ -0,0 +1,91 @@ +#!groovy​ + +@Library('SovrinHelpers') _ + +name = 'indy-sdk' +def err +def publishBranch = (env.BRANCH_NAME == 'master' || env.BRANCH_NAME == 'devel') + +try { + +// ALL BRANCHES: master, devel, PRs + + // 1. TEST + stage('Test') { + parallel 'ubuntu-java-test': { + node('ubuntu') { + stage('Ubuntu Java Test') { + javaTestUbuntu() + } + } + } + } + +} catch (e) { + currentBuild.result = "FAILED" + node('ubuntu-master') { + sendNotification.fail([slack: publishBranch]) + } + err = e +} finally { + if (err) { + throw err + } + currentBuild.result = "SUCCESS" + if (publishBranch) { + node('ubuntu-master') { + sendNotification.success(name) + } + } +} + +def javaTestUbuntu() { + def poolInst + def network_name = "pool_network" + try { + echo 'Ubuntu Java Test: Checkout csm' + checkout scm + + echo "Ubuntu Java Test: Create docker network (${network_name}) for nodes pool and test image" + sh "docker network create --subnet=10.0.0.0/8 ${network_name}" + + echo 'Ubuntu Java Test: Build docker image for nodes pool' + def poolEnv = dockerHelpers.build('indy_pool', 'ci/indy-pool.dockerfile ci') + echo 'Ubuntu Java Test: Run nodes pool' + poolInst = poolEnv.run("--ip=\"10.0.0.2\" --network=${network_name}") + + echo 'Ubuntu Java Test: Build docker image' + def testEnv = dockerHelpers.build(name, 'ci/java.dockerfile ci') + + testEnv.inside("--ip=\"10.0.0.3\" --network=${network_name}") { + echo 'Ubuntu Java Test: Test' + + sh ''' + cd wrappers/java + mvn clean test + ''' + } + } + finally { + echo 'Ubuntu Java Test: Cleanup' + try { + sh "docker network inspect ${network_name}" + } catch (ignore) { + } + try { + if (poolInst) { + echo 'Ubuntu Java Test: stop pool' + poolInst.stop() + } + } catch (err) { + echo "Ubuntu Java Tests: error while stop pool ${err}" + } + try { + echo "Ubuntu Java Test: remove pool network ${network_name}" + sh "docker network rm ${network_name}" + } catch (err) { + echo "Ubuntu Java Test: error while delete ${network_name} - ${err}" + } + step([$class: 'WsCleanup']) + } +} \ No newline at end of file diff --git a/wrappers/java/pom.xml b/wrappers/java/pom.xml index b1ea3fa129..e9d3016c41 100644 --- a/wrappers/java/pom.xml +++ b/wrappers/java/pom.xml @@ -94,7 +94,23 @@ 3.5 compile - + + commons-io + commons-io + 2.5 + test + + + org.bitcoinj + bitcoinj-core + 0.14.4 + test + + + org.json + json + 20160810 + test + - diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ErrorCode.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ErrorCode.java index 226f428fd9..3a465da184 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ErrorCode.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ErrorCode.java @@ -5,106 +5,117 @@ public enum ErrorCode { - Success(0), + Success(0), - // Common errors + // Common errors - // Caller passed invalid value as param 1 (null, invalid json and etc..) - CommonInvalidParam1(100), + // Caller passed invalid value as param 1 (null, invalid json and etc..) + CommonInvalidParam1(100), - // Caller passed invalid value as param 2 (null, invalid json and etc..) - CommonInvalidParam2(101), + // Caller passed invalid value as param 2 (null, invalid json and etc..) + CommonInvalidParam2(101), - // Caller passed invalid value as param 3 (null, invalid json and etc..) - CommonInvalidParam3(102), + // Caller passed invalid value as param 3 (null, invalid json and etc..) + CommonInvalidParam3(102), - // Caller passed invalid value as param 4 (null, invalid json and etc..) - CommonInvalidParam4(103), + // Caller passed invalid value as param 4 (null, invalid json and etc..) + CommonInvalidParam4(103), - // Caller passed invalid value as param 5 (null, invalid json and etc..) - CommonInvalidParam5(104), + // Caller passed invalid value as param 5 (null, invalid json and etc..) + CommonInvalidParam5(104), - // Caller passed invalid value as param 6 (null, invalid json and etc..) - CommonInvalidParam6(105), + // Caller passed invalid value as param 6 (null, invalid json and etc..) + CommonInvalidParam6(105), - // Caller passed invalid value as param 7 (null, invalid json and etc..) - CommonInvalidParam7(106), + // Caller passed invalid value as param 7 (null, invalid json and etc..) + CommonInvalidParam7(106), - // Caller passed invalid value as param 8 (null, invalid json and etc..) - CommonInvalidParam8(107), + // Caller passed invalid value as param 8 (null, invalid json and etc..) + CommonInvalidParam8(107), - // Caller passed invalid value as param 9 (null, invalid json and etc..) - CommonInvalidParam9(108), + // Caller passed invalid value as param 9 (null, invalid json and etc..) + CommonInvalidParam9(108), - // Invalid library state was detected in runtime. It signals library bug - CommonInvalidState(109), + // Caller passed invalid value as param 10 (null, invalid json and etc..) + CommonInvalidParam10(109), - // Object (json, config, key, claim and etc...) passed by library caller has invalid structure - CommonInvalidStructure(110), + // Caller passed invalid value as param 11 (null, invalid json and etc..) + CommonInvalidParam11(110), - // IO Error - CommonIOError(111), + // Caller passed invalid value as param 12 (null, invalid json and etc..) + CommonInvalidParam12(111), - // Wallet errors - // Caller passed invalid wallet handle - WalletInvalidHandle(200), + // Invalid library state was detected in runtime. It signals library bug + CommonInvalidState(112), - // Unknown type of wallet was passed on create_wallet - WalletUnknownTypeError(201), + // Object (json, config, key, claim and etc...) passed by library caller has invalid structure + CommonInvalidStructure(113), - // Attempt to register already existing wallet type - WalletTypeAlreadyRegisteredError(202), + // IO Error + CommonIOError(114), - // Attempt to create wallet with name used for another exists wallet - WalletAlreadyExistsError(203), + // Wallet errors + // Caller passed invalid wallet handle + WalletInvalidHandle(200), - // Requested entity id isn't present in wallet - WalletNotFoundError(204), + // Unknown type of wallet was passed on create_wallet + WalletUnknownTypeError(201), - // Trying to use wallet with pool that has different name - WalletIncompatiblePoolError(205), + // Attempt to register already existing wallet type + WalletTypeAlreadyRegisteredError(202), - // Ledger errors - // Trying to open pool ledger that wasn't created before - PoolLedgerNotCreatedError(300), + // Attempt to create wallet with name used for another exists wallet + WalletAlreadyExistsError(203), - // Caller passed invalid pool ledger handle - PoolLedgerInvalidPoolHandle(301), + // Requested entity id isn't present in wallet + WalletNotFoundError(204), - // Pool ledger terminated - PoolLedgerTerminated(302), + // Trying to use wallet with pool that has different name + WalletIncompatiblePoolError(205), - // No concensus during ledger operation - LedgerNoConsensusError(303), + // Trying to open wallet that was opened already + WalletAlreadyOpenedError(206), - // Attempt to send unknown or incomplete transaction message - LedgerInvalidTransaction(304), + // Ledger errors + // Trying to open pool ledger that wasn't created before + PoolLedgerNotCreatedError(300), - // Attempt to send transaction without the necessary privileges - LedgerSecurityError(305), + // Caller passed invalid pool ledger handle + PoolLedgerInvalidPoolHandle(301), - // Crypto errors - // Revocation registry is full and creation of new registry is necessary - AnoncredsRevocationRegistryFullError(400), + // Pool ledger terminated + PoolLedgerTerminated(302), - AnoncredsInvalidUserRevocIndex(401), + // No concensus during ledger operation + LedgerNoConsensusError(303), - AnoncredsAccumulatorIsFull(402), + // Attempt to send unknown or incomplete transaction message + LedgerInvalidTransaction(304), - AnoncredsNotIssuedError(403), + // Attempt to send transaction without the necessary privileges + LedgerSecurityError(305), - // Attempt to generate master secret with dupplicated name - AnoncredsMasterSecretDuplicateNameError(404), + // Crypto errors + // Revocation registry is full and creation of new registry is necessary + AnoncredsRevocationRegistryFullError(400), - AnoncredsProofRejected(405), + AnoncredsInvalidUserRevocIndex(401), - // Signus errors - // Unknown format of DID entity keys - SignusUnknownCryptoError(500); + AnoncredsAccumulatorIsFull(402), - private int value; - private static Map map = new HashMap<> (); + AnoncredsNotIssuedError(403), + + // Attempt to generate master secret with dupplicated name + AnoncredsMasterSecretDuplicateNameError(404), + + AnoncredsProofRejected(405), + // Signus errors + // Unknown format of DID entity keys + SignusUnknownCryptoError(500); + + private int value; + private static Map map = new HashMap(); private ErrorCode(int value) { this.value = value; diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/IndyException.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/IndyException.java index 5fc3d6916a..54a22122b3 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/IndyException.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/IndyException.java @@ -4,13 +4,19 @@ public class IndyException extends Exception { private static final long serialVersionUID = 2650355290834266477L; + private ErrorCode errorCode; + public IndyException(String message) { super(message); } - public static IndyException fromErrorCode(ErrorCode errorCode, int err) { + public IndyException(ErrorCode errorCode) { + this(String.format("%s: %d", errorCode.name(), errorCode.value())); + this.errorCode = errorCode; + } - return new IndyException("" + (errorCode == null ? null : errorCode.name()) + ": " + (errorCode == null ? null : errorCode.value()) + " (" + Integer.toString(err) + ")"); + public ErrorCode getErrorCode() { + return errorCode; } } diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/IndyJava.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/IndyJava.java index 395c6e6b24..bd5a7a601b 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/IndyJava.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/IndyJava.java @@ -4,6 +4,8 @@ import java.util.Iterator; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -22,24 +24,63 @@ public class IndyJava { public static class API { - protected static final int FIXED_COMMAND_HANDLE = 0; + /* + * FUTURES + */ - protected static boolean checkCallback(CompletableFuture future, int xcommand_handle, int err) { + private static AtomicInteger atomicInteger = new AtomicInteger(); + private static Map> futures = new ConcurrentHashMap>(); - assert(xcommand_handle == FIXED_COMMAND_HANDLE); + protected static int newCommandHandle() { + + return Integer.valueOf(atomicInteger.incrementAndGet()); + } + + protected static int addFuture(CompletableFuture future) { + + int commandHandle = newCommandHandle(); + assert(! futures.containsKey(Integer.valueOf(commandHandle))); + futures.put(Integer.valueOf(commandHandle), future); + + return commandHandle; + } + + protected static CompletableFuture removeFuture(int xcommand_handle) { + + CompletableFuture future = futures.remove(Integer.valueOf(xcommand_handle)); + assert(future != null); + + return future; + } + + /* + * ERROR CHECKING + */ + + protected static boolean checkCallback(CompletableFuture future, int err) { ErrorCode errorCode = ErrorCode.valueOf(err); - if (! ErrorCode.Success.equals(errorCode)) { future.completeExceptionally(IndyException.fromErrorCode(errorCode, err)); return false; } + if (! ErrorCode.Success.equals(errorCode)) { future.completeExceptionally(new IndyException(errorCode)); return false; } return true; } - protected static void checkResult(int result) throws IndyException { + protected static void checkCallback(int err) throws IndyException { + + ErrorCode errorCode = ErrorCode.valueOf(err); + if (! ErrorCode.Success.equals(errorCode)) throw new IndyException(errorCode); + } + + protected static void checkResult(int err) throws IndyException { - ErrorCode errorCode = ErrorCode.valueOf(result); - if (! ErrorCode.Success.equals(errorCode)) throw IndyException.fromErrorCode(errorCode, result); + ErrorCode errorCode = ErrorCode.valueOf(err); + if (! ErrorCode.Success.equals(errorCode)) throw new IndyException(errorCode); } + /* + * OBJECT METHODS + */ + @Override public int hashCode() { @@ -60,12 +101,16 @@ public String toString() { } /* - * JSON parameter + * JSON PARAMETER */ public abstract static class JsonParameter { - protected Map map = new HashMap (); + protected Map map = new HashMap(); + + /* + * JSON CREATION + */ public final String toJson() { @@ -96,6 +141,10 @@ private static String escapeJson(String string) { return string.replace("\\", "\\\\").replace("\"", "\\\""); } + /* + * OBJECT METHODS + */ + @Override public int hashCode() { @@ -139,4 +188,4 @@ public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } } -} \ No newline at end of file +} diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/LibIndy.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/LibIndy.java index ab5b5497df..f632b3839d 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/LibIndy.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/LibIndy.java @@ -26,11 +26,11 @@ public interface API extends Library { // wallet.rs + public int indy_register_wallet_type(int command_handle, String xtype, Callback create, Callback open, Callback set, Callback get, Callback get_not_expired, Callback list, Callback close, Callback delete, Callback free, Callback cb); public int indy_create_wallet(int command_handle, String pool_name, String name, String xtype, String config, String credentials, Callback cb); public int indy_open_wallet(int command_handle, String name, String runtime_config, String credentials, Callback cb); public int indy_close_wallet(int command_handle, int handle, Callback cb); public int indy_delete_wallet(int command_handle, String name, String credentials, Callback cb); - public int indy_wallet_set_seq_no_for_value(int command_handle, int wallet_handle, String wallet_key, Callback cb); // ledger.rs @@ -42,10 +42,11 @@ public interface API extends Library { public int indy_build_get_attrib_request(int command_handle, String submitter_did, String target_did, String data, Callback cb); public int indy_build_get_nym_request(int command_handle, String submitter_did, String target_did, Callback cb); public int indy_build_schema_request(int command_handle, String submitter_did, String data, Callback cb); - public int indy_build_get_schema_request(int command_handle, String submitter_did, String data, Callback cb); - public int indy_build_claim_def_txn(int command_handle, String submitter_did, String xref, String data, Callback cb); - public int indy_build_get_claim_def_txn(int command_handle, String submitter_did, String xref, Callback cb); + public int indy_build_get_schema_request(int command_handle, String submitter_did, String dest, String data, Callback cb); + public int indy_build_claim_def_txn(int command_handle, String submitter_did, int xref, String signature_type, String data, Callback cb); + public int indy_build_get_claim_def_txn(int command_handle, String submitter_did, int xref, String signature_type, String origin, Callback cb); public int indy_build_node_request(int command_handle, String submitter_did, String target_did, String data, Callback cb); + public int indy_build_get_txn_request(int command_handle, String submitter_did, int data, Callback cb); // signus.rs @@ -54,15 +55,15 @@ public interface API extends Library { public int indy_store_their_did(int command_handle, int wallet_handle, String identity_json, Callback cb); public int indy_sign(int command_handle, int wallet_handle, String did, String msg, Callback cb); public int indy_verify_signature(int command_handle, int wallet_handle, int pool_handle, String did, String signed_msg, Callback cb); - public int indy_encrypt(int command_handle, int wallet_handle, String did, String msg, Callback cb); - public int indy_decrypt(int command_handle, int wallet_handle, String did, String encrypted_msg, Callback cb); + public int indy_encrypt(int command_handle, int wallet_handle, int pool_handle, String myDid, String did, String msg, Callback cb); + public int indy_decrypt(int command_handle, int wallet_handle, String myDid, String did, String encrypted_msg, String nonce, Callback cb); // anoncreds.rs - public int indy_issuer_create_and_store_claim_def(int command_handle, int wallet_handle, String schema_json, String signature_type, boolean create_non_revoc, Callback cb); - public int indy_issuer_create_and_store_revoc_reg(int command_handle, int wallet_handle, int claim_def_seq_no, int max_claim_num, Callback cb); + public int indy_issuer_create_and_store_claim_def(int command_handle, int wallet_handle, String issuer_did, String schema_json, String signature_type, boolean create_non_revoc, Callback cb); + public int indy_issuer_create_and_store_revoc_reg(int command_handle, int wallet_handle, String issuer_did, int schema_seq_no, int max_claim_num, Callback cb); public int indy_issuer_create_claim(int command_handle, int wallet_handle, String claim_req_json, String claim_json, int revoc_reg_seq_no, int user_revoc_index, Callback cb); - public int indy_issuer_revoke_claim(int command_handle, int wallet_handle, int claim_def_seq_no, int revoc_reg_seq_no, int user_revoc_index, Callback cb); + public int indy_issuer_revoke_claim(int command_handle, int wallet_handle, int revoc_reg_seq_no, int user_revoc_index, Callback cb); public int indy_prover_store_claim_offer(int command_handle, int wallet_handle, String claim_offer_json, Callback cb); public int indy_prover_get_claim_offers(int command_handle, int wallet_handle, String filter_json, Callback cb); public int indy_prover_create_master_secret(int command_handle, int wallet_handle, String master_secret_name, Callback cb); @@ -71,7 +72,17 @@ public interface API extends Library { public int indy_prover_get_claims(int command_handle, int wallet_handle, String filter_json, Callback cb); public int indy_prover_get_claims_for_proof_req(int command_handle, int wallet_handle, String proof_request_json, Callback cb); public int indy_prover_create_proof(int command_handle, int wallet_handle, String proof_req_json, String requested_claims_json, String schemas_json, String master_secret_name, String claim_defs_json, String revoc_regs_json, Callback cb); - public int indy_verifier_verify_proof(int command_handle, int wallet_handle, String proof_request_json, String proof_json, String schemas_json, String claim_defs_jsons, String revoc_regs_json, Callback cb); + public int indy_verifier_verify_proof(int command_handle, String proof_request_json, String proof_json, String schemas_json, String claim_defs_jsons, String revoc_regs_json, Callback cb); + + // agent.rs + + public int indy_agent_connect(int command_handle, int pool_handle, int wallet_handle, String sender_did, String receiver_did, Callback connection_cb, Callback message_cb); + public int indy_agent_listen(int command_handle, String endpoint, Callback listener_cb, Callback connection_cb, Callback message_cb); + public int indy_agent_add_identity(int command_handle, int listener_handle, int pool_handle, int wallet_handle, String did, Callback add_identity_cb); + public int indy_agent_remove_identity(int command_handle, int listener_handle, int wallet_handle, String did, Callback rm_identity_cb); + public int indy_agent_send(int command_handle, int connection_handle, String message, Callback cb); + public int indy_agent_close_connection(int command_handle, int connection_handle, Callback cb); + public int indy_agent_close_listener(int command_handle, int listener_handle, Callback cb); } /* diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/agent/Agent.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/agent/Agent.java new file mode 100644 index 0000000000..7a89710a54 --- /dev/null +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/agent/Agent.java @@ -0,0 +1,434 @@ +package org.hyperledger.indy.sdk.agent; + +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +import org.hyperledger.indy.sdk.IndyException; +import org.hyperledger.indy.sdk.IndyJava; +import org.hyperledger.indy.sdk.LibIndy; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.wallet.Wallet; + +import com.sun.jna.Callback; + +/** + * agent.rs API + */ +public class Agent extends IndyJava.API { + + private static Map connections = new ConcurrentHashMap(); + private static Map listeners = new ConcurrentHashMap(); + + private Agent() { + + } + + /* + * OBSERVERS + */ + + private static Map messageObserver = new ConcurrentHashMap(); + private static Map connectionObservers = new ConcurrentHashMap(); + + private static void addMessageObserver(int commandHandle, AgentObservers.MessageObserver messageObserver) { + + assert(! Agent.messageObserver.containsKey(commandHandle)); + Agent.messageObserver.put(commandHandle, messageObserver); + + } + + private static AgentObservers.MessageObserver removeMessageObserver(int xcommand_handle) { + + AgentObservers.MessageObserver future = messageObserver.remove(xcommand_handle); + assert(future != null); + + return future; + } + + private static void addConnectionObserver(int commandHandle, AgentObservers.ConnectionObserver connectionObserver) { + + assert(! connectionObservers.containsKey(commandHandle)); + connectionObservers.put(commandHandle, connectionObserver); + + } + + private static AgentObservers.ConnectionObserver removeConnectionObserver(int xcommand_handle) { + + AgentObservers.ConnectionObserver future = connectionObservers.remove(xcommand_handle); + assert(future != null); + + return future; + } + + /* + * STATIC CALLBACKS + */ + + private static Callback agentConnectConnectionCb = new Callback() { + + @SuppressWarnings("unused") + public void callback(int xcommand_handle, int err, int connection_handle) throws IndyException { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + assert(! connections.containsKey(connection_handle)); + Agent.Connection connection = new Agent.Connection(connection_handle); + connections.put(connection_handle, connection); + + connection.messageObserver = removeMessageObserver(xcommand_handle); + + future.complete(connection); + } + }; + + private static Callback agentConnectMessageCb = new Callback() { + + @SuppressWarnings("unused") + public void callback(int xconnection_handle, int err, String message) throws IndyException { + + checkCallback(err); + + Agent.Connection connection = connections.get(xconnection_handle); + if (connection == null) return; + + AgentObservers.MessageObserver messageObserver = connection.messageObserver; + messageObserver.onMessage(connection, message); + } + }; + + private static Callback agentListenListenerCb = new Callback() { + + @SuppressWarnings("unused") + public void callback(int xcommand_handle, int err, int listener_handle) throws IndyException { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + assert(! listeners.containsKey(listener_handle)); + Agent.Listener listener = new Agent.Listener(listener_handle); + listeners.put(listener_handle, listener); + + listener.connectionObserver = removeConnectionObserver(xcommand_handle); + + future.complete(listener); + } + }; + + private static Callback agentListenConnectionCb = new Callback() { + + @SuppressWarnings("unused") + public void callback(int xlistener_handle, int err, int connection_handle, String sender_did, String receiver_did) throws IndyException { + + checkCallback(err); + + Agent.Listener listener = listeners.get(xlistener_handle); + if (listener == null) return; + + assert(! connections.containsKey(connection_handle)); + Agent.Connection connection = new Agent.Connection(connection_handle); + connections.put(connection_handle, connection); + + AgentObservers.ConnectionObserver connectionObserver = listener.connectionObserver; + connection.messageObserver = connectionObserver.onConnection(listener, connection, sender_did, receiver_did); + } + }; + + private static Callback agentListenMessageCb = new Callback() { + + @SuppressWarnings("unused") + public void callback(int xconnection_handle, int err, String message) throws IndyException { + + checkCallback(err); + + Agent.Connection connection = connections.get(xconnection_handle); + if (connection == null) return; + + AgentObservers.MessageObserver messageObserver = connection.messageObserver; + messageObserver.onMessage(connection, message); + } + }; + + private static Callback agentAddIdentityCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, int listener_handle) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + future.complete(null); + } + }; + + private static Callback agentRemoveIdentityCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, int listener_handle) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + future.complete(null); + } + }; + + private static Callback agentSendCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + future.complete(null); + } + }; + + private static Callback agentCloseConnectionCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + future.complete(null); + } + }; + + private static Callback agentCloseListenerCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + future.complete(null); + } + }; + + /* + * STATIC METHODS + */ + + public static CompletableFuture agentConnect( + Pool pool, + Wallet wallet, + String senderDid, + String receiverDid, + AgentObservers.MessageObserver messageObserver) throws IndyException { + + CompletableFuture future = new CompletableFuture<>(); + int commandHandle = addFuture(future); + addMessageObserver(commandHandle, messageObserver); + + int poolHandle = pool.getPoolHandle(); + int walletHandle = wallet.getWalletHandle(); + + int result = LibIndy.api.indy_agent_connect( + commandHandle, + poolHandle, + walletHandle, + senderDid, + receiverDid, + agentConnectConnectionCb, + agentConnectMessageCb); + + checkResult(result); + + return future; + } + + public static CompletableFuture agentListen( + String endpoint, + AgentObservers.ConnectionObserver connectionObserver) throws IndyException { + + CompletableFuture future = new CompletableFuture<>(); + int commandHandle = addFuture(future); + addConnectionObserver(commandHandle, connectionObserver); + + int result = LibIndy.api.indy_agent_listen( + commandHandle, + endpoint, + agentListenListenerCb, + agentListenConnectionCb, + agentListenMessageCb); + + checkResult(result); + + return future; + } + + public static CompletableFuture agentAddIdentity( + Agent.Listener listener, + Pool pool, + Wallet wallet, + String did) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int listenerHandle = listener.getListenerHandle(); + int poolHandle = pool.getPoolHandle(); + int walletHandle = wallet.getWalletHandle(); + + int result = LibIndy.api.indy_agent_add_identity( + commandHandle, + listenerHandle, + poolHandle, + walletHandle, + did, + agentAddIdentityCb); + + checkResult(result); + + return future; + } + + public static CompletableFuture agentRemoveIdentity( + Agent.Listener listener, + Wallet wallet, + String did) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int listenerHandle = listener.getListenerHandle(); + int walletHandle = wallet.getWalletHandle(); + + int result = LibIndy.api.indy_agent_remove_identity( + commandHandle, + listenerHandle, + walletHandle, + did, + agentRemoveIdentityCb); + + checkResult(result); + + return future; + } + + public static CompletableFuture agentSend( + Agent.Connection connection, + String message) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int connectionHandle = connection.getConnectionHandle(); + + int result = LibIndy.api.indy_agent_send( + commandHandle, + connectionHandle, + message, + agentSendCb); + + checkResult(result); + + return future; + } + + public static CompletableFuture agentCloseConnection( + Agent.Connection connection) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int connectionHandle = connection.getConnectionHandle(); + + connections.remove(connectionHandle); + + int result = LibIndy.api.indy_agent_close_connection( + commandHandle, + connectionHandle, + agentCloseConnectionCb); + + checkResult(result); + + return future; + } + + public static CompletableFuture agentCloseListener( + Agent.Listener listener) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int listenerHandle = listener.getListenerHandle(); + + listeners.remove(listenerHandle); + + int result = LibIndy.api.indy_agent_close_listener( + commandHandle, + listenerHandle, + agentCloseListenerCb); + + checkResult(result); + + return future; + } + + /* + * NESTED CLASSES WITH INSTANCE METHODS + */ + + public static class Listener { + + private final int listenerHandle; + private AgentObservers.ConnectionObserver connectionObserver; + + private Listener(int listenerHandle) { + + this.listenerHandle = listenerHandle; + } + + public int getListenerHandle() { + + return this.listenerHandle; + } + + public CompletableFuture agentAddIdentity(Pool pool, Wallet wallet, String did) throws IndyException { + + return Agent.agentAddIdentity(this, pool, wallet, did); + } + + public CompletableFuture agentRemoveIdentity(Wallet wallet, String did) throws IndyException { + + return Agent.agentRemoveIdentity(this, wallet, did); + } + + public CompletableFuture agentCloseListener() throws IndyException { + + return Agent.agentCloseListener(this); + } + } + + public static class Connection { + + private final int connectionHandle; + private AgentObservers.MessageObserver messageObserver; + + private Connection(int connectionHandle) { + + this.connectionHandle = connectionHandle; + } + + public int getConnectionHandle() { + + return this.connectionHandle; + } + + public CompletableFuture agentSend(String message) throws IndyException { + + return Agent.agentSend(this, message); + } + + public CompletableFuture agentCloseConnection() throws IndyException { + + return Agent.agentCloseConnection(this); + } + } +} diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/agent/AgentJSONParameters.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/agent/AgentJSONParameters.java new file mode 100644 index 0000000000..a165b15296 --- /dev/null +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/agent/AgentJSONParameters.java @@ -0,0 +1,11 @@ +package org.hyperledger.indy.sdk.agent; + +/** + * agent.rs JSON parameters + */ +public class AgentJSONParameters { + + private AgentJSONParameters() { + + } +} diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/agent/AgentObservers.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/agent/AgentObservers.java new file mode 100644 index 0000000000..c5f148aff2 --- /dev/null +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/agent/AgentObservers.java @@ -0,0 +1,21 @@ +package org.hyperledger.indy.sdk.agent; + +/** + * agent.rs observers + */ +public final class AgentObservers { + + private AgentObservers() { + + } + + public interface ConnectionObserver { + + public MessageObserver onConnection(Agent.Listener listener, Agent.Connection connection, String senderDid, String receiverDid); + } + + public interface MessageObserver { + + public void onMessage(Agent.Connection connection, String message); + } +} diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/agent/AgentResults.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/agent/AgentResults.java new file mode 100644 index 0000000000..5600668712 --- /dev/null +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/agent/AgentResults.java @@ -0,0 +1,11 @@ +package org.hyperledger.indy.sdk.agent; + +/** + * agent.rs results + */ +public final class AgentResults { + + private AgentResults() { + + } +} diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/anoncreds/Anoncreds.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/anoncreds/Anoncreds.java index 86cd88db8d..85bd4e44f1 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/anoncreds/Anoncreds.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/anoncreds/Anoncreds.java @@ -1,17 +1,12 @@ package org.hyperledger.indy.sdk.anoncreds; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; import org.hyperledger.indy.sdk.IndyException; -import org.hyperledger.indy.sdk.LibIndy; import org.hyperledger.indy.sdk.IndyJava; -import org.hyperledger.indy.sdk.anoncreds.AnoncredsResults.IssuerCreateAndStoreClaimDefResult; +import org.hyperledger.indy.sdk.LibIndy; import org.hyperledger.indy.sdk.anoncreds.AnoncredsResults.IssuerCreateAndStoreRevocRegResult; import org.hyperledger.indy.sdk.anoncreds.AnoncredsResults.IssuerCreateClaimResult; -import org.hyperledger.indy.sdk.anoncreds.AnoncredsResults.IssuerRevokeClaimResult; -import org.hyperledger.indy.sdk.anoncreds.AnoncredsResults.ProverGetClaimOffersResult; -import org.hyperledger.indy.sdk.anoncreds.AnoncredsResults.ProverStoreClaimOfferResult; import org.hyperledger.indy.sdk.wallet.Wallet; import com.sun.jna.Callback; @@ -25,206 +20,477 @@ private Anoncreds() { } + /* + * STATIC CALLBACKS + */ + + private static Callback issuerCreateAndStoreClaimDefCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String claim_def_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = claim_def_json, claim_def_uuid; + future.complete(result); + } + }; + + private static Callback issuerCreateAndStoreRevocRegCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String revoc_reg_json, String revoc_reg_uuid) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + IssuerCreateAndStoreRevocRegResult result = new IssuerCreateAndStoreRevocRegResult(revoc_reg_json, revoc_reg_uuid); + future.complete(result); + } + }; + + private static Callback issuerCreateClaimCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String revoc_reg_update_json, String xclaim_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + IssuerCreateClaimResult result = new IssuerCreateClaimResult(revoc_reg_update_json, xclaim_json); + future.complete(result); + } + }; + + private static Callback issuerRevokeClaimCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String revoc_reg_update_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = revoc_reg_update_json; + future.complete(result); + } + }; + + private static Callback proverStoreClaimOfferCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Void result = null; + future.complete(result); + } + }; + + private static Callback proverGetClaimOffersCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String claim_offers_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = claim_offers_json; + future.complete(result); + } + }; + + private static Callback proverCreateMasterSecretCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Void result = null; + future.complete(result); + } + }; + + private static Callback proverCreateClaimReqCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String claim_req_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = claim_req_json; + future.complete(result); + } + }; + + private static Callback proverStoreClaimCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Void result = null; + future.complete(result); + } + }; + + private static Callback proverGetClaimsCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String claimsJson) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = claimsJson; + future.complete(result); + } + }; + + private static Callback proverGetClaimsForProofReqCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String claimsJson) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = claimsJson; + future.complete(result); + } + }; + + private static Callback proverCreateProofCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String proofJson) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = proofJson; + future.complete(result); + } + }; + + private static Callback verifierVerifyProofCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, Boolean valid) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Boolean result = valid; + future.complete(result); + } + }; + + + /* * STATIC METHODS */ - public static Future issuerCreateAndStoreClaimDef( + public static CompletableFuture issuerCreateAndStoreClaimDef( Wallet wallet, + String issuerDid, String schemaJson, String signatureType, boolean createNonRevoc) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String claim_def_json, String claim_def_uuid) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - IssuerCreateAndStoreClaimDefResult result = new IssuerCreateAndStoreClaimDefResult(claim_def_json, claim_def_uuid); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); int result = LibIndy.api.indy_issuer_create_and_store_claim_def( - FIXED_COMMAND_HANDLE, + commandHandle, walletHandle, + issuerDid, schemaJson, signatureType, createNonRevoc, - callback); + issuerCreateAndStoreClaimDefCb); checkResult(result); return future; } - public static Future issuerCreateAndStoreRevocReg( + public static CompletableFuture issuerCreateAndStoreRevocReg( Wallet wallet, - int claimDefSeqNo, + String issuerDid, + int schemaSeqNo, int maxClaimNum) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String revoc_reg_json, String revoc_reg_uuid) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - IssuerCreateAndStoreRevocRegResult result = new IssuerCreateAndStoreRevocRegResult(revoc_reg_json, revoc_reg_uuid); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); int result = LibIndy.api.indy_issuer_create_and_store_revoc_reg( - FIXED_COMMAND_HANDLE, + commandHandle, walletHandle, - claimDefSeqNo, + issuerDid, + schemaSeqNo, maxClaimNum, - callback); + issuerCreateAndStoreRevocRegCb); checkResult(result); return future; } - public static Future issuerCreateClaim( + public static CompletableFuture issuerCreateClaim( Wallet wallet, String claimReqJson, String claimJson, int revocRegSeqNo, int userRevocIndex) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String revoc_reg_update_json, String xclaim_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - IssuerCreateClaimResult result = new IssuerCreateClaimResult(revoc_reg_update_json, xclaim_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); int result = LibIndy.api.indy_issuer_create_claim( - FIXED_COMMAND_HANDLE, + commandHandle, walletHandle, claimReqJson, claimJson, revocRegSeqNo, userRevocIndex, - callback); + issuerCreateClaimCb); checkResult(result); return future; } - public static Future issuerRevokeClaim( + public static CompletableFuture issuerRevokeClaim( Wallet wallet, - int claimDefSeqNo, int revocRegSeqNo, int userRevocIndex) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String revoc_reg_update_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - IssuerRevokeClaimResult result = new IssuerRevokeClaimResult(revoc_reg_update_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); int result = LibIndy.api.indy_issuer_revoke_claim( - FIXED_COMMAND_HANDLE, + commandHandle, walletHandle, - claimDefSeqNo, revocRegSeqNo, userRevocIndex, - callback); + issuerRevokeClaimCb); checkResult(result); return future; } - public static Future proverStoreClaimOffer( + public static CompletableFuture proverStoreClaimOffer( Wallet wallet, String claimOfferJson) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); - Callback callback = new Callback() { + int walletHandle = wallet.getWalletHandle(); - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err) { + int result = LibIndy.api.indy_prover_store_claim_offer( + commandHandle, + walletHandle, + claimOfferJson, + proverStoreClaimOfferCb); + + checkResult(result); - if (! checkCallback(future, xcommand_handle, err)) return; + return future; + } + + public static CompletableFuture proverGetClaimOffers( + Wallet wallet, + String filterJson) throws IndyException { - ProverStoreClaimOfferResult result = new ProverStoreClaimOfferResult(); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); - int result = LibIndy.api.indy_prover_store_claim_offer( - FIXED_COMMAND_HANDLE, + int result = LibIndy.api.indy_prover_get_claim_offers( + commandHandle, walletHandle, + filterJson, + proverGetClaimOffersCb); + + checkResult(result); + + return future; + } + + public static CompletableFuture proverCreateMasterSecret( + Wallet wallet, + String masterSecretName) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int walletHandle = wallet.getWalletHandle(); + + int result = LibIndy.api.indy_prover_create_master_secret( + commandHandle, + walletHandle, + masterSecretName, + proverCreateMasterSecretCb); + + checkResult(result); + + return future; + } + + public static CompletableFuture proverCreateClaimReq( + Wallet wallet, + String proverDid, + String claimOfferJson, + String claimDefJson, + String masterSecretName) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int walletHandle = wallet.getWalletHandle(); + + int result = LibIndy.api.indy_prover_create_and_store_claim_req( + commandHandle, + walletHandle, + proverDid, claimOfferJson, - callback); + claimDefJson, + masterSecretName, + proverCreateClaimReqCb); checkResult(result); return future; } - public static Future proverGetClaimOffers( + public static CompletableFuture proverStoreClaim( Wallet wallet, - String filterJson) throws IndyException { + String claim) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); - final CompletableFuture future = new CompletableFuture<> (); + int walletHandle = wallet.getWalletHandle(); + + int result = LibIndy.api.indy_prover_store_claim( + commandHandle, + walletHandle, + claim, + proverStoreClaimCb); - Callback callback = new Callback() { + checkResult(result); - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String claim_offers_json) { + return future; + } - if (! checkCallback(future, xcommand_handle, err)) return; + public static CompletableFuture proverGetClaims( + Wallet wallet, + String filter) throws IndyException { - ProverGetClaimOffersResult result = new ProverGetClaimOffersResult(claim_offers_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); - int result = LibIndy.api.indy_prover_get_claim_offers( - FIXED_COMMAND_HANDLE, - walletHandle, - filterJson, - callback); + int result = LibIndy.api.indy_prover_get_claims( + commandHandle, + walletHandle, + filter, + proverGetClaimsCb); + + checkResult(result); + + return future; + } + + public static CompletableFuture proverGetClaimsForProofReq( + Wallet wallet, + String proofRequest) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int walletHandle = wallet.getWalletHandle(); + + int result = LibIndy.api.indy_prover_get_claims_for_proof_req( + commandHandle, + walletHandle, + proofRequest, + proverGetClaimsForProofReqCb); + + checkResult(result); + + return future; + } + + public static CompletableFuture proverCreateProof( + Wallet wallet, + String proofRequest, + String requestedClaims, + String schemas, + String masterSecret, + String claimDefs, + String revocRegs) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int walletHandle = wallet.getWalletHandle(); + + int result = LibIndy.api.indy_prover_create_proof( + commandHandle, + walletHandle, + proofRequest, + requestedClaims, + schemas, + masterSecret, + claimDefs, + revocRegs, + proverCreateProofCb); + + checkResult(result); + + return future; + } + + public static CompletableFuture verifierVerifyProof( + String proofRequest, + String proof, + String schemas, + String claimDefs, + String revocRegs) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int result = LibIndy.api.indy_verifier_verify_proof( + commandHandle, + proofRequest, + proof, + schemas, + claimDefs, + revocRegs, + verifierVerifyProofCb); checkResult(result); diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/anoncreds/AnoncredsResults.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/anoncreds/AnoncredsResults.java index cb60994d94..8d784db27d 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/anoncreds/AnoncredsResults.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/anoncreds/AnoncredsResults.java @@ -11,14 +11,6 @@ private AnoncredsResults() { } - public static class IssuerCreateAndStoreClaimDefResult extends IndyJava.Result { - - private String claimDefJson, claimDefUuid; - IssuerCreateAndStoreClaimDefResult(String claimDefJson, String claimDefUuid) { this.claimDefJson = claimDefJson; this.claimDefUuid = claimDefUuid; } - public String getClaimDefJson() { return this.claimDefJson; } - public String getClaimDefUuid() { return this.claimDefUuid; } - } - public static class IssuerCreateAndStoreRevocRegResult extends IndyJava.Result { private String revocRegJson, revocRegUuid; @@ -34,68 +26,4 @@ public static class IssuerCreateClaimResult extends IndyJava.Result { public String getRevocRegUpdateJson() { return this.revocRegUpdateJson; } public String getClaimJson() { return this.claimJson; } } - - public static class IssuerRevokeClaimResult extends IndyJava.Result { - - private String revocRegUpdateJson; - IssuerRevokeClaimResult(String revocRegUpdateJson) { this.revocRegUpdateJson = revocRegUpdateJson; } - public String getRevocRegUpdateJson() { return this.revocRegUpdateJson; } - } - - public static class ProverStoreClaimOfferResult extends IndyJava.Result { - - ProverStoreClaimOfferResult() { } - } - - public static class ProverGetClaimOffersResult extends IndyJava.Result { - - private String claimOffersJson; - ProverGetClaimOffersResult(String claimOffersJson) { this.claimOffersJson = claimOffersJson; } - public String getClaimOffersJson() { return this.claimOffersJson; } - } - - public static class ProverCreateMasterSecretResult extends IndyJava.Result { - - ProverCreateMasterSecretResult() { } - } - - public static class ProverCreateAndStoreClaimReqResult extends IndyJava.Result { - - private String claimReqJson; - ProverCreateAndStoreClaimReqResult(String claimReqJson) { this.claimReqJson = claimReqJson; } - public String getClaimReqJson() { return this.claimReqJson; } - } - - public static class ProverStoreClaimResult extends IndyJava.Result { - - ProverStoreClaimResult() { } - } - - public static class ProverGetClaimsResult extends IndyJava.Result { - - private String claimsJson; - ProverGetClaimsResult(String claimsJson) { this.claimsJson = claimsJson; } - public String getClaimsJson() { return this.claimsJson; } - } - - public static class ProverGetClaimsForProofReqResult extends IndyJava.Result { - - private String claimsJson; - ProverGetClaimsForProofReqResult(String claimsJson) { this.claimsJson = claimsJson; } - public String getClaimsJson() { return this.claimsJson; } - } - - public static class ProverCreateProofResult extends IndyJava.Result { - - private String proofJson; - ProverCreateProofResult(String proofJson) { this.proofJson = proofJson; } - public String getProofJson() { return this.proofJson; } - } - - public static class VerifierVerifyProofResult extends IndyJava.Result { - - private boolean valid; - VerifierVerifyProofResult(boolean valid) { this.valid = valid; } - public boolean isValid() { return this.valid; } - } } diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ledger/Ledger.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ledger/Ledger.java index bc669d1557..7f27e62b46 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ledger/Ledger.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ledger/Ledger.java @@ -1,23 +1,10 @@ package org.hyperledger.indy.sdk.ledger; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; import org.hyperledger.indy.sdk.IndyException; -import org.hyperledger.indy.sdk.LibIndy; import org.hyperledger.indy.sdk.IndyJava; -import org.hyperledger.indy.sdk.ledger.LedgerResults.BuildAttribRequestResult; -import org.hyperledger.indy.sdk.ledger.LedgerResults.BuildClaimDefTxnResult; -import org.hyperledger.indy.sdk.ledger.LedgerResults.BuildGetAttribRequestResult; -import org.hyperledger.indy.sdk.ledger.LedgerResults.BuildGetClaimDefTxnResult; -import org.hyperledger.indy.sdk.ledger.LedgerResults.BuildGetDdoRequestResult; -import org.hyperledger.indy.sdk.ledger.LedgerResults.BuildGetNymRequestResult; -import org.hyperledger.indy.sdk.ledger.LedgerResults.BuildGetSchemaRequestResult; -import org.hyperledger.indy.sdk.ledger.LedgerResults.BuildNodeRequestResult; -import org.hyperledger.indy.sdk.ledger.LedgerResults.BuildNymRequestResult; -import org.hyperledger.indy.sdk.ledger.LedgerResults.BuildSchemaRequestResult; -import org.hyperledger.indy.sdk.ledger.LedgerResults.SignAndSubmitRequestResult; -import org.hyperledger.indy.sdk.ledger.LedgerResults.SubmitRequestResult; +import org.hyperledger.indy.sdk.LibIndy; import org.hyperledger.indy.sdk.pool.Pool; import org.hyperledger.indy.sdk.wallet.Wallet; @@ -32,380 +19,447 @@ private Ledger() { } + /* + * STATIC CALLBACKS + */ + + private static Callback signAndSubmitRequestCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_result_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_result_json; + future.complete(result); + } + }; + + private static Callback submitRequestCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_result_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_result_json; + future.complete(result); + } + }; + + private static Callback buildGetDdoRequestCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_json; + future.complete(result); + } + }; + + private static Callback buildNymRequestCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_json; + future.complete(result); + } + }; + + private static Callback buildAttribRequestCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_json; + future.complete(result); + } + }; + + private static Callback buildGetAttribRequestCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_json; + future.complete(result); + } + }; + + private static Callback buildGetNymRequestCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_json; + future.complete(result); + } + }; + + private static Callback buildSchemaRequestCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_json; + future.complete(result); + } + }; + + private static Callback buildGetSchemaRequestCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_json; + future.complete(result); + } + }; + + private static Callback buildClaimDefTxnCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_json; + future.complete(result); + } + }; + + private static Callback buildGetClaimDefTxnCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_json; + future.complete(result); + } + }; + + private static Callback buildNodeRequestCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_json; + future.complete(result); + } + }; + + public static Callback buildGetTxnRequestCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String request_json) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = request_json; + future.complete(result); + } + }; + /* * STATIC METHODS */ - public static Future signAndSubmitRequest( + public static CompletableFuture signAndSubmitRequest( Pool pool, Wallet wallet, String submitterDid, String requestJson) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String request_result_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - SignAndSubmitRequestResult result = new SignAndSubmitRequestResult(request_result_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int poolHandle = pool.getPoolHandle(); int walletHandle = wallet.getWalletHandle(); int result = LibIndy.api.indy_sign_and_submit_request( - FIXED_COMMAND_HANDLE, + commandHandle, poolHandle, walletHandle, submitterDid, requestJson, - callback); + signAndSubmitRequestCb); checkResult(result); return future; } - public static Future submitRequest( + public static CompletableFuture submitRequest( Pool pool, String requestJson) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String request_result_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - SubmitRequestResult result = new SubmitRequestResult(request_result_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int poolHandle = pool.getPoolHandle(); int result = LibIndy.api.indy_submit_request( - FIXED_COMMAND_HANDLE, + commandHandle, poolHandle, requestJson, - callback); + submitRequestCb); checkResult(result); return future; } - public static Future buildGetDdoRequest( + public static CompletableFuture buildGetDdoRequest( String submitterDid, String targetDid, String requestJson) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String request_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - BuildGetDdoRequestResult result = new BuildGetDdoRequestResult(request_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_build_get_ddo_request( - FIXED_COMMAND_HANDLE, + commandHandle, submitterDid, targetDid, - callback); + buildGetDdoRequestCb); checkResult(result); return future; } - public static Future buildNymRequest( + public static CompletableFuture buildNymRequest( String submitterDid, String targetDid, String verkey, String alias, String role) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String request_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - BuildNymRequestResult result = new BuildNymRequestResult(request_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_build_nym_request( - FIXED_COMMAND_HANDLE, + commandHandle, submitterDid, targetDid, verkey, alias, role, - callback); + buildNymRequestCb); checkResult(result); return future; } - public static Future buildAttribRequest( + public static CompletableFuture buildAttribRequest( String submitterDid, String targetDid, String hash, String raw, String enc) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String request_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - BuildAttribRequestResult result = new BuildAttribRequestResult(request_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_build_attrib_request( - FIXED_COMMAND_HANDLE, + commandHandle, submitterDid, targetDid, hash, raw, enc, - callback); + buildAttribRequestCb); checkResult(result); return future; } - public static Future buildGetAttribRequest( + public static CompletableFuture buildGetAttribRequest( String submitterDid, String targetDid, String data) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String request_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - BuildGetAttribRequestResult result = new BuildGetAttribRequestResult(request_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_build_get_attrib_request( - FIXED_COMMAND_HANDLE, + commandHandle, submitterDid, targetDid, data, - callback); + buildGetAttribRequestCb); checkResult(result); return future; } - public static Future buildGetNymRequest( + public static CompletableFuture buildGetNymRequest( String submitterDid, String targetDid) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String request_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - BuildGetNymRequestResult result = new BuildGetNymRequestResult(request_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_build_get_nym_request( - FIXED_COMMAND_HANDLE, + commandHandle, submitterDid, targetDid, - callback); + buildGetNymRequestCb); checkResult(result); return future; } - public static Future buildSchemaRequest( + public static CompletableFuture buildSchemaRequest( String submitterDid, String data) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String request_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - BuildSchemaRequestResult result = new BuildSchemaRequestResult(request_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_build_schema_request( - FIXED_COMMAND_HANDLE, + commandHandle, submitterDid, data, - callback); + buildSchemaRequestCb); checkResult(result); return future; } - public static Future buildGetSchemaRequest( + public static CompletableFuture buildGetSchemaRequest( String submitterDid, + String dest, String data) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String request_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - BuildGetSchemaRequestResult result = new BuildGetSchemaRequestResult(request_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_build_get_schema_request( - FIXED_COMMAND_HANDLE, + commandHandle, submitterDid, + dest, data, - callback); + buildGetSchemaRequestCb); checkResult(result); return future; } - public static Future buildClaimDefTxn( + public static CompletableFuture buildClaimDefTxn( String submitterDid, - String xref, + int xref, + String signatureType, String data) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String request_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - BuildClaimDefTxnResult result = new BuildClaimDefTxnResult(request_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_build_claim_def_txn( - FIXED_COMMAND_HANDLE, + commandHandle, submitterDid, xref, + signatureType, data, - callback); + buildClaimDefTxnCb); checkResult(result); return future; } - public static Future buildGetClaimDefTxn( + public static CompletableFuture buildGetClaimDefTxn( String submitterDid, - String xref) throws IndyException { - - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String request_json) { + int xref, + String signatureType, + String origin) throws IndyException { - if (! checkCallback(future, xcommand_handle, err)) return; - - BuildGetClaimDefTxnResult result = new BuildGetClaimDefTxnResult(request_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_build_get_claim_def_txn( - FIXED_COMMAND_HANDLE, + commandHandle, submitterDid, xref, - callback); + signatureType, + origin, + buildGetClaimDefTxnCb); checkResult(result); return future; } - public static Future buildNodeRequest( + public static CompletableFuture buildNodeRequest( String submitterDid, String targetDid, String data) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String request_json) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - BuildNodeRequestResult result = new BuildNodeRequestResult(request_json); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_build_node_request( - FIXED_COMMAND_HANDLE, + commandHandle, submitterDid, targetDid, data, - callback); + buildNodeRequestCb); + + checkResult(result); + + return future; + } + + public static CompletableFuture buildGetTxnRequest( + String submitterDid, + int data) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int result = LibIndy.api.indy_build_get_txn_request( + commandHandle, + submitterDid, + data, + buildGetTxnRequestCb); checkResult(result); diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ledger/LedgerResults.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ledger/LedgerResults.java index 714e83effb..0c7b75c102 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ledger/LedgerResults.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ledger/LedgerResults.java @@ -1,7 +1,5 @@ package org.hyperledger.indy.sdk.ledger; -import org.hyperledger.indy.sdk.IndyJava; - /** * ledger.rs results */ @@ -10,88 +8,4 @@ public final class LedgerResults { private LedgerResults() { } - - public static class SignAndSubmitRequestResult extends IndyJava.Result { - - private String requestResultJson; - SignAndSubmitRequestResult(String requestResultJson) { this.requestResultJson = requestResultJson; } - public String getRequestResultJson() { return this.requestResultJson; } - } - - public static class SubmitRequestResult extends IndyJava.Result { - - private String requestResultJson; - SubmitRequestResult(String requestResultJson) { this.requestResultJson = requestResultJson; } - public String getRequestResultJson() { return this.requestResultJson; } - } - - public static class BuildGetDdoRequestResult extends IndyJava.Result { - - private String requestJson; - BuildGetDdoRequestResult(String requestJson) { this.requestJson = requestJson; } - public String getRequestJson() { return this.requestJson; } - } - - public static class BuildNymRequestResult extends IndyJava.Result { - - private String requestJson; - BuildNymRequestResult(String requestJson) { this.requestJson = requestJson; } - public String getRequestJson() { return this.requestJson; } - } - - public static class BuildAttribRequestResult extends IndyJava.Result { - - private String requestJson; - BuildAttribRequestResult(String requestJson) { this.requestJson = requestJson; } - public String getRequestJson() { return this.requestJson; } - } - - public static class BuildGetAttribRequestResult extends IndyJava.Result { - - private String requestJson; - BuildGetAttribRequestResult(String requestJson) { this.requestJson = requestJson; } - public String getRequestJson() { return this.requestJson; } - } - - public static class BuildGetNymRequestResult extends IndyJava.Result { - - private String requestJson; - BuildGetNymRequestResult(String requestJson) { this.requestJson = requestJson; } - public String getRequestJson() { return this.requestJson; } - } - - public static class BuildSchemaRequestResult extends IndyJava.Result { - - private String requestJson; - BuildSchemaRequestResult(String requestJson) { this.requestJson = requestJson; } - public String getRequestJson() { return this.requestJson; } - } - - public static class BuildGetSchemaRequestResult extends IndyJava.Result { - - private String requestJson; - BuildGetSchemaRequestResult(String requestJson) { this.requestJson = requestJson; } - public String getRequestJson() { return this.requestJson; } - } - - public static class BuildClaimDefTxnResult extends IndyJava.Result { - - private String requestJson; - BuildClaimDefTxnResult(String requestJson) { this.requestJson = requestJson; } - public String getRequestJson() { return this.requestJson; } - } - - public static class BuildGetClaimDefTxnResult extends IndyJava.Result { - - private String requestResultJson; - BuildGetClaimDefTxnResult(String requestResultJson) { this.requestResultJson = requestResultJson; } - public String getRequestResultJson() { return this.requestResultJson; } - } - - public static class BuildNodeRequestResult extends IndyJava.Result { - - private String requestJson; - BuildNodeRequestResult(String requestJson) { this.requestJson = requestJson; } - public String getRequestJson() { return this.requestJson; } - } } diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/pool/Pool.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/pool/Pool.java index 4b62fd4f54..de1541da5b 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/pool/Pool.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/pool/Pool.java @@ -1,18 +1,10 @@ package org.hyperledger.indy.sdk.pool; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; import org.hyperledger.indy.sdk.IndyException; -import org.hyperledger.indy.sdk.LibIndy; import org.hyperledger.indy.sdk.IndyJava; -import org.hyperledger.indy.sdk.pool.PoolJSONParameters.CreatePoolLedgerConfigJSONParameter; -import org.hyperledger.indy.sdk.pool.PoolJSONParameters.OpenPoolLedgerJSONParameter; -import org.hyperledger.indy.sdk.pool.PoolResults.ClosePoolLedgerResult; -import org.hyperledger.indy.sdk.pool.PoolResults.CreatePoolLedgerConfigResult; -import org.hyperledger.indy.sdk.pool.PoolResults.DeletePoolLedgerConfigResult; -import org.hyperledger.indy.sdk.pool.PoolResults.OpenPoolLedgerResult; -import org.hyperledger.indy.sdk.pool.PoolResults.RefreshPoolLedgerResult; +import org.hyperledger.indy.sdk.LibIndy; import com.sun.jna.Callback; @@ -23,155 +15,173 @@ public class Pool extends IndyJava.API { private final int poolHandle; - Pool(int poolHandle) { + private Pool(int poolHandle) { this.poolHandle = poolHandle; } public int getPoolHandle() { - + return this.poolHandle; } - + /* - * STATIC METHODS + * STATIC CALLBACKS */ - - public static Future createPoolLedgerConfig( - String configName, - CreatePoolLedgerConfigJSONParameter config) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); + private static Callback createPoolLedgerConfigCb = new Callback() { - Callback callback = new Callback() { + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err) { + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; - if (! checkCallback(future, xcommand_handle, err)) return; + Void result = null; + future.complete(result); + } + }; - CreatePoolLedgerConfigResult result = new CreatePoolLedgerConfigResult(); - future.complete(result); - } - }; + private static Callback openPoolLedgerCb = new Callback() { - int result = LibIndy.api.indy_create_pool_ledger_config( - FIXED_COMMAND_HANDLE, - configName, - config == null ? null : config.toJson(), - callback); + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, int pool_handle) { - checkResult(result); + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; - return future; - } + Pool pool = new Pool(pool_handle); - public static Future openPoolLedger( - String configName, - OpenPoolLedgerJSONParameter config) throws IndyException { + Pool result = pool; + future.complete(result); + } + }; - final CompletableFuture future = new CompletableFuture<> (); + private static Callback refreshPoolLedgerCb = new Callback() { - Callback callback = new Callback() { + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, int pool_handle) { + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; - if (! checkCallback(future, xcommand_handle, err)) return; + Void result = null; + future.complete(result); + } + }; - Pool pool = new Pool(pool_handle); + private static Callback closePoolLedgerCb = new Callback() { - OpenPoolLedgerResult result = new OpenPoolLedgerResult(pool); - future.complete(result); - } - }; + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { - int result = LibIndy.api.indy_open_pool_ledger( - FIXED_COMMAND_HANDLE, + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Void result = null; + future.complete(result); + } + }; + + private static Callback deletePoolLedgerConfigCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Void result = null; + future.complete(result); + } + }; + + /* + * STATIC METHODS + */ + + public static CompletableFuture createPoolLedgerConfig( + String configName, + String config) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int result = LibIndy.api.indy_create_pool_ledger_config( + commandHandle, configName, - config == null ? null : config.toJson(), - callback); + config, + createPoolLedgerConfigCb); checkResult(result); return future; } - private static Future refreshPoolLedger( - int handle) throws IndyException { + public static CompletableFuture openPoolLedger( + String configName, + String config) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); + + int result = LibIndy.api.indy_open_pool_ledger( + commandHandle, + configName, + config, + openPoolLedgerCb); - final CompletableFuture future = new CompletableFuture<> (); + checkResult(result); - Callback callback = new Callback() { + return future; + } - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err) { + private static CompletableFuture refreshPoolLedger( + Pool pool) throws IndyException { - if (! checkCallback(future, xcommand_handle, err)) return; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); - RefreshPoolLedgerResult result = new RefreshPoolLedgerResult(); - future.complete(result); - } - }; + int handle = pool.getPoolHandle(); int result = LibIndy.api.indy_refresh_pool_ledger( - FIXED_COMMAND_HANDLE, + commandHandle, handle, - callback); + refreshPoolLedgerCb); checkResult(result); return future; } - private static Future closePoolLedger( - int handle) throws IndyException { - - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { + private static CompletableFuture closePoolLedger( + Pool pool) throws IndyException { - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err) { + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); - if (! checkCallback(future, xcommand_handle, err)) return; - - ClosePoolLedgerResult result = new ClosePoolLedgerResult(); - future.complete(result); - } - }; + int handle = pool.getPoolHandle(); int result = LibIndy.api.indy_close_pool_ledger( - FIXED_COMMAND_HANDLE, + commandHandle, handle, - callback); + closePoolLedgerCb); checkResult(result); return future; } - public static Future deletePoolLedgerConfig( + public static CompletableFuture deletePoolLedgerConfig( String configName) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - DeletePoolLedgerConfigResult result = new DeletePoolLedgerConfigResult(); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_delete_pool_ledger_config( - FIXED_COMMAND_HANDLE, + commandHandle, configName, - callback); + deletePoolLedgerConfigCb); checkResult(result); @@ -182,15 +192,15 @@ public void callback(int xcommand_handle, int err) { * INSTANCE METHODS */ - public Future refreshPoolLedger( + public CompletableFuture refreshPoolLedger( ) throws IndyException { - return refreshPoolLedger(this.poolHandle); + return refreshPoolLedger(this); } - public Future closePoolLedger( + public CompletableFuture closePoolLedger( ) throws IndyException { - return closePoolLedger(this.poolHandle); + return closePoolLedger(this); } } diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/pool/PoolResults.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/pool/PoolResults.java index 6a15c295bc..7cf6e0a931 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/pool/PoolResults.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/pool/PoolResults.java @@ -1,7 +1,5 @@ package org.hyperledger.indy.sdk.pool; -import org.hyperledger.indy.sdk.IndyJava; - /** * pool.rs results */ @@ -10,31 +8,4 @@ public final class PoolResults { private PoolResults() { } - - public static class CreatePoolLedgerConfigResult extends IndyJava.Result { - - CreatePoolLedgerConfigResult() { } - } - - public static class OpenPoolLedgerResult extends IndyJava.Result { - - private Pool pool; - OpenPoolLedgerResult(Pool pool) { this.pool = pool; } - public Pool getPool() { return this.pool; } - } - - public static class RefreshPoolLedgerResult extends IndyJava.Result { - - RefreshPoolLedgerResult() { } - } - - public static class ClosePoolLedgerResult extends IndyJava.Result { - - ClosePoolLedgerResult() { } - } - - public static class DeletePoolLedgerConfigResult extends IndyJava.Result { - - DeletePoolLedgerConfigResult() { } - } } diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/signus/Signus.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/signus/Signus.java index b563af9ce2..731be50240 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/signus/Signus.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/signus/Signus.java @@ -1,20 +1,13 @@ package org.hyperledger.indy.sdk.signus; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; import org.hyperledger.indy.sdk.IndyException; -import org.hyperledger.indy.sdk.LibIndy; import org.hyperledger.indy.sdk.IndyJava; +import org.hyperledger.indy.sdk.LibIndy; import org.hyperledger.indy.sdk.pool.Pool; -import org.hyperledger.indy.sdk.signus.SignusJSONParameters.CreateAndStoreMyDidJSONParameter; import org.hyperledger.indy.sdk.signus.SignusResults.CreateAndStoreMyDidResult; -import org.hyperledger.indy.sdk.signus.SignusResults.DecryptResult; -import org.hyperledger.indy.sdk.signus.SignusResults.EncryptResult; import org.hyperledger.indy.sdk.signus.SignusResults.ReplaceKeysResult; -import org.hyperledger.indy.sdk.signus.SignusResults.SignResult; -import org.hyperledger.indy.sdk.signus.SignusResults.StoreTheirDidResult; -import org.hyperledger.indy.sdk.signus.SignusResults.VerifySignatureResult; import org.hyperledger.indy.sdk.wallet.Wallet; import com.sun.jna.Callback; @@ -29,233 +22,260 @@ private Signus() { } /* - * STATIC METHODS + * STATIC CALLBACKS */ - public static Future createAndStoreMyDid( - Wallet wallet, - CreateAndStoreMyDidJSONParameter didJson) throws IndyException { + private static Callback createAndStoreMyDidCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String did, String verkey, String pk) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + CreateAndStoreMyDidResult result = new CreateAndStoreMyDidResult(did, verkey, pk); + future.complete(result); + } + }; + + private static Callback replaceKeysCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String verkey, String pk) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + ReplaceKeysResult result = new ReplaceKeysResult(verkey, pk); + future.complete(result); + } + }; + + private static Callback storeTheirDidCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Void result = null; + future.complete(result); + } + }; - final CompletableFuture future = new CompletableFuture<> (); + private static Callback signCb = new Callback() { - Callback callback = new Callback() { + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String signature) { - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String did, String verkey, String pk) { + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; - if (! checkCallback(future, xcommand_handle, err)) return; + String result = signature; + future.complete(result); + } + }; - CreateAndStoreMyDidResult result = new CreateAndStoreMyDidResult(did, verkey, pk); - future.complete(result); - } - }; + private static Callback verifySignatureCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, boolean valid) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Boolean result = Boolean.valueOf(valid); + future.complete(result); + } + }; + + private static Callback encryptCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String encryptedMsg) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = encryptedMsg; + future.complete(result); + } + }; + + private static Callback decryptCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, String decryptedMsg) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + String result = decryptedMsg; + future.complete(result); + } + }; + + /* + * STATIC METHODS + */ + + public static CompletableFuture createAndStoreMyDid( + Wallet wallet, + String didJson) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); int result = LibIndy.api.indy_create_and_store_my_did( - FIXED_COMMAND_HANDLE, + commandHandle, walletHandle, - didJson == null ? null : didJson.toJson(), - callback); + didJson, + createAndStoreMyDidCb); checkResult(result); return future; } - public static Future replaceKeys( + public static CompletableFuture replaceKeys( Wallet wallet, String did, String identityJson) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String verkey, String pk) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - ReplaceKeysResult result = new ReplaceKeysResult(verkey, pk); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); int result = LibIndy.api.indy_replace_keys( - FIXED_COMMAND_HANDLE, + commandHandle, walletHandle, did, identityJson, - callback); + replaceKeysCb); checkResult(result); return future; } - public static Future storeTheirDid( + public static CompletableFuture storeTheirDid( Wallet wallet, String identityJson) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - StoreTheirDidResult result = new StoreTheirDidResult(); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); int result = LibIndy.api.indy_store_their_did( - FIXED_COMMAND_HANDLE, + commandHandle, walletHandle, identityJson, - callback); + storeTheirDidCb); checkResult(result); return future; } - public static Future sign( + public static CompletableFuture sign( Wallet wallet, String did, String msg) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String signature) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - SignResult result = new SignResult(signature); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); int result = LibIndy.api.indy_sign( - FIXED_COMMAND_HANDLE, + commandHandle, walletHandle, did, msg, - callback); + signCb); checkResult(result); return future; } - public static Future verifySignature( + public static CompletableFuture verifySignature( Wallet wallet, Pool pool, String did, String signedMsg) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, boolean valid) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - VerifySignatureResult result = new VerifySignatureResult(valid); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); int poolHandle = pool.getPoolHandle(); int result = LibIndy.api.indy_verify_signature( - FIXED_COMMAND_HANDLE, + commandHandle, walletHandle, poolHandle, did, signedMsg, - callback); + verifySignatureCb); checkResult(result); return future; } - public static Future encrypt( + public static CompletableFuture encrypt( Wallet wallet, + Pool pool, + String myDid, String did, String msg) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String encryptedMsg) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - EncryptResult result = new EncryptResult(encryptedMsg); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); + int poolHandle = pool.getPoolHandle(); int result = LibIndy.api.indy_encrypt( - FIXED_COMMAND_HANDLE, + commandHandle, walletHandle, + poolHandle, + myDid, did, msg, - callback); + encryptCb); checkResult(result); return future; } - public static Future decrypt( + public static CompletableFuture decrypt( Wallet wallet, + String myDid, String did, - String encryptedMsg) throws IndyException { - - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, String decryptedMsg) { - - if (! checkCallback(future, xcommand_handle, err)) return; + String encryptedMsg, + String nonce) throws IndyException { - DecryptResult result = new DecryptResult(decryptedMsg); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int walletHandle = wallet.getWalletHandle(); int result = LibIndy.api.indy_decrypt( - FIXED_COMMAND_HANDLE, + commandHandle, walletHandle, + myDid, did, encryptedMsg, - callback); + nonce, + decryptCb); checkResult(result); diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/signus/SignusResults.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/signus/SignusResults.java index 7b67283b84..4182b7f8b0 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/signus/SignusResults.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/signus/SignusResults.java @@ -27,37 +27,4 @@ public static class ReplaceKeysResult extends IndyJava.Result { public String getVerkey() { return this.verkey; } public String getPk() { return this.pk; } } - - public static class StoreTheirDidResult extends IndyJava.Result { - - StoreTheirDidResult() { } - } - - public static class SignResult extends IndyJava.Result { - - private String signature; - SignResult(String signature) { this.signature = signature; } - public String getSignature() { return this.signature; } - } - - public static class VerifySignatureResult extends IndyJava.Result { - - private boolean valid; - VerifySignatureResult(boolean valid) { this.valid = valid; } - public boolean isValid() { return this.valid; } - } - - public static class EncryptResult extends IndyJava.Result { - - private String encryptedMsg; - EncryptResult(String encryptedMsg) { this.encryptedMsg = encryptedMsg; } - public String getEncryptedMsg() { return this.encryptedMsg; } - } - - public static class DecryptResult extends IndyJava.Result { - - private String decryptedMsg; - DecryptResult(String decryptedMsg) { this.decryptedMsg = decryptedMsg; } - public String getDecryptedMsg() { return this.decryptedMsg; } - } } diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/Wallet.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/Wallet.java index b53b79ac7c..2c529b879b 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/Wallet.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/Wallet.java @@ -1,16 +1,13 @@ package org.hyperledger.indy.sdk.wallet; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; import org.hyperledger.indy.sdk.IndyException; -import org.hyperledger.indy.sdk.LibIndy; import org.hyperledger.indy.sdk.IndyJava; -import org.hyperledger.indy.sdk.wallet.WalletResults.CloseWalletResult; -import org.hyperledger.indy.sdk.wallet.WalletResults.CreateWalletResult; -import org.hyperledger.indy.sdk.wallet.WalletResults.DeleteWalletResult; -import org.hyperledger.indy.sdk.wallet.WalletResults.OpenWalletResult; -import org.hyperledger.indy.sdk.wallet.WalletResults.WalletSetSeqNoForValueResult; +import org.hyperledger.indy.sdk.LibIndy; import com.sun.jna.Callback; @@ -21,172 +18,205 @@ public class Wallet extends IndyJava.API { private final int walletHandle; - Wallet(int walletHandle) { + private Wallet(int walletHandle) { this.walletHandle = walletHandle; } public int getWalletHandle() { - + return this.walletHandle; } + /* + * STATIC CALLBACKS + */ + + private static Callback registerWalletTypeCb = new Callback() { + + @SuppressWarnings({ "unused", "unchecked" }) + public void callback(int xcommand_handle, int err) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Void result = null; + future.complete(result); + } + }; + + private static Callback createWalletCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Void result = null; + future.complete(result); + } + }; + + private static Callback openWalletCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err, int handle) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Wallet wallet = new Wallet(handle); + + Wallet result = wallet; + future.complete(result); + } + }; + + private static Callback closeWalletCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Void result = null; + future.complete(result); + } + }; + + private static Callback deleteWalletCb = new Callback() { + + @SuppressWarnings({"unused", "unchecked"}) + public void callback(int xcommand_handle, int err) { + + CompletableFuture future = (CompletableFuture) removeFuture(xcommand_handle); + if (! checkCallback(future, err)) return; + + Void result = null; + future.complete(result); + } + }; + /* * STATIC METHODS */ - /* IMPLEMENT LATER - * public Future<...> registerWalletType( - ...) throws IndyException;*/ + private static final List REGISERED_WALLETS = Collections.synchronizedList(new ArrayList()); - public static Future createWallet( - String poolName, - String name, + public static CompletableFuture registerWalletType( String xtype, - String config, - String credentials) throws IndyException { + WalletType walletType, + Boolean forceCreate) throws IndyException, InterruptedException { - final CompletableFuture future = new CompletableFuture<> (); + synchronized (REGISERED_WALLETS) { + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); - Callback callback = new Callback() { - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err) { + if (REGISERED_WALLETS.contains(xtype) && ! forceCreate) { + future.complete(null); + return future; + } - if (! checkCallback(future, xcommand_handle, err)) return; - CreateWalletResult result = new CreateWalletResult(); - future.complete(result); - } - }; + REGISERED_WALLETS.add(xtype); + + int result = LibIndy.api.indy_register_wallet_type( + commandHandle, + xtype, + walletType.getCreateCb(), + walletType.getOpenCb(), + walletType.getSetCb(), + walletType.getGetCb(), + walletType.getGetNotExpiredCb(), + walletType.getListCb(), + walletType.getCloseCb(), + walletType.getDeleteCb(), + walletType.getFreeCb(), + registerWalletTypeCb); + + checkResult(result); + + return future; + } + } + + public static CompletableFuture createWallet( + String poolName, + String name, + String xtype, + String config, + String credentials) throws IndyException { + + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_create_wallet( - FIXED_COMMAND_HANDLE, + commandHandle, poolName, name, xtype, config, credentials, - callback); + createWalletCb); checkResult(result); return future; } - public static Future openWallet( + public static CompletableFuture openWallet( String name, String runtimeConfig, String credentials) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err, int handle) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - Wallet wallet = new Wallet(handle); - - OpenWalletResult result = new OpenWalletResult(wallet); - future.complete(result); - } - }; - int result = LibIndy.api.indy_open_wallet( - FIXED_COMMAND_HANDLE, + commandHandle, name, runtimeConfig, credentials, - callback); + openWalletCb); checkResult(result); return future; } - private static Future closeWallet( - int handle) throws IndyException { - - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { + private static CompletableFuture closeWallet( + Wallet wallet) throws IndyException { - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err) { + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); - if (! checkCallback(future, xcommand_handle, err)) return; - - CloseWalletResult result = new CloseWalletResult(); - future.complete(result); - } - }; + int handle = wallet.getWalletHandle(); int result = LibIndy.api.indy_close_wallet( - FIXED_COMMAND_HANDLE, + commandHandle, handle, - callback); + closeWalletCb); checkResult(result); return future; } - public static Future deleteWallet( + public static CompletableFuture deleteWallet( String name, String credentials) throws IndyException { - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - DeleteWalletResult result = new DeleteWalletResult(); - future.complete(result); - } - }; + CompletableFuture future = new CompletableFuture(); + int commandHandle = addFuture(future); int result = LibIndy.api.indy_delete_wallet( - FIXED_COMMAND_HANDLE, + commandHandle, name, credentials, - callback); - - checkResult(result); - - return future; - } - - private static Future walletSetSeqNoForValue( - int walletHandle, - String walletKey, - String configName) throws IndyException { - - final CompletableFuture future = new CompletableFuture<> (); - - Callback callback = new Callback() { - - @SuppressWarnings("unused") - public void callback(int xcommand_handle, int err) { - - if (! checkCallback(future, xcommand_handle, err)) return; - - WalletSetSeqNoForValueResult result = new WalletSetSeqNoForValueResult(); - future.complete(result); - } - }; - - int result = LibIndy.api.indy_wallet_set_seq_no_for_value( - FIXED_COMMAND_HANDLE, - walletHandle, - walletKey, - callback); + deleteWalletCb); checkResult(result); @@ -197,16 +227,9 @@ public void callback(int xcommand_handle, int err) { * INSTANCE METHODS */ - public Future closeWallet( + public CompletableFuture closeWallet( ) throws IndyException { - - return closeWallet(this.walletHandle); - } - public Future walletSetSeqNoForValue( - String walletKey, - String configName) throws IndyException { - - return walletSetSeqNoForValue(this.walletHandle, walletKey, configName); + return closeWallet(this); } } diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/WalletResults.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/WalletResults.java index 415ed83317..296aa55515 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/WalletResults.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/WalletResults.java @@ -1,7 +1,5 @@ package org.hyperledger.indy.sdk.wallet; -import org.hyperledger.indy.sdk.IndyJava; - /** * wallet.rs Results */ @@ -10,31 +8,4 @@ public final class WalletResults { private WalletResults() { } - - public static class CreateWalletResult extends IndyJava.Result { - - CreateWalletResult() { } - } - - public static class OpenWalletResult extends IndyJava.Result { - - private Wallet wallet; - OpenWalletResult(Wallet wallet) { this.wallet = wallet; } - public Wallet getWallet() { return this.wallet; } - } - - public static class CloseWalletResult extends IndyJava.Result { - - CloseWalletResult() { } - } - - public static class DeleteWalletResult extends IndyJava.Result { - - DeleteWalletResult() { } - } - - public static class WalletSetSeqNoForValueResult extends IndyJava.Result { - - WalletSetSeqNoForValueResult() { } - } } diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/WalletType.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/WalletType.java new file mode 100644 index 0000000000..c619f67a48 --- /dev/null +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/WalletType.java @@ -0,0 +1,137 @@ +package org.hyperledger.indy.sdk.wallet; + +import org.hyperledger.indy.sdk.ErrorCode; + +import com.sun.jna.Callback; +import com.sun.jna.Pointer; +import com.sun.jna.ptr.PointerByReference; + +public abstract class WalletType { + + private Callback createCb = new Callback() { + + @SuppressWarnings("unused") + public int callback(String name, String config, String credentials) { + + return WalletType.this.create(name, config, credentials).ordinal(); + } + }; + + private Callback openCb = new Callback() { + + @SuppressWarnings("unused") + public int callback(String name, String config, String runtime_config, String credentials, Pointer handle) { + + return WalletType.this.open(name, config, runtime_config, credentials, handle).ordinal(); + } + }; + + private Callback setCb = new Callback() { + + @SuppressWarnings("unused") + public int callback(int handle, String key, String value) { + + return WalletType.this.set(handle, key, value).ordinal(); + } + }; + + private Callback getCb = new Callback() { + + @SuppressWarnings("unused") + public int callback(int handle, String key, PointerByReference value_ptr) { + + return WalletType.this.get(handle, key, value_ptr).ordinal(); + } + }; + + private Callback getNotExpiredCb = new Callback() { + + @SuppressWarnings("unused") + public int callback(int handle, String key, PointerByReference value_ptr) { + + return WalletType.this.getNotExpired(handle, key, value_ptr).ordinal(); + } + }; + + private Callback listCb = new Callback() { + + @SuppressWarnings("unused") + public int callback(int handle, String key_prefix, PointerByReference values_json_ptr) { + + return WalletType.this.list(handle, key_prefix, values_json_ptr).ordinal(); + } + }; + + private Callback closeCb = new Callback() { + + @SuppressWarnings("unused") + public int callback(int handle) { + + return WalletType.this.close(handle).ordinal(); + } + }; + + private Callback deleteCb = new Callback() { + + @SuppressWarnings("unused") + public int callback(String name, String config, String credentials) { + + return WalletType.this.delete(name, config, credentials).ordinal(); + } + }; + + private Callback freeCb = new Callback() { + + @SuppressWarnings("unused") + public int callback(int wallet_handle, Pointer value) { + + return WalletType.this.free(wallet_handle, value).ordinal(); + } + }; + + public abstract ErrorCode create(String name, String config, String credentials); + public abstract ErrorCode open(String name, String config, String runtimeConfig, String credentials, Pointer handle); + public abstract ErrorCode set(int handle, String key, String value); + public abstract ErrorCode get(int handle, String key, PointerByReference valuePtr); + public abstract ErrorCode getNotExpired(int handle, String key, PointerByReference valuePtr); + public abstract ErrorCode list(int handle, String keyPrefx, PointerByReference valuesJsonPtr); + public abstract ErrorCode close(int handle); + public abstract ErrorCode delete(String name, String config, String credentials); + public abstract ErrorCode free(int walletHandle, Pointer value); + + public Callback getCreateCb() { + return createCb; + } + + public Callback getOpenCb() { + return openCb; + } + + public Callback getSetCb() { + return setCb; + } + + public Callback getGetCb() { + return getCb; + } + + public Callback getGetNotExpiredCb() { + return getNotExpiredCb; + } + + public Callback getListCb() { + return listCb; + } + + public Callback getCloseCb() { + return closeCb; + } + + public Callback getDeleteCb() { + return deleteCb; + } + + public Callback getFreeCb() { + return freeCb; + } +} diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/WalletTypeInmem.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/WalletTypeInmem.java new file mode 100644 index 0000000000..2e356b1af3 --- /dev/null +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/wallet/WalletTypeInmem.java @@ -0,0 +1,189 @@ +package org.hyperledger.indy.sdk.wallet; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +import org.hyperledger.indy.sdk.ErrorCode; + +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.ptr.PointerByReference; + +public class WalletTypeInmem extends WalletType { + + private static WalletTypeInmem instance; + + public static WalletTypeInmem getInstance() { + + if (instance == null) instance = new WalletTypeInmem(); + return instance; + } + + private WalletTypeInmem() { + + } + + @Override + public ErrorCode create(String name, String config, String credentials) { + + if (this.walletsByName.containsKey(name)) return ErrorCode.CommonInvalidState; + + WalletInmem wallet = new WalletInmem(); + this.walletsByName.put(name, wallet); + this.walletsByHandle.put(wallet.handle, wallet); + + return ErrorCode.Success; + } + + @Override + public ErrorCode open(String name, String config, String runtimeConfig, String credentials, Pointer handle) { + + WalletInmem wallet = this.walletsByName.get(name); + if (wallet == null) return ErrorCode.CommonInvalidState; + + wallet.open = true; + + handle.setInt(0, wallet.handle); + return ErrorCode.Success; + } + + @Override + public ErrorCode set(int handle, String key, String value) { + + WalletInmem wallet = this.walletsByHandle.get(handle); + if (wallet == null) return ErrorCode.CommonInvalidState; + + wallet.values.put(key, value); + + return ErrorCode.Success; + } + + @Override + public ErrorCode get(int handle, String key, PointerByReference valuePtr) { + + WalletInmem wallet = this.walletsByHandle.get(handle); + if (wallet == null) return ErrorCode.CommonInvalidState; + + String value = wallet.values.get(key); + + byte[] bytes = Native.toByteArray(value); + Pointer pointer = new Memory(bytes.length + 1); + pointer.write(0, bytes, 0, bytes.length); + pointer.setByte(bytes.length, (byte) 0); + valuePtr.setPointer(pointer); + return ErrorCode.Success; + } + + @Override + public ErrorCode getNotExpired(int handle, String key, PointerByReference valuePtr) { + + WalletInmem wallet = this.walletsByHandle.get(handle); + if (wallet == null) return ErrorCode.CommonInvalidState; + + String value = wallet.values.get(key); + + byte[] bytes = Native.toByteArray(value); + Pointer pointer = new Memory(bytes.length + 1); + pointer.write(0, bytes, 0, bytes.length); + pointer.setByte(bytes.length, (byte) 0); + valuePtr.setPointer(pointer); + return ErrorCode.Success; + } + + @Override + public ErrorCode list(int handle, String keyPrefix, PointerByReference valuesJsonPtr) { + + WalletInmem wallet = this.walletsByHandle.get(handle); + if (wallet == null) return ErrorCode.CommonInvalidState; + + StringBuilder builder = new StringBuilder(); + builder.append("["); + + for (Iterator> iterator = wallet.values.entrySet().iterator(); iterator.hasNext(); ) { + + Map.Entry entry = iterator.next(); + String key = entry.getKey(); + String value = entry.getValue(); + if (key.startsWith(keyPrefix)) continue; + builder.append("\"" + escapeJson(value.toString()) + "\""); + if (iterator.hasNext()) builder.append(","); + } + + builder.append("]"); + + byte[] bytes = Native.toByteArray(builder.toString()); + Pointer pointer = new Memory(bytes.length + 1); + pointer.write(0, bytes, 0, bytes.length); + pointer.setByte(bytes.length, (byte) 0); + valuesJsonPtr.setPointer(pointer); + return ErrorCode.Success; + } + + @Override + public ErrorCode close(int handle) { + + WalletInmem wallet = this.walletsByHandle.get(handle); + if (wallet == null) return ErrorCode.CommonInvalidState; + + wallet.open = false; + + return ErrorCode.Success; + } + + @Override + public ErrorCode delete(String name, String config, String credentials) { + + if (! this.walletsByName.containsKey(name)) return ErrorCode.CommonInvalidState; + + WalletInmem wallet = new WalletInmem(); + this.walletsByName.remove(name); + this.walletsByHandle.remove(wallet.handle); + + return ErrorCode.Success; + } + + @Override + public ErrorCode free(int walletHandle, Pointer value) { + + Native.free(Pointer.nativeValue(value)); + + return ErrorCode.Success; + } + + private static String escapeJson(String string) { + + return string.replace("\\", "\\\\").replace("\"", "\\\""); + } + + private AtomicInteger atomicInteger = new AtomicInteger(); + private Map walletsByName = new ConcurrentHashMap(); + private Map walletsByHandle = new ConcurrentHashMap(); + + private int newHandle() { + + return Integer.valueOf(atomicInteger.incrementAndGet()); + } + + public void clear() { + this.walletsByName.clear(); + this.walletsByHandle.clear(); + } + + private class WalletInmem { + + private int handle; + private boolean open; + private Map values; + + private WalletInmem() { + + this.handle = WalletTypeInmem.this.newHandle(); + this.open = false; + this.values = new HashMap<>(); + } + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ErrorCodeMatcher.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ErrorCodeMatcher.java new file mode 100644 index 0000000000..a6a7658c63 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ErrorCodeMatcher.java @@ -0,0 +1,22 @@ +package org.hyperledger.indy.sdk; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + +public class ErrorCodeMatcher extends TypeSafeMatcher { + private ErrorCode expectedErrorCode; + + public ErrorCodeMatcher(ErrorCode errorCode) { + this.expectedErrorCode = errorCode; + } + + @Override + protected boolean matchesSafely(IndyException e) { + return expectedErrorCode.equals(e.getErrorCode()); + } + + @Override + public void describeTo(Description description) { + description.appendText("expect ").appendText(expectedErrorCode.name()); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/IndyIntegrationTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/IndyIntegrationTest.java new file mode 100644 index 0000000000..9bb4b356ff --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/IndyIntegrationTest.java @@ -0,0 +1,45 @@ +package org.hyperledger.indy.sdk; + +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.utils.InitHelper; +import org.hyperledger.indy.sdk.utils.StorageUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.rules.ExpectedException; +import org.junit.rules.Timeout; + +import java.io.IOException; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; + +public class IndyIntegrationTest { + + public static final String TRUSTEE_SEED = "000000000000000000000000Trustee1"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Rule + public Timeout globalTimeout = new Timeout(30, TimeUnit.SECONDS); + + @Before + public void setUp() throws IOException { + InitHelper.init(); + StorageUtils.cleanupStorage(); + } + + protected HashSet openedPools = new HashSet<>(); + + @After + public void tearDown() throws IOException { + openedPools.forEach(pool -> { + try { + pool.closePoolLedger(); + } catch (IndyException ignore) { + } + }); + openedPools.clear(); + StorageUtils.cleanupStorage(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/LedgerTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/LedgerTest.java deleted file mode 100644 index 6128de908a..0000000000 --- a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/LedgerTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.hyperledger.indy.sdk; - -import java.io.File; - -import org.hyperledger.indy.sdk.LibIndy; -import org.hyperledger.indy.sdk.ledger.Ledger; -import org.hyperledger.indy.sdk.ledger.LedgerResults.BuildGetDdoRequestResult; -import org.hyperledger.indy.sdk.ledger.LedgerResults.BuildGetNymRequestResult; -import org.hyperledger.indy.sdk.pool.Pool; -import org.hyperledger.indy.sdk.pool.PoolJSONParameters.OpenPoolLedgerJSONParameter; -import org.junit.Assert; - -import junit.framework.TestCase; - -public class LedgerTest extends TestCase { - - private Pool pool; - - @Override - protected void setUp() throws Exception { - - if (! LibIndy.isInitialized()) LibIndy.init(new File("./lib/libindy.so")); - - OpenPoolLedgerJSONParameter openPoolLedgerOptions = new OpenPoolLedgerJSONParameter(null, null, null); - this.pool = Pool.openPoolLedger("myconfig", openPoolLedgerOptions).get().getPool(); - } - - @Override - protected void tearDown() throws Exception { - - this.pool.closePoolLedger(); - } - - public void testLedger() throws Exception { - - BuildGetDdoRequestResult result1 = Ledger.buildGetDdoRequest("did:sov:21tDAKCERh95uGgKbJNHYp", "did:sov:1yvXbmgPoUm4dl66D7KhyD", "{}").get(); - Assert.assertNotNull(result1); - String requestJson1 = result1.getRequestJson(); - Assert.assertNotNull(requestJson1); - - BuildGetNymRequestResult result2 = Ledger.buildGetNymRequest("did:sov:21tDAKCERh95uGgKbJNHYp", "did:sov:1yvXbmgPoUm4dl66D7KhyD").get(); - Assert.assertNotNull(result2); - String requestJson2 = result2.getRequestJson(); - Assert.assertNotNull(requestJson2); - } -} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/PoolTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/PoolTest.java deleted file mode 100644 index 573f83b277..0000000000 --- a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/PoolTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.hyperledger.indy.sdk; - -import java.io.File; -import java.util.concurrent.Future; - -import org.hyperledger.indy.sdk.LibIndy; -import org.hyperledger.indy.sdk.pool.Pool; -import org.hyperledger.indy.sdk.pool.PoolJSONParameters.OpenPoolLedgerJSONParameter; -import org.hyperledger.indy.sdk.pool.PoolResults.OpenPoolLedgerResult; -import org.junit.Assert; - -import junit.framework.TestCase; - -public class PoolTest extends TestCase { - - @Override - protected void setUp() throws Exception { - - if (! LibIndy.isInitialized()) LibIndy.init(new File("./lib/libindy.so")); - } - - @Override - protected void tearDown() throws Exception { - - } - - public void testPool() throws Exception { - -/* CreatePoolLedgerConfigOptions config1 = new CreatePoolLedgerConfigOptions(null); - Future future1 = Pool.createPoolLedgerConfig("myconfig", config1); - CreatePoolLedgerConfigResult result1 = future1.get(); - Assert.assertNotNull(result1);*/ - - OpenPoolLedgerJSONParameter config2 = new OpenPoolLedgerJSONParameter(null, null, null); - Future future2 = Pool.openPoolLedger("myconfig", config2); - OpenPoolLedgerResult result2 = future2.get(); - Assert.assertNotNull(result2); - } -} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/SignusTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/SignusTest.java deleted file mode 100644 index 8a924ef53a..0000000000 --- a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/SignusTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.hyperledger.indy.sdk; - -import java.io.File; -import java.util.concurrent.Future; - -import org.hyperledger.indy.sdk.LibIndy; -import org.hyperledger.indy.sdk.pool.Pool; -import org.hyperledger.indy.sdk.pool.PoolJSONParameters.OpenPoolLedgerJSONParameter; -import org.hyperledger.indy.sdk.signus.Signus; -import org.hyperledger.indy.sdk.signus.SignusResults.CreateAndStoreMyDidResult; -import org.hyperledger.indy.sdk.signus.SignusResults.ReplaceKeysResult; -import org.hyperledger.indy.sdk.wallet.Wallet; -import org.junit.Assert; - -import junit.framework.TestCase; - -public class SignusTest extends TestCase { - - private Pool pool; - private Wallet wallet; - - @Override - protected void setUp() throws Exception { - - if (! LibIndy.isInitialized()) LibIndy.init(new File("./lib/libindy.so")); - - OpenPoolLedgerJSONParameter openPoolLedgerOptions = new OpenPoolLedgerJSONParameter(null, null, null); - this.pool = Pool.openPoolLedger("myconfig", openPoolLedgerOptions).get().getPool(); - this.wallet = Wallet.openWallet("mywallet", null, null).get().getWallet(); - } - - @Override - protected void tearDown() throws Exception { - - this.wallet.closeWallet(); - this.pool.closePoolLedger(); - Wallet.deleteWallet("mywallet", null); - } - - public void testSignus() throws Exception { - - Future future1 = Signus.createAndStoreMyDid(this.wallet, null); - CreateAndStoreMyDidResult result1 = future1.get(); - Assert.assertNotNull(result1); - String did1 = result1.getDid(); - String verkey1 = result1.getVerkey(); - String pk1 = result1.getPk(); - Assert.assertNotNull(did1); - Assert.assertNotNull(verkey1); - Assert.assertNotNull(pk1); - System.out.println(did1); - System.out.println(verkey1); - System.out.println(pk1); - - Future future2 = Signus.replaceKeys(this.wallet, did1, "{}"); - ReplaceKeysResult result2 = future2.get(); - Assert.assertNotNull(result2); - String verkey2 = result2.getVerkey(); - String pk2 = result2.getPk(); - Assert.assertNotNull(verkey2); - Assert.assertNotNull(pk2); - Assert.assertNotEquals(verkey2, verkey1); - } -} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/WalletTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/WalletTest.java deleted file mode 100644 index 2a95da198d..0000000000 --- a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/WalletTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.hyperledger.indy.sdk; - -import java.io.File; - -import org.hyperledger.indy.sdk.LibIndy; -import org.hyperledger.indy.sdk.pool.Pool; -import org.hyperledger.indy.sdk.pool.PoolJSONParameters.OpenPoolLedgerJSONParameter; -import org.hyperledger.indy.sdk.wallet.Wallet; -import org.hyperledger.indy.sdk.wallet.WalletResults.CloseWalletResult; -import org.hyperledger.indy.sdk.wallet.WalletResults.CreateWalletResult; -import org.hyperledger.indy.sdk.wallet.WalletResults.DeleteWalletResult; -import org.hyperledger.indy.sdk.wallet.WalletResults.OpenWalletResult; -import org.junit.Assert; - -import junit.framework.TestCase; - -public class WalletTest extends TestCase { - - private Pool pool; - - @Override - protected void setUp() throws Exception { - - if (! LibIndy.isInitialized()) LibIndy.init(new File("./lib/libindy.so")); - - OpenPoolLedgerJSONParameter openPoolLedgerOptions = new OpenPoolLedgerJSONParameter(null, null, null); - this.pool = Pool.openPoolLedger("myconfig", openPoolLedgerOptions).get().getPool(); - } - - @Override - protected void tearDown() throws Exception { - - this.pool.closePoolLedger(); - } - - public void testWallet() throws Exception { - - Wallet wallet; - - CreateWalletResult result1 = Wallet.createWallet("default", "mywallet", null, null, null).get(); - Assert.assertNotNull(result1); - - OpenWalletResult result2 = Wallet.openWallet("mywallet", null, null).get(); - Assert.assertNotNull(result2); - wallet = result2.getWallet(); - - CloseWalletResult result3 = wallet.closeWallet().get(); - Assert.assertNotNull(result3); - - DeleteWalletResult result4 = Wallet.deleteWallet("mywallet", null).get(); - Assert.assertNotNull(result4); - } -} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentAddIdentityTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentAddIdentityTest.java new file mode 100644 index 0000000000..2697b6831e --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentAddIdentityTest.java @@ -0,0 +1,37 @@ +package org.hyperledger.indy.sdk.agent; + +import org.hyperledger.indy.sdk.agent.Agent.Listener; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.junit.Test; + + +public class AgentAddIdentityTest extends AgentIntegrationTest { + + @Test + public void testAgentAddIdentityWorks() throws Exception { + String endpoint = "127.0.0.1:9701"; + + SignusResults.CreateAndStoreMyDidResult myDid = Signus.createAndStoreMyDid(wallet, "{}").get(); + + Listener activeListener = Agent.agentListen(endpoint, incomingConnectionObserver).get(); + + activeListener.agentAddIdentity(pool, wallet, myDid.getDid()).get(); + } + + @Test + public void testAgentAddIdentityWorksForMultiplyKeys() throws Exception { + String endpoint = "127.0.0.1:9702"; + + SignusResults.CreateAndStoreMyDidResult myDid1 = Signus.createAndStoreMyDid(wallet, "{}").get(); + SignusResults.CreateAndStoreMyDidResult myDid2 = Signus.createAndStoreMyDid(wallet, "{}").get(); + + SignusResults.CreateAndStoreMyDidResult[] dids = {myDid1, myDid2}; + + Listener activeListener = Agent.agentListen(endpoint, incomingConnectionObserver).get(); + + for (SignusResults.CreateAndStoreMyDidResult did : dids) { + activeListener.agentAddIdentity(pool, wallet, did.getDid()).get(); + } + } +} \ No newline at end of file diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentCloseConnectionTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentCloseConnectionTest.java new file mode 100644 index 0000000000..125534b97f --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentCloseConnectionTest.java @@ -0,0 +1,98 @@ +package org.hyperledger.indy.sdk.agent; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.agent.Agent.Connection; +import org.hyperledger.indy.sdk.agent.Agent.Listener; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.junit.Test; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + + +public class AgentCloseConnectionTest extends AgentIntegrationTest { + + private static CompletableFuture serverToClientConnectionFuture = new CompletableFuture(); + + private static final AgentObservers.MessageObserver messageObserver = new AgentObservers.MessageObserver() { + + public void onMessage(Connection connection, String message) { + + System.out.println("Received message '" + message + "' on connection " + connection); + } + }; + + private static final AgentObservers.MessageObserver messageObserverForIncoming = new AgentObservers.MessageObserver() { + + public void onMessage(Connection connection, String message) { + + System.out.println("Received message '" + message + "' on incoming connection " + connection); + } + }; + + private static final AgentObservers.ConnectionObserver incomingConnectionObserver = new AgentObservers.ConnectionObserver() { + + public AgentObservers.MessageObserver onConnection(Listener listener, Connection connection, String senderDid, String receiverDid) { + + System.out.println("New connection " + connection); + + serverToClientConnectionFuture.complete(connection); + + return messageObserverForIncoming; + } + }; + + @Test + public void testAgentCloseConnectionWorksForOutgoing() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String endpoint = "127.0.0.1:9703"; + + SignusResults.CreateAndStoreMyDidResult myDid = Signus.createAndStoreMyDid(wallet, "{}").get(); + + String identityJson = String.format("{\"did\":\"%s\", \"pk\":\"%s\", \"verkey\":\"%s\", \"endpoint\":\"%s\"}", + myDid.getDid(), myDid.getPk(), myDid.getVerkey(), endpoint); + Signus.storeTheirDid(wallet, identityJson).get(); + + Listener activeListener = Agent.agentListen(endpoint, incomingConnectionObserver).get(); + + activeListener.agentAddIdentity(pool, wallet, myDid.getDid()).get(); + + Connection connection = Agent.agentConnect(pool, wallet, myDid.getDid(), myDid.getDid(), messageObserver).get(); + + connection.agentCloseConnection().get(); + + connection.agentSend("msg").get(); + } + + @Test + public void testAgentCloseConnectionWorksForIncoming() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String endpoint = "127.0.0.1:9713"; + + SignusResults.CreateAndStoreMyDidResult myDid = Signus.createAndStoreMyDid(wallet, "{}").get(); + + String identityJson = String.format("{\"did\":\"%s\", \"pk\":\"%s\", \"verkey\":\"%s\", \"endpoint\":\"%s\"}", + myDid.getDid(), myDid.getPk(), myDid.getVerkey(), endpoint); + Signus.storeTheirDid(wallet, identityJson).get(); + + Listener activeListener = Agent.agentListen(endpoint, incomingConnectionObserver).get(); + + activeListener.agentAddIdentity(pool, wallet, myDid.getDid()).get(); + + Agent.agentConnect(pool, wallet, myDid.getDid(), myDid.getDid(), messageObserver).get(); + + Connection serverToClientConnection = serverToClientConnectionFuture.get(); + + serverToClientConnection.agentCloseConnection().get(); + + serverToClientConnection.agentSend("msg").get(); + } +} \ No newline at end of file diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentCloseListenerTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentCloseListenerTest.java new file mode 100644 index 0000000000..b8971c7471 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentCloseListenerTest.java @@ -0,0 +1,73 @@ +package org.hyperledger.indy.sdk.agent; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.agent.Agent.Connection; +import org.hyperledger.indy.sdk.agent.Agent.Listener; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.junit.Test; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + + +public class AgentCloseListenerTest extends AgentIntegrationTest { + + private static CompletableFuture serverToClientConnectionFuture = new CompletableFuture(); + + private static final AgentObservers.MessageObserver messageObserver = new AgentObservers.MessageObserver() { + + public void onMessage(Connection connection, String message) { + + System.out.println("Received message '" + message + "' on connection " + connection); + } + }; + + private static final AgentObservers.MessageObserver messageObserverForIncoming = new AgentObservers.MessageObserver() { + + public void onMessage(Connection connection, String message) { + + System.out.println("Received message '" + message + "' on incoming connection " + connection); + } + }; + + private static final AgentObservers.ConnectionObserver incomingConnectionObserver = new AgentObservers.ConnectionObserver() { + + public AgentObservers.MessageObserver onConnection(Listener listener, Connection connection, String senderDid, String receiverDid) { + + System.out.println("New connection " + connection); + + serverToClientConnectionFuture.complete(connection); + + return messageObserverForIncoming; + } + }; + + @Test + public void testAgentCloseConnectionWorksForOutgoing() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String endpoint = "127.0.0.1:9704"; + + SignusResults.CreateAndStoreMyDidResult myDid = Signus.createAndStoreMyDid(wallet, "{}").get(); + + String identityJson = String.format("{\"did\":\"%s\", \"pk\":\"%s\", \"verkey\":\"%s\", \"endpoint\":\"%s\"}", + myDid.getDid(), myDid.getPk(), myDid.getVerkey(), endpoint); + Signus.storeTheirDid(wallet, identityJson).get(); + + Listener activeListener = Agent.agentListen(endpoint, incomingConnectionObserver).get(); + + activeListener.agentAddIdentity(pool, wallet, myDid.getDid()).get(); + + Agent.agentConnect(pool, wallet, myDid.getDid(), myDid.getDid(), messageObserver).get(); + + Connection serverToClientConnection = serverToClientConnectionFuture.get(); + + activeListener.agentCloseListener().get(); + + serverToClientConnection.agentSend("msg").get(); + } +} \ No newline at end of file diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentConnectTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentConnectTest.java new file mode 100644 index 0000000000..8e0606938c --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentConnectTest.java @@ -0,0 +1,77 @@ +package org.hyperledger.indy.sdk.agent; + +import org.hyperledger.indy.sdk.agent.Agent.Listener; +import org.hyperledger.indy.sdk.ledger.Ledger; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusJSONParameters; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.junit.Test; + +import static org.hyperledger.indy.sdk.IndyIntegrationTest.TRUSTEE_SEED; + + +public class AgentConnectTest extends AgentIntegrationTest { + + @Test + public void testAgentConnectWorksForRemoteData() throws Exception { + String endpoint = "127.0.0.1:9705"; + String listenerWalletName = "listenerWallet"; + String trusteeWalletName = "trusteeWallet"; + + Wallet.createWallet(poolName, listenerWalletName, "default", null, null).get(); + Wallet listenerWallet = Wallet.openWallet(listenerWalletName, null, null).get(); + + Wallet.createWallet(poolName, trusteeWalletName, "default", null, null).get(); + Wallet trusteeWallet = Wallet.openWallet(trusteeWalletName, null, null).get(); + Wallet senderWallet = trusteeWallet; + + SignusResults.CreateAndStoreMyDidResult createMyDidResult = Signus.createAndStoreMyDid(listenerWallet, "{}").get(); + String listenerDid = createMyDidResult.getDid(); + String listenerVerkey = createMyDidResult.getVerkey(); + String listenerPk = createMyDidResult.getPk(); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(trusteeWallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + String senderDid = trusteeDid; + + String nymRequest = Ledger.buildNymRequest(trusteeDid, listenerDid, listenerVerkey, null, null).get(); + Ledger.signAndSubmitRequest(pool, trusteeWallet, trusteeDid, nymRequest).get(); + + String attribRequest = Ledger.buildAttribRequest(listenerDid, listenerDid, null, + String.format("{\"endpoint\":{\"ha\":\"%s\",\"verkey\":\"%s\"}}", endpoint, listenerPk), null).get(); + Ledger.signAndSubmitRequest(pool, listenerWallet, listenerDid, attribRequest).get(); + + Listener activeListener = Agent.agentListen(endpoint, incomingConnectionObserver).get(); + + activeListener.agentAddIdentity(pool, listenerWallet, listenerDid).get(); + + Agent.agentConnect(pool, senderWallet, senderDid, listenerDid, messageObserver).get(); + + listenerWallet.closeWallet().get(); + Wallet.deleteWallet(listenerWalletName, null).get(); + + trusteeWallet.closeWallet().get(); + Wallet.deleteWallet(trusteeWalletName, null).get(); + } + + @Test + public void testAgentConnectWorksForAllDataInWalletPresent() throws Exception { + String endpoint = "127.0.0.1:9706"; + + SignusResults.CreateAndStoreMyDidResult myDid = Signus.createAndStoreMyDid(wallet, "{}").get(); + + String identityJson = String.format("{\"did\":\"%s\", \"pk\":\"%s\", \"verkey\":\"%s\", \"endpoint\":\"%s\"}", + myDid.getDid(), myDid.getPk(), myDid.getVerkey(), endpoint); + Signus.storeTheirDid(wallet, identityJson).get(); + + Listener activeListener = Agent.agentListen(endpoint, incomingConnectionObserver).get(); + + activeListener.agentAddIdentity(pool, wallet, myDid.getDid()).get(); + + Agent.agentConnect(pool, wallet, myDid.getDid(), myDid.getDid(), messageObserver).get(); + } +} \ No newline at end of file diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentIntegrationTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentIntegrationTest.java new file mode 100644 index 0000000000..d4c2879bed --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentIntegrationTest.java @@ -0,0 +1,89 @@ +package org.hyperledger.indy.sdk.agent; + +import org.hyperledger.indy.sdk.agent.Agent.Connection; +import org.hyperledger.indy.sdk.agent.Agent.Listener; +import org.hyperledger.indy.sdk.agent.AgentObservers.ConnectionObserver; +import org.hyperledger.indy.sdk.agent.AgentObservers.MessageObserver; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.pool.PoolJSONParameters; +import org.hyperledger.indy.sdk.utils.InitHelper; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.utils.StorageUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.rules.ExpectedException; +import org.junit.rules.Timeout; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + + +public class AgentIntegrationTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Rule + public Timeout globalTimeout = new Timeout(1, TimeUnit.MINUTES); + + static Wallet wallet; + static Pool pool; + String poolName; + private String walletName = "agentWallet"; + + @BeforeClass + public static void init() throws Exception { + InitHelper.init(); + } + + @Before + public void setUp() throws Exception { + StorageUtils.cleanupStorage(); + + poolName = PoolUtils.createPoolLedgerConfig(); + + PoolJSONParameters.OpenPoolLedgerJSONParameter config2 = new PoolJSONParameters.OpenPoolLedgerJSONParameter(null, null, null); + pool = Pool.openPoolLedger(poolName, config2.toJson()).get(); + + Wallet.createWallet(poolName, walletName, "default", null, null).get(); + wallet = Wallet.openWallet(walletName, null, null).get(); + } + + @After + public void tearDown() throws Exception { + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + + pool.closePoolLedger().get(); + StorageUtils.cleanupStorage(); + } + + static final AgentObservers.MessageObserver messageObserver = new AgentObservers.MessageObserver() { + + public void onMessage(Connection connection, String message) { + + System.out.println("Received message '" + message + "' on connection " + connection); + } + }; + + private static final AgentObservers.MessageObserver messageObserverForIncoming = new AgentObservers.MessageObserver() { + + public void onMessage(Connection connection, String message) { + + System.out.println("Received message '" + message + "' on incoming connection " + connection); + } + }; + + static final AgentObservers.ConnectionObserver incomingConnectionObserver = new AgentObservers.ConnectionObserver() { + + public AgentObservers.MessageObserver onConnection(Listener listener, Connection connection, String senderDid, String receiverDid) { + + System.out.println("New connection " + connection); + + return messageObserverForIncoming; + } + }; +} \ No newline at end of file diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentListenTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentListenTest.java new file mode 100644 index 0000000000..2da18da83b --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentListenTest.java @@ -0,0 +1,26 @@ +package org.hyperledger.indy.sdk.agent; + +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusJSONParameters; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.junit.Test; + + +public class AgentListenTest extends AgentIntegrationTest { + + @Test + public void testAgentListenWorksForAllDataInWalletPresent() throws Exception { + String endpoint = "127.0.0.1:9707"; + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, "sovrin_agent_connect_works_for_a", null, null); + + SignusResults.CreateAndStoreMyDidResult myDid = Signus.createAndStoreMyDid(wallet, didJson.toJson()).get(); + + String identityJson = String.format("{\"did\":\"%s\", \"pk\":\"%s\", \"verkey\":\"%s\", \"endpoint\":\"%s\"}", + myDid.getDid(), myDid.getPk(), myDid.getVerkey(), endpoint); + Signus.storeTheirDid(wallet, identityJson).get(); + + Agent.agentListen(endpoint, incomingConnectionObserver).get(); + } +} \ No newline at end of file diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentRemoveIdentityTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentRemoveIdentityTest.java new file mode 100644 index 0000000000..0231602d5e --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentRemoveIdentityTest.java @@ -0,0 +1,23 @@ +package org.hyperledger.indy.sdk.agent; + +import org.hyperledger.indy.sdk.agent.Agent.Listener; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.junit.Test; + + +public class AgentRemoveIdentityTest extends AgentIntegrationTest { + + @Test + public void testAgentRemoveIdentityWorks() throws Exception { + String endpoint = "127.0.0.1:9708"; + + SignusResults.CreateAndStoreMyDidResult myDid = Signus.createAndStoreMyDid(wallet, "{}").get(); + + Listener activeListener = Agent.agentListen(endpoint, incomingConnectionObserver).get(); + + activeListener.agentAddIdentity(pool, wallet, myDid.getDid()).get(); + + activeListener.agentRemoveIdentity(wallet, myDid.getDid()).get(); + } +} \ No newline at end of file diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentSendTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentSendTest.java new file mode 100644 index 0000000000..bdf1defcca --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/agent/AgentSendTest.java @@ -0,0 +1,79 @@ +package org.hyperledger.indy.sdk.agent; + +import org.hyperledger.indy.sdk.agent.Agent.Connection; +import org.hyperledger.indy.sdk.agent.Agent.Listener; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.junit.Test; + +import java.util.concurrent.CompletableFuture; + +import static org.junit.Assert.assertEquals; + +public class AgentSendTest extends AgentIntegrationTest { + + private static CompletableFuture serverToClientConnectionFuture = new CompletableFuture(); + private static CompletableFuture serverToClientMsgFuture = new CompletableFuture(); + private static CompletableFuture clientToServerMsgFuture = new CompletableFuture(); + + private static final AgentObservers.MessageObserver messageObserver = new AgentObservers.MessageObserver() { + + public void onMessage(Connection connection, String message) { + + System.out.println("Received message '" + message + "' on connection " + connection); + + serverToClientMsgFuture.complete(message); + } + }; + + private static final AgentObservers.MessageObserver messageObserverForIncoming = new AgentObservers.MessageObserver() { + + public void onMessage(Connection connection, String message) { + + System.out.println("Received message '" + message + "' on incoming connection " + connection); + + clientToServerMsgFuture.complete(message); + } + }; + + private static final AgentObservers.ConnectionObserver incomingConnectionObserver = new AgentObservers.ConnectionObserver() { + + public AgentObservers.MessageObserver onConnection(Listener listener, Connection connection, String senderDid, String receiverDid) { + + System.out.println("New connection " + connection); + + serverToClientConnectionFuture.complete(connection); + + return messageObserverForIncoming; + } + }; + + @Test + public void testAgentSendWorksForAllDataInWalletPresent() throws Exception { + String endpoint = "127.0.0.1:9709"; + + SignusResults.CreateAndStoreMyDidResult myDid = Signus.createAndStoreMyDid(wallet, "{}").get(); + + String identityJson = String.format("{\"did\":\"%s\", \"pk\":\"%s\", \"verkey\":\"%s\", \"endpoint\":\"%s\"}", + myDid.getDid(), myDid.getPk(), myDid.getVerkey(), endpoint); + Signus.storeTheirDid(wallet, identityJson).get(); + + Listener activeListener = Agent.agentListen(endpoint, incomingConnectionObserver).get(); + + activeListener.agentAddIdentity(pool, wallet, myDid.getDid()).get(); + + Connection clientToServerConnection = Agent.agentConnect(pool, wallet, myDid.getDid(), myDid.getDid(), messageObserver).get(); + + String clientToServerMessage = "msg_from_client"; + String serverToClientMessage = "msg_from_server"; + + clientToServerConnection.agentSend(clientToServerMessage).get(); + + assertEquals(clientToServerMessage, clientToServerMsgFuture.get()); + + Connection serverToClientConnection = serverToClientConnectionFuture.get(); + serverToClientConnection.agentSend(serverToClientMessage).get(); + + assertEquals(serverToClientMessage, serverToClientMsgFuture.get()); + } +} \ No newline at end of file diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/AnoncredsIntegrationTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/AnoncredsIntegrationTest.java new file mode 100644 index 0000000000..4dcce1ddf4 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/AnoncredsIntegrationTest.java @@ -0,0 +1,80 @@ +package org.hyperledger.indy.sdk.anoncreds; + +import org.hyperledger.indy.sdk.utils.InitHelper; +import org.hyperledger.indy.sdk.utils.StorageUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.junit.*; +import org.junit.rules.ExpectedException; +import org.junit.rules.Timeout; + +import java.util.concurrent.TimeUnit; + +public class AnoncredsIntegrationTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Rule + public Timeout globalTimeout = new Timeout(1, TimeUnit.MINUTES); + + static Wallet wallet; + static String claimDef; + + private static Boolean walletOpened = false; + + String masterSecretName = "master_secret_name"; + String issuerDid = "NcYxiDXkpYi6ov5FcYDi1e"; + String issuerDid2 = "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW"; + String proverDid = "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW"; + String claimOfferTemplate = "{\"issuer_did\":\"%s\",\"schema_seq_no\":%d}"; + String schema = "{\"seqNo\":1,\"data\": {\"name\":\"gvt\",\"version\":\"1.0\",\"keys\":[\"age\",\"sex\",\"height\",\"name\"]}}"; + String claimRequestTemplate = "{\"blinded_ms\":" + + "{\"prover_did\":\"CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW\"," + + "\"u\":\"54172737564529332710724213139048941083013176891644677117322321823630308734620627329227591845094100636256829761959157314784293939045176621327154990908459072821826818718739696323299787928173535529024556540323709578850706993294234966440826690899266872682790228513973999212370574548239877108511283629423807338632435431097339875665075453785141722989098387895970395982432709011505864533727415552566715069675346220752584449560407261446567731711814188836703337365986725429656195275616846543535707364215498980750860746440672050640048215761507774996460985293327604627646056062013419674090094698841792968543317468164175921100038\"," + + "\"ur\":null}," + + "\"issuer_did\":\"%s\",\"schema_seq_no\":%d}"; + + @BeforeClass + public static void setUp() throws Exception{ + InitHelper.init(); + } + + void initCommonWallet() throws Exception { + + if (walletOpened) { + return; + } + + StorageUtils.cleanupStorage(); + + String walletName = "anoncredsCommonWallet"; + + Wallet.createWallet("default", walletName, "default", null, null).get(); + wallet = Wallet.openWallet(walletName, null, null).get(); + + claimDef = Anoncreds.issuerCreateAndStoreClaimDef(wallet, issuerDid, schema, null, false).get(); + + Anoncreds.proverStoreClaimOffer(wallet, String.format(claimOfferTemplate, issuerDid, 1)).get(); + Anoncreds.proverStoreClaimOffer(wallet, String.format(claimOfferTemplate, issuerDid, 2)).get(); + Anoncreds.proverStoreClaimOffer(wallet, String.format(claimOfferTemplate, issuerDid2, 2)).get(); + + Anoncreds.proverCreateMasterSecret(wallet, masterSecretName).get(); + + String claimOffer = String.format("{\"issuer_did\":\"%s\",\"schema_seq_no\":%d}", issuerDid, 1); + + String claimRequest = Anoncreds.proverCreateClaimReq(wallet, "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW", claimOffer, claimDef, masterSecretName).get(); + + String claim = "{\"sex\":[\"male\",\"5944657099558967239210949258394887428692050081607692519917050011144233115103\"],\n" + + " \"name\":[\"Alex\",\"1139481716457488690172217916278103335\"],\n" + + " \"height\":[\"175\",\"175\"],\n" + + " \"age\":[\"28\",\"28\"]\n" + + " }"; + + AnoncredsResults.IssuerCreateClaimResult createClaimResult = Anoncreds.issuerCreateClaim(wallet, claimRequest, claim, - 1, - 1).get(); + String claimJson = createClaimResult.getClaimJson(); + + Anoncreds.proverStoreClaim(wallet, claimJson).get(); + + walletOpened = true; + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/IssuerCreateAndStoreClaimDefinitionTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/IssuerCreateAndStoreClaimDefinitionTest.java new file mode 100644 index 0000000000..aabf38ebce --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/IssuerCreateAndStoreClaimDefinitionTest.java @@ -0,0 +1,116 @@ +package org.hyperledger.indy.sdk.anoncreds; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.wallet.Wallet; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.json.*; + +import java.util.concurrent.ExecutionException; + +public class IssuerCreateAndStoreClaimDefinitionTest extends AnoncredsIntegrationTest { + + private Wallet wallet; + private String walletName = "createAndStoreClaimDefWallet"; + + @Before + public void createWallet() throws Exception { + Wallet.createWallet("default", walletName, "default", null, null).get(); + wallet = Wallet.openWallet(walletName, null, null).get(); + } + + @After + public void deleteWallet() throws Exception { + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + private String issuerDid = "NcYxiDXkpYi6ov5FcYDi1e"; + private String gvtSchemaJson = "{\n" + + " \"seqNo\":1,\n" + + " \"data\": {\n" + + " \"name\":\"gvt\",\n" + + " \"version\":\"1.0\",\n" + + " \"keys\":[\"age\",\"sex\",\"height\",\"name\"]\n" + + " }\n" + + " }"; + + @Test + public void testIssuerCreateAndStoreClaimDefWorks() throws Exception { + + String claimDef = Anoncreds.issuerCreateAndStoreClaimDef(wallet, issuerDid, gvtSchemaJson, null, false).get(); + assertNotNull(claimDef); + + JSONObject claimDefObject = new JSONObject(claimDef); + JSONObject primary = claimDefObject.getJSONObject("data").getJSONObject("primary"); + + assertEquals(4, primary.getJSONObject("r").length()); + assertTrue(primary.getString("n").length() > 0); + assertTrue(primary.getString("s").length() > 0); + assertTrue(primary.getString("z").length() > 0); + assertTrue(primary.getString("rms").length() > 0); + assertTrue(primary.getString("rctxt").length() > 0); + } + + @Test + public void testIssuerCreateAndStoreClaimDefWorksForInvalidSchemaJson() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String schema = "{\"seqNo\":1, \"name\":\"name\",\"version\":\"1.0\", \"keys\":[\"name\"]}"; + + Anoncreds.issuerCreateAndStoreClaimDef(wallet, issuerDid, schema, null, false).get(); + } + + @Test + public void testIssuerCreateAndStoreClaimDefWorksForEmptyKeys() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String schema = "{\n" + + " \"seqNo\":1,\n" + + " \"data\": {\n" + + " \"name\":\"gvt\",\n" + + " \"version\":\"1.0\",\n" + + " \"keys\":[]\n" + + " }\n" + + " }"; + + Anoncreds.issuerCreateAndStoreClaimDef(wallet, issuerDid, schema, null, false).get(); + } + + @Test + public void testIssuerCreateAndStoreClaimDefWorksForCorrectCryptoType() throws Exception { + + String claimDef = Anoncreds.issuerCreateAndStoreClaimDef(wallet, issuerDid, gvtSchemaJson, "CL", false).get(); + assertNotNull(claimDef); + + JSONObject claimDefObject = new JSONObject(claimDef); + JSONObject primary = claimDefObject.getJSONObject("data").getJSONObject("primary"); + + assertEquals(4, primary.getJSONObject("r").length()); + assertTrue(primary.getString("n").length() > 0); + assertTrue(primary.getString("s").length() > 0); + assertTrue(primary.getString("z").length() > 0); + assertTrue(primary.getString("rms").length() > 0); + assertTrue(primary.getString("rctxt").length() > 0); + } + + @Test + public void testIssuerCreateAndStoreClaimDefWorksForInvalidCryptoType() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + Anoncreds.issuerCreateAndStoreClaimDef(wallet, issuerDid, gvtSchemaJson, "type", false).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/IssuerCreateClaimTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/IssuerCreateClaimTest.java new file mode 100644 index 0000000000..941813c5e9 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/IssuerCreateClaimTest.java @@ -0,0 +1,77 @@ +package org.hyperledger.indy.sdk.anoncreds; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.json.JSONObject; +import org.junit.*; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class IssuerCreateClaimTest extends AnoncredsIntegrationTest { + + @Test + public void testIssuerCreateClaimWorks() throws Exception { + + initCommonWallet(); + + String claimRequest = String.format(claimRequestTemplate, issuerDid, 1); + + String claim = "{\"sex\":[\"male\",\"5944657099558967239210949258394887428692050081607692519917050011144233115103\"],\n" + + " \"name\":[\"Alex\",\"1139481716457488690172217916278103335\"],\n" + + " \"height\":[\"175\",\"175\"],\n" + + " \"age\":[\"28\",\"28\"]\n" + + " }"; + + AnoncredsResults.IssuerCreateClaimResult createClaimResult = Anoncreds.issuerCreateClaim(wallet, claimRequest, claim, - 1, - 1).get(); + assertNotNull(createClaimResult); + String claimJson = createClaimResult.getClaimJson(); + + JSONObject claimObj = new JSONObject(claimJson); + + JSONObject primaryClaim = claimObj.getJSONObject("signature").getJSONObject("primary_claim"); + + assertTrue(primaryClaim.getString("a").length() > 0); + assertTrue(primaryClaim.getString("m2").length() > 0); + assertTrue(primaryClaim.getString("e").length() > 0); + assertTrue(primaryClaim.getString("v").length() > 0); + } + + @Test + public void testIssuerCreateClaimWorksForClaimDoesNotCorrespondToClaimRequest() throws Exception { + + initCommonWallet(); + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String claimRequest = String.format(claimRequestTemplate, issuerDid, 1); + + String claim = "{\"status\":[\"partial\",\"51792877103171595686471452153480627530895\"],\n" + + " \"period\":[\"8\",\"8\"]\n" + + " }"; + + Anoncreds.issuerCreateClaim(wallet, claimRequest, claim, - 1, - 1).get(); + } + + @Test + public void testIssuerCreateClaimWorksForInvalidClaim() throws Exception { + + initCommonWallet(); + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String claimRequest = String.format(claimRequestTemplate, issuerDid, 1); + + String claim = "{\"sex\":\"male\",\n" + + " \"name\":\"Alex\",\n" + + " \"height\":\"175\",\n" + + " \"age\":\"28\"" + + " }"; + + Anoncreds.issuerCreateClaim(wallet, claimRequest, claim, - 1, - 1).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverCreateAndStoreClaimReqTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverCreateAndStoreClaimReqTest.java new file mode 100644 index 0000000000..6c18116718 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverCreateAndStoreClaimReqTest.java @@ -0,0 +1,72 @@ +package org.hyperledger.indy.sdk.anoncreds; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +public class ProverCreateAndStoreClaimReqTest extends AnoncredsIntegrationTest { + + @Test + public void testProverCreateAndStoreClaimReqWorks() throws Exception { + + initCommonWallet(); + + String claimOffer = String.format(claimOfferTemplate, issuerDid, 1); + + Anoncreds.proverCreateClaimReq(wallet, proverDid, claimOffer, claimDef, masterSecretName).get(); + } + + @Test + public void testProverCreateAndStoreClaimReqWorksForClaimDefDoesNotCorrespondToClaimOfferDifferentIssuer() throws Exception { + + initCommonWallet(); + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String claimOffer = String.format(claimOfferTemplate, "acWziYqKpYi6ov5FcYDi1e3", 1); + + Anoncreds.proverCreateClaimReq(wallet, proverDid, claimOffer, claimDef, masterSecretName).get(); + } + + @Test + public void testProverCreateAndStoreClaimReqWorksForClaimDefDoesNotCorrespondToClaimOfferDifferentSchema() throws Exception { + + initCommonWallet(); + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String claimOffer = String.format(claimOfferTemplate, issuerDid, 2); + + Anoncreds.proverCreateClaimReq(wallet, proverDid, claimOffer, claimDef, masterSecretName).get(); + } + + @Test + public void testProverCreateAndStoreClaimReqWorksForInvalidClaimOffer() throws Exception { + + initCommonWallet(); + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String claimOffer = String.format("{\"issuer_did\":\"%s\"}", issuerDid); + + Anoncreds.proverCreateClaimReq(wallet, proverDid, claimOffer, claimDef, masterSecretName).get(); + } + + @Test + public void testProverCreateAndStoreClaimReqWorksForInvalidMasterSecret() throws Exception { + + initCommonWallet(); + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.WalletNotFoundError)); + + String claimOffer = String.format(claimOfferTemplate, issuerDid, 1); + + Anoncreds.proverCreateClaimReq(wallet, proverDid, claimOffer, claimDef, "other_master_secret").get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverCreateMasterSecretTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverCreateMasterSecretTest.java new file mode 100644 index 0000000000..eee5db6465 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverCreateMasterSecretTest.java @@ -0,0 +1,54 @@ +package org.hyperledger.indy.sdk.anoncreds; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +public class ProverCreateMasterSecretTest extends AnoncredsIntegrationTest { + + private Wallet wallet; + private String walletName = "createMasterSecretWallet"; + + @Before + public void createWallet() throws Exception { + Wallet.createWallet("default", walletName, "default", null, null).get(); + this.wallet = Wallet.openWallet(walletName, null, null).get(); + } + + @After + public void deleteWallet() throws Exception { + this.wallet.closeWallet(); + Wallet.deleteWallet(walletName, null); + } + + @Test + public void testProverCreateMasterSecretWorks() throws Exception { + + Anoncreds.proverCreateMasterSecret(wallet, "master_secret_name").get(); + } + + @Test + public void testProverCreateMasterSecretWorksForDuplicate() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.AnoncredsMasterSecretDuplicateNameError)); + + String masterSecretName = "master_secret_name_duplicate"; + Anoncreds.proverCreateMasterSecret(wallet, masterSecretName).get(); + Anoncreds.proverCreateMasterSecret(wallet, masterSecretName).get(); + } + + @Test + public void testProverCreateMasterSecretWorksForEmptyName() throws Exception { + + thrown.expect(new ErrorCodeMatcher(ErrorCode.CommonInvalidParam3)); + + Anoncreds.proverCreateMasterSecret(wallet, "").get(); + + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverCreateProofTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverCreateProofTest.java new file mode 100644 index 0000000000..1e05c36860 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverCreateProofTest.java @@ -0,0 +1,189 @@ +package org.hyperledger.indy.sdk.anoncreds; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.json.JSONArray; +import org.json.JSONObject; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertNotNull; + +public class ProverCreateProofTest extends AnoncredsIntegrationTest { + + @Test + public void testProverCreateProofWorks() throws Exception { + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1, \"name\":\"name\"}},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}}\n" + + " }"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + JSONObject claimForAttribute = claims.getJSONObject("attrs").getJSONArray("attr1_uuid").getJSONObject(0); + + String claimUuid = claimForAttribute.getString("claim_uuid"); + + String requestedClaimsJson = String.format("{\n" + + " \"self_attested_attributes\":{},\n" + + " \"requested_attrs\":{\"attr1_uuid\":[\"%s\", true]},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":\"%s\"}\n" + + " }", claimUuid, claimUuid); + + String schemasJson = String.format("{\"%s\":%s}", claimUuid, schema); + String claimDefsJson = String.format("{\"%s\":%s}", claimUuid, claimDef); + String revocRegsJson = "{}"; + + String proofJson = Anoncreds.proverCreateProof(wallet, proofRequest, requestedClaimsJson, schemasJson, + masterSecretName, claimDefsJson, revocRegsJson).get(); + assertNotNull(proofJson); + } + + @Test + public void testProverCreateProofWorksForUsingNotSatisfyClaim() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + initCommonWallet(); + + String claimsJson = Anoncreds.proverGetClaims(wallet, "{}").get(); + + JSONArray claims = new JSONArray(claimsJson); + + String claimUuid = claims.getJSONObject(0).getString("claim_uuid"); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1, \"name\":\"some_attr\"}},\n" + + " \"requested_predicates\":{}\n" + + " }"; + + String requestedClaimsJson = String.format("{\"self_attested_attributes\":{},\n" + + " \"requested_attrs\":{\"attr1_uuid\":[\"%s\", true]},\n" + + " \"requested_predicates\":{}\n" + + " }", claimUuid); + + String schemasJson = String.format("{\"%s\":%s}", claimUuid, schema); + String claimDefsJson = String.format("{\"%s\":%s}", claimUuid, claimDef); + String revocRegsJson = "{}"; + + Anoncreds.proverCreateProof(wallet, proofRequest, requestedClaimsJson, schemasJson, + masterSecretName, claimDefsJson, revocRegsJson).get(); + } + + @Test + public void testProverCreateProofWorksForInvalidMasterSecret() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.WalletNotFoundError)); + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1, \"name\":\"name\"}},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}}\n" + + " }"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + JSONObject claimForAttribute = claims.getJSONObject("attrs").getJSONArray("attr1_uuid").getJSONObject(0); + + String claimUuid = claimForAttribute.getString("claim_uuid"); + + String requestedClaimsJson = String.format("{\n" + + " \"self_attested_attributes\":{},\n" + + " \"requested_attrs\":{\"attr1_uuid\":[\"%s\", true]},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":\"%s\"}\n" + + " }", claimUuid, claimUuid); + + String schemasJson = String.format("{\"%s\":%s}", claimUuid, schema); + String claimDefsJson = String.format("{\"%s\":%s}", claimUuid, claimDef); + String revocRegsJson = "{}"; + + Anoncreds.proverCreateProof(wallet, proofRequest, requestedClaimsJson, schemasJson, "wrong_master_secret", claimDefsJson, revocRegsJson).get(); + } + + @Test + public void testProverCreateProofWorksForInvalidSchemas() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1, \"name\":\"name\"}},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}}\n" + + " }"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + JSONObject claimForAttribute = claims.getJSONObject("attrs").getJSONArray("attr1_uuid").getJSONObject(0); + + String claimUuid = claimForAttribute.getString("claim_uuid"); + + String requestedClaimsJson = String.format("{\n" + + " \"self_attested_attributes\":{},\n" + + " \"requested_attrs\":{\"attr1_uuid\":[\"%s\", true]},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":\"%s\"}\n" + + " }", claimUuid, claimUuid); + + String schemasJson = "{}"; + String claimDefsJson = String.format("{\"%s\":%s}", claimUuid, claimDef); + String revocRegsJson = "{}"; + + Anoncreds.proverCreateProof(wallet, proofRequest, requestedClaimsJson, schemasJson, masterSecretName, claimDefsJson, revocRegsJson).get(); + } + + @Test + public void testProverCreateProofWorksForInvalidRequestedClaimsJson() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1, \"name\":\"name\"}},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}}\n" + + " }"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + JSONObject claimForAttribute = claims.getJSONObject("attrs").getJSONArray("attr1_uuid").getJSONObject(0); + + String claimUuid = claimForAttribute.getString("claim_uuid"); + + String requestedClaimsJson = "{\"self_attested_attributes\":{},\n" + + " \"requested_predicates\":{}\n" + + " }"; + + String schemasJson = String.format("{\"%s\":%s}", claimUuid, schema); + String claimDefsJson = String.format("{\"%s\":%s}", claimUuid, claimDef); + String revocRegsJson = "{}"; + + Anoncreds.proverCreateProof(wallet, proofRequest, requestedClaimsJson, schemasJson, masterSecretName, claimDefsJson, revocRegsJson).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverGetClaimOfferTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverGetClaimOfferTest.java new file mode 100644 index 0000000000..4b49e02b68 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverGetClaimOfferTest.java @@ -0,0 +1,98 @@ +package org.hyperledger.indy.sdk.anoncreds; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.json.JSONArray; +import org.junit.*; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class ProverGetClaimOfferTest extends AnoncredsIntegrationTest { + + @Test + public void testsProverGetClaimOffersWorksForEmptyFilter() throws Exception { + + initCommonWallet(); + + String claimOffers = Anoncreds.proverGetClaimOffers(wallet, "{}").get(); + JSONArray claimOffersArray = new JSONArray(claimOffers); + + assertEquals(3, claimOffersArray.length()); + } + + @Test + public void testsProverGetClaimOffersWorksForFilterByIssuer() throws Exception { + + initCommonWallet(); + + String filter = String.format("{\"issuer_did\":\"%s\"}", issuerDid); + + String claimOffers = Anoncreds.proverGetClaimOffers(wallet, filter).get(); + JSONArray claimOffersArray = new JSONArray(claimOffers); + + assertEquals(2, claimOffersArray.length()); + + assertTrue(claimOffersArray.toString().contains(String.format(claimOfferTemplate, issuerDid, 1))); + assertTrue(claimOffersArray.toString().contains(String.format(claimOfferTemplate, issuerDid, 2))); + } + + @Test + public void testsProverGetClaimOffersWorksForFilterBySchema() throws Exception { + + initCommonWallet(); + + String filter = String.format("{\"schema_seq_no\":%d}", 2); + + String claimOffers = Anoncreds.proverGetClaimOffers(wallet, filter).get(); + JSONArray claimOffersArray = new JSONArray(claimOffers); + + assertEquals(2, claimOffersArray.length()); + + assertTrue(claimOffersArray.toString().contains(String.format(claimOfferTemplate, issuerDid, 2))); + assertTrue(claimOffersArray.toString().contains(String.format(claimOfferTemplate, issuerDid2, 2))); + } + + @Test + public void testsProverGetClaimOffersWorksForFilterByIssuerAndSchema() throws Exception { + + initCommonWallet(); + + String filter = String.format("{\"issuer_did\":\"%s\",\"schema_seq_no\":%d}", issuerDid, 1); + + String claimOffers = Anoncreds.proverGetClaimOffers(wallet, filter).get(); + JSONArray claimOffersArray = new JSONArray(claimOffers); + + assertEquals(1, claimOffersArray.length()); + + assertTrue(claimOffersArray.toString().contains(String.format(claimOfferTemplate, issuerDid, 1))); + } + + @Test + public void testsProverGetClaimOffersWorksForNoResult() throws Exception { + + initCommonWallet(); + + String filter = String.format("{\"schema_seq_no\":%d}", 3); + + String claimOffers = Anoncreds.proverGetClaimOffers(wallet, filter).get(); + JSONArray claimOffersArray = new JSONArray(claimOffers); + + assertEquals(0, claimOffersArray.length()); + } + + @Test + public void testsProverGetClaimOffersWorksForInvalidFilterJson() throws Exception { + + initCommonWallet(); + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String filter = String.format("{\"schema_seq_no\":\"%d\"}", 1); + + Anoncreds.proverGetClaimOffers(wallet, filter).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverGetClaimsForProofRequestTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverGetClaimsForProofRequestTest.java new file mode 100644 index 0000000000..ba0dd0fc26 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverGetClaimsForProofRequestTest.java @@ -0,0 +1,243 @@ +package org.hyperledger.indy.sdk.anoncreds; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.json.JSONArray; +import org.json.JSONObject; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertEquals; + +public class ProverGetClaimsForProofRequestTest extends AnoncredsIntegrationTest { + + @Test + public void testProverGetClaimsForProofRequestWorksForRevealedAttribute() throws Exception { + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1, \"name\":\"name\"}},\n" + + " \"requested_predicates\":{}\n" + + " }"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + JSONArray claimsForAttribute1 = claims.getJSONObject("attrs").getJSONArray("attr1_uuid"); + assertEquals(1, claimsForAttribute1.length()); + } + + @Test + public void testProverGetClaimsForProofRequestWorksForNotFoundAttribute() throws Exception { + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1, \"name\":\"attribute\"}},\n" + + " \"requested_predicates\":{}\n" + + " }"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + JSONArray claimsForAttribute1 = claims.getJSONObject("attrs").getJSONArray("attr1_uuid"); + assertEquals(0, claimsForAttribute1.length()); + } + + @Test + public void testProverGetClaimsForProofRequestWorksForSatisfyPredicate() throws Exception { + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}}\n" + + " }"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + JSONArray claimsForPredicate = claims.getJSONObject("predicates").getJSONArray("predicate1_uuid"); + assertEquals(1, claimsForPredicate.length()); + } + + @Test + public void testProverGetClaimsForProofRequestWorksForNotSatisfyPredicate() throws Exception { + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":58}}\n" + + " }"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + JSONArray claimsForPredicate = claims.getJSONObject("predicates").getJSONArray("predicate1_uuid"); + assertEquals(0, claimsForPredicate.length()); + } + + @Test + public void testProverGetClaimsForProofRequestWorksForMultiplyAttributesAndPredicates() throws Exception { + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\n" + + " \"attr1_uuid\":{\"schema_seq_no\":1, \"name\":\"name\"},\n" + + " \"attr2_uuid\":{\"schema_seq_no\":1, \"name\":\"sex\"}\n" + + " },\n" + + " \"requested_predicates\":{\n" + + " \"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18},\n" + + " \"predicate2_uuid\":{\"attr_name\":\"height\",\"p_type\":\"GE\",\"value\":160}\n" + + " }}"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + JSONArray claimsForAttribute1 = claims.getJSONObject("attrs").getJSONArray("attr1_uuid"); + assertEquals(1, claimsForAttribute1.length()); + + JSONArray claimsForAttribute2 = claims.getJSONObject("attrs").getJSONArray("attr2_uuid"); + assertEquals(1, claimsForAttribute2.length()); + + JSONArray claimsForPredicate1 = claims.getJSONObject("predicates").getJSONArray("predicate1_uuid"); + assertEquals(1, claimsForPredicate1.length()); + + JSONArray claimsForPredicate2 = claims.getJSONObject("predicates").getJSONArray("predicate2_uuid"); + assertEquals(1, claimsForPredicate2.length()); + } + + @Test + public void testProverGetClaimsForProofRequestWorksForEmptyRequest() throws Exception { + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{},\n" + + " \"requested_predicates\":{}\n" + + " }"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + assertEquals(0, claims.getJSONObject("attrs").length()); + assertEquals(0, claims.getJSONObject("predicates").length()); + } + + @Test + public void testProverGetClaimsForProofRequestWorksForRevealedAttributeWithOtherSchema() throws Exception { + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":2, \"name\":\"name\"}},\n" + + " \"requested_predicates\":{}\n" + + " }"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + JSONArray claimsForAttribute1 = claims.getJSONObject("attrs").getJSONArray("attr1_uuid"); + assertEquals(0, claimsForAttribute1.length()); + } + + @Test + public void testProverGetClaimsForProofRequestWorksForRevealedAttributeBySpecificIssuer() throws Exception { + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"issuer_did\":\"NcYxiDXkpYi6ov5FcYDi1e\",\"name\":\"name\"}},\n" + + " \"requested_predicates\":{}\n" + + " }"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + JSONArray claimsForAttribute1 = claims.getJSONObject("attrs").getJSONArray("attr1_uuid"); + assertEquals(1, claimsForAttribute1.length()); + } + + @Test + public void testProverGetClaimsForProofRequestWorksForSatisfyPredicateByIssuerAndSchema() throws Exception { + + initCommonWallet(); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18,\"schema_seq_no\":1,\"issuer_did\":\"NcYxiDXkpYi6ov5FcYDi1e\"}}\n" + + " }"; + + String claimsJson = Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + + JSONObject claims = new JSONObject(claimsJson); + + JSONArray claimsForPredicate = claims.getJSONObject("predicates").getJSONArray("predicate1_uuid"); + assertEquals(1, claimsForPredicate.length()); + } + + @Test + public void testProverGetClaimsForProofRequestWorksForInvalidProofRequest() throws Exception { + + initCommonWallet(); + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_predicates\":{}\n" + + " }"; + + Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + } + + @Test + public void testProverGetClaimsForProofRequestWorksForInvalidPredicateType() throws Exception { + + initCommonWallet(); + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"LE\",\"value\":18}}\n" + + " }"; + + Anoncreds.proverGetClaimsForProofReq(wallet, proofRequest).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverGetClaimsTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverGetClaimsTest.java new file mode 100644 index 0000000000..7b5047e7c3 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverGetClaimsTest.java @@ -0,0 +1,80 @@ +package org.hyperledger.indy.sdk.anoncreds; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.json.JSONArray; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertEquals; + +public class ProverGetClaimsTest extends AnoncredsIntegrationTest { + + @Test + public void testProverGetClaimsWorksForEmptyFilter() throws Exception { + + initCommonWallet(); + + String claims = Anoncreds.proverGetClaims(wallet, "{}").get(); + + JSONArray claimsArray = new JSONArray(claims); + + assertEquals(1, claimsArray.length()); + } + + @Test + public void testProverGetClaimsWorksForFilterByIssuer() throws Exception { + + initCommonWallet(); + + String filter = String.format("{\"issuer_did\":\"%s\"}", issuerDid); + + String claims = Anoncreds.proverGetClaims(wallet, filter).get(); + + JSONArray claimsArray = new JSONArray(claims); + + assertEquals(1, claimsArray.length()); + } + + @Test + public void testProverGetClaimsWorksForFilterByIssuerAndSchema() throws Exception { + + initCommonWallet(); + + String filter = String.format("{\"issuer_did\":\"%s\", \"schema_seq_no\":%d}", issuerDid, 1); + + String claims = Anoncreds.proverGetClaims(wallet, filter).get(); + + JSONArray claimsArray = new JSONArray(claims); + + assertEquals(1, claimsArray.length()); + } + + @Test + public void testProverGetClaimsWorksForEmptyResult() throws Exception { + + initCommonWallet(); + + String filter = String.format("{\"schema_seq_no\":%d}", 10); + + String claims = Anoncreds.proverGetClaims(wallet, filter).get(); + + JSONArray claimsArray = new JSONArray(claims); + + assertEquals(0, claimsArray.length()); + } + + @Test + public void testProverGetClaimsWorksForInvalidFilterJson() throws Exception { + + initCommonWallet(); + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String filter = String.format("{\"schema_seq_no\":\"%d\"}", 1); + + Anoncreds.proverGetClaims(wallet, filter).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverStoreClaimOfferTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverStoreClaimOfferTest.java new file mode 100644 index 0000000000..69a32bcc06 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverStoreClaimOfferTest.java @@ -0,0 +1,58 @@ +package org.hyperledger.indy.sdk.anoncreds; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +public class ProverStoreClaimOfferTest extends AnoncredsIntegrationTest { + + private Wallet wallet; + private String walletName = "storeClaimOfferWallet"; + + @Before + public void createWallet() throws Exception { + Wallet.createWallet("default", walletName, "default", null, null).get(); + this.wallet = Wallet.openWallet(walletName, null, null).get(); + } + + @After + public void deleteWallet() throws Exception { + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + @Test + public void testProverStoreClaimOfferWorks() throws Exception { + + String claimOffer = "{\"issuer_did\":\"NcYxiDXkpYi6ov5FcYDi1e\",\"schema_seq_no\":1 }"; + + Anoncreds.proverStoreClaimOffer(wallet, claimOffer).get(); + } + + @Test + public void testProverStoreClaimOfferWorksForInvalidJson() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String claimOffer = "{\"issuer_did\":\"NcYxiDXkpYi6ov5FcYDi1e\"}"; + + Anoncreds.proverStoreClaimOffer(wallet, claimOffer).get(); + } + + @Test + public void testProverStoreClaimOfferWorksForInvalidIssuerDid() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String claimOffer = "{\"issuer_did\":\"invalid_base58_string\",\"schema_seq_no\":1}"; + + Anoncreds.proverStoreClaimOffer(wallet, claimOffer).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverStoreClaimTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverStoreClaimTest.java new file mode 100644 index 0000000000..efee38983d --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/ProverStoreClaimTest.java @@ -0,0 +1,78 @@ +package org.hyperledger.indy.sdk.anoncreds; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.junit.*; + +import java.util.concurrent.ExecutionException; + +public class ProverStoreClaimTest extends AnoncredsIntegrationTest { + + @Test + public void testProverStoreClaimWorks() throws Exception { + initCommonWallet(); + + String proverWalletName = "proverWallet"; + Wallet.createWallet("default", proverWalletName, "default", null, null).get(); + Wallet proverWallet = Wallet.openWallet(proverWalletName, null, null).get(); + + Anoncreds.proverCreateMasterSecret(proverWallet, masterSecretName).get(); + + String claimOffer = String.format(claimOfferTemplate, issuerDid, 1); + + String claimRequest = Anoncreds.proverCreateClaimReq(proverWallet, proverDid, claimOffer, claimDef, masterSecretName).get(); + + String claim = "{\"sex\":[\"male\",\"5944657099558967239210949258394887428692050081607692519917050011144233115103\"],\n" + + " \"name\":[\"Alex\",\"1139481716457488690172217916278103335\"],\n" + + " \"height\":[\"175\",\"175\"],\n" + + " \"age\":[\"28\",\"28\"]\n" + + " }"; + + AnoncredsResults.IssuerCreateClaimResult createClaimResult = Anoncreds.issuerCreateClaim(wallet, claimRequest, claim, - 1, - 1).get(); + String claimJson = createClaimResult.getClaimJson(); + + Anoncreds.proverStoreClaim(proverWallet, claimJson).get(); + + proverWallet.closeWallet().get(); + Wallet.deleteWallet(proverWalletName, null).get(); + } + + @Test + public void testProverStoreClaimWorksWithoutClaimReq() throws Exception { + + initCommonWallet(); + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.WalletNotFoundError)); + + String claimJson = String.format("{\"claim\":{\"sex\":[\"male\",\"1\"],\"age\":[\"28\",\"28\"],\"name\":[\"Alex\",\"1\"],\"height\":[\"175\",\"175\"]},\n" + + " \"issuer_did\":\"%s\",\n" + + " \"revoc_reg_seq_no\":null,\n" + + " \"schema_seq_no\":2,\n" + + " \"signature\":{\"primary_claim\":{\"m2\":\"1\",\"a\":\"1\",\"e\":\"2\",\"v\":\"3\"}," + + " \"non_revocation_claim\":null}}", issuerDid2); + + Anoncreds.proverStoreClaim(wallet, claimJson).get(); + } + + @Test + public void testProverStoreClaimWorksForInvalidClaimJson() throws Exception { + + initCommonWallet(); + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String claimOffer = String.format(claimOfferTemplate, issuerDid, 1); + + Anoncreds.proverCreateClaimReq(wallet, proverDid, claimOffer, claimDef, masterSecretName).get(); + + String claimJson = "{\"claim\":{\"sex\":[\"male\",\"1\"],\"age\":[\"28\",\"28\"],\"name\":[\"Alex\",\"1\"],\"height\":[\"175\",\"175\"]},\n" + + " \"issuer_did\":1,\"\n" + + " \"revoc_reg_seq_no\":null,\n" + + " \"schema_seq_no\":1}"; + + Anoncreds.proverStoreClaim(wallet, claimJson).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/VerifierVerifyProofTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/VerifierVerifyProofTest.java new file mode 100644 index 0000000000..773d31f82a --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/anoncreds/VerifierVerifyProofTest.java @@ -0,0 +1,80 @@ +package org.hyperledger.indy.sdk.anoncreds; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class VerifierVerifyProofTest extends AnoncredsIntegrationTest { + + private String claimDef = "{\"ref\":1," + + " \"signature_type\":\"CL\"," + + " \"origin\":\"NcYxiDXkpYi6ov5FcYDi1e\"," + + " \"data\":{\"primary\":{\"n\":\"94759924268422840873493186881483285628376767714620627055233230078254863658476446487556117977593248501523199451418346650764648601684276437772084327637083000213497377603495837360299641742248892290843802071224822481683143989223918276185323177379400413928352871249494885563503003839960930062341074783742062464846448855510814252519824733234277681749977392772900212293652238651538092092030867161752390937372967233462027620699196724949212432236376627703446877808405786247217818975482797381180714523093913559060716447170497587855871901716892114835713057965087473682457896508094049813280368069805661739141591558517233009123957\",\"s\":\"3589207374161609293256840431433442367968556468254553005135697551692970564853243905310862234226531556373974144223993822323573625466428920716249949819187529684239371465431718456502388533731367046146704547241076626874082510133130124364613881638153345624380195335138152993132904167470515345775215584510356780117368593105284564368954871044494967246738070895990267205643985529060025311535539534155086912661927003271053443110788963970349858709526217650537936123121324492871282397691771309596632805099306241616501610166028401599243350835158479028294769235556557248339060399322556412171888114265194198405765574333538019124846\",\"rms\":\"57150374376895616256492932008792437185713712934712117819417607831438470701645904776986426606717466732609284990796923331049549544903261623636958698296956103821068569714644825742048584174696465882627177060166162341112552851798863535031243458188976013190131935905789786836375734914391914349188643340535242562896244661798678234667651641013894284156416773868299435641426810968290584996112925365638881750944407842890875840705650290814965768221299488400872767679122749231050406680432079499973527780212310700022178178822528199576164498116369689770884051691678056831493476045361227274839673581033532995523269047577973637307053\",\"r\":{\"age\":\"94304485801056920773231824603827244147437820123357994068540328541540143488826838939836897544389872126768239056314698953816072289663428273075648246498659039419931054256171488371404693243192741923382499918184822032756852725234903892700640856294525441486319095181804549558538523888770076173572615957495813339649470619615099181648313548341951673407624414494737018574238782648822189142664108450534642272145962844003886059737965854042074083374478426875684184904488545593139633653407062308621502392373426120986761417580127895634822264744063122368296502161439648408926687989964483291459079738447940651025900007635890755686910\",\"sex\":\"29253365609829921413347591854991689007250272038394995372767401325848195298844802462252851926995846503104090589196060683329875231216529049681648909174047403783834364995363938741001507091534282239210301727771803410513303526378812888571225762557471133950393342500638551458868147905023198508660460641434022020257614450354085808398293279060446966692082427506909617283562394303716193372887306176319841941848888379308208426966697446699225783646634631703732019477632822374479322570142967559738439193417309205283438893083349863592921249218168590490390313109776446516881569691499831380592661740653935515397472059631417493981532\",\"name\":\"25134437486609445980011967476486104706321061312022352268621323694861467756181853100693555519614894168921947814126694858839278103549577703105305116890325322098078409416441750313062396467567140699008203113519528887729951138845002409659317083029073793314514377377412805387401717457417895322600145580639449003584446356048213839274172751441145076183734269045919984853749007476629365146654240675320041155618450449041510280560040162429566008590065069477149918088087715269037925211599101597422023202484497946662159070023999719865939258557778022770035320019440597702090334486792710436579355608406897769514395306079855023848170\",\"height\":\"59326960517737425423547279838932030505937927873589489863081026714907925093402287263487670945897247474465655528290016645774365383046524346223348261262488616342337864633104758662753452450299389775751012589698563659277683974188553993694220606310980581680471280640591973543996299789038056921309016983827578247477799948667666717056420270448516049047961099547588510086600581628091290215485826514170097211360599793229701811672966818089371089216189744274422526431130783428589346341196561742409198605034972210917502326180305735092988639850309253190875578501020679137562856724998821945605494355779034135306337094344532980411836\"},\"rctxt\":\"9641986614889199796257508700106896585587271615330980339636468819377346498767697681332046156705231986464570206666984343024200482683981302064613556104594051003956610353281701880542337665385482309134369756144345334575765116656633321636736946947493150642615481313285221467998414924865943067790561494301461899025374692884841352282256044388512875752628313052128404892424405230961678931620525106856624692942373538946467902799339061714326383378018581568876147181355325663707572429090278505823900491548970098691127791086305310899642155499128171811034581730190877600697624903963241473287185133286356124371104261592694271730029\",\"z\":\"77594127026421654059198621152153180600664927707984020918609426112642522289621323453889995053400171879296098965678384769043918218957929606187082395048777546641833348694470081024386996548890150355901703252426977094536933434556202865213941384425538749866521536494046548509344678288447175898173634381514948562261015286492185924659638474376885655055568341574638453213864956407243206035973349529545863886325462867413885904072942842465859476940638839087894582648849969332663627779378998245133055807038199937421971988505911494931665143822588532097754480882750243126847177560978100527491344463525107644125030963904001009159559\"},\"revocation\":null}}"; + + private String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1, \"name\":\"name\"}},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}}\n" + + " }"; + + private String schemasJson = String.format("{\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\":%s}", schema); + private String claimDefsJson = String.format("{\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\":%s}", claimDef); + private String revocRegsJson = "{}"; + + @Test + public void testVerifierVerifyProofWorksForCorrectProof() throws Exception { + + String proofJson = "{\"proofs\":{\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\":{\"proof\":{\"primary_proof\":{\"eq_proof\":{\"revealed_attrs\":{\"name\":\"1139481716457488690172217916278103335\"},\"a_prime\":\"47629821806628155353444789773246165920681315271529392722265555946090524267165563309836167110610840740533588118152308411732923636370660640410661034994521654033599863817144282118006097899736622728860229305231675970853294584911572355833537271010861501353858292189045263114095480601737776505186511389129055847562085611741257601964074827979121349153316235245772819207422031038042586202074331681302501661153569340935741290924699468188826629478130140797677338573924284871118002193526319478550852287453975107498037063076866410320160118555629090040954555043934303307652160345244864713226315470541231435958298648179413077988340\",\"e\":\"13427639393364185909415877973872458621259927563729922146828001652769380799419438410309469022979920689628523901764614163117469683925816443\",\"v\":\"852136445143816932026946294488424887907102968158908948827421962603492187508454543239422067899916472317305416590471170842186669606584356963437132366711335927890209765986844538775191207999204354235774464468525274918097404114453069375363594310105209141774763909570100638835926337238009617444858777301355087706167735590386774813901740600054753028260344014744801229032610106838480523182317262113911183640784111960909501662169298536941919854667754097841344375972975021196106884215734228415868248724905018661498061287694439466570946597514142085096419985189064172035527690786158872698717583830848410994616274586162550376126607414773916066374234063208380831144157533076866210628625236440222547584539349936639548061601416341705483504386186280800509889531835172071717956251546280392606775903107774727736794828168898273891724336881907672405328368540895104468091907771325910937575557566831844131159128453840354307814975621978196047820\",\"m\":{\"age\":\"1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662\",\"height\":\"7064132689652704067914104576495132313294680087958177180391515757079548676035445873279966783996928425154050462229933823707574545166617858646442019030600136959459527533262821184869\",\"sex\":\"16084497853957041205729191269508720470626311156190485518484640641677445098603656354458362520541393995692536218820724164533958162674375198846036330444513484319280148335515891811530\"},\"m1\":\"154906224259819061652290487122980839849626068919893070220438585977323162319993111920906032317552959103520053742608858935542877608981244065301675821390065831113115709272412144796159984624494428122971995557415296140268002332169405587907128359886810433617416529821500995701094400375272097687818064435577784795275\",\"m2\":\"13805395408072590464827983892588030341708765524663545700917462089376137940485022437657208204460048097312372685954050370540389593952001973312378647790917367330461398089529292217752\"},\"ge_proofs\":[{\"u\":{\"1\":\"7698818972783845439601187851976452936638792889455287252542709653271706844173743185409084669157965935169942655008606334521674712818637940377261656468700786810566551698412412949418\",\"0\":\"11703047052430512223413711314521545616119146623040600935686474696241801697819280425232876917607198335376453682738553665221410353412906194951254558355994401995990233992518110582450\",\"3\":\"13210777821918317858818819091924507295018522783042111457450035423463340571245465760486275059291363621513532153389441883097799049597687545496359999443320001567152794884095192951040\",\"2\":\"15219471780524079156861690098171693383497641272226737821992208834301871102152362116211452788300889697214391366996966539871625433480959011635688106136537800706217506402845296449689\"},\"r\":{\"1\":\"46043242109380749151527145850513330956077996622769158245225343392397735706292106535150958053995712629189143692293204979798837951212291825184346767969751978730000071952944305252032332015837054475531407691352179423131405515518588355918925056889302269768343499864256747177988825578647189563088068257214198650437730618330249172716051559993880468542083352885474175039320848153156858562341041960950299312991459780503345784440261679263045723337629951517601461685539857683027034345542399365706329805317943096391758978877658949910614447086409173234155028671453929715706057153381022697673192590033507204548864311227048268516889390503318015295207078022755834130221198717787608473222789491216667698651180077661375273569115943192\",\"0\":\"135472587547410377947826119498467634347118057359097899596599164976338466445104141784869016998150489852448547539824768048351359572626675997498079394825940306636285481821620973655797996638210760710325933304918452142858879806106214845499670718704532018129553348815327362843246706518826311676917538452317818631484884032929252959289913274829848084561421467966320595980172006456003183536232790787521924655750157145207798486087511869939940023266736153366338179116840490184005332351004990854691988404031259910319601383696749511809898297656135548118786342107367065232798999979296280467063561892962526945512167505847049907450058650930480352253243357594344686769208712964458923557777584158831146374282687397585726706489164423632\",\"DELTA\":\"93540839493959971552865423901789226093328763011922445919928571946113703515842729132879472109395228387208764738970926484618949870591214627692618668077375153559192701474693025462226656116549337248146652482501255820930607033869432220667968682424554711616471973627651716863421554516577716366331699848682958681216261888139409101603059124344125075525791543312721162515584942523419876134808829569829529457617639955678189490257208141837196965948342373022812790844435050648360150869293836349223060722858500537182872294143846213258360218898475766641125493477502149553491502593654061863323857297998048614447925371606038801933864960337435890254277043261512846682042139570000962051463878026338583242360548041329046695667868842400\",\"3\":\"1227675452527605924725300993571504188580051470857656204064614533296779844072852823820754766175236321050062349182891221840452517985644028521499240739391613871973822807731772613052644168369405390658793869751915172749739844553410726807277698347769400977274750672880389943392076308065414059539317340070691852044062594715307024113666759844200606183662256825096857658837519571386467051003466014468855293015652584667669998830524947537781865745830650392641812221679438090257444660715937570193098993118585554478799821072396238689063767016402460690760792908977364175126682041704095200572282644311025594681667826054722587271200221036938804846621444065128275082392082327596239358623150786484106872933657139420542280145197712634108\",\"2\":\"596248147592834822582469335300585333722415132713749620075902332764163096347819006925876158892694742461036531935093982309708492066217459300117157420442081698140277277546563570823996272914068575482008392971932777453900260626542725308060927710122631763045025742980634216666560934260634907599194353151523256914796667535940073668465664206971169038864484235442207811974981191879443614478897291543702607764944403808380921189291059195014621592027660463072969363556421687131446107696579365265893962197300447027501604372738056016734644378437907931412654753728514905671605635291285742886484416973884856055084605172305967034292646171874483670469193852404511746786039743401185954843446037600121496137915619789351744485264614840070\"},\"mj\":\"1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662\",\"alpha\":\"76727612740067576380015106087224381023260815407331375101920043509817863645705120013304683427627332447210083684516403565749916480947649443674885388155460323163682547865307733144184097845709556309570345707127872162476432029772452433292049079349274445907295491125915363620615679995457134810061392296263970553630102299601689685622244925494554558218277670233361938142224820526392365740420502452466959099546877778248089664282581792213376636587293479012783947088070052463503335266180110771978445892744225891676396288437005847308189508347446490710626231658457908472341606549292437553353163031111068977301305043175839949352742711874426231072729977019365761072816602400121302646283352164756787266537474728685656685493249314400351742964904006326192403855909148605656818024621453179832395687665671245528217931951331393482249182516107670379946496778373\",\"t\":{\"1\":\"37203689290881948278188715497642400459048942241931994079434400288578680362970117779048886269388440270597283202033458042171954610700745461571112086648991639439510380585728148682202768590972068041537531136529323260832899360551065706810590032715173070285762675403853992183366951113799098912676809373169763887110420539387555392787590966452796271491986622992160642135480293110112269570862265489120557014181468118619500321000966443141863893743211690388599242584469856365803370202569641902205925191670838354052104480074127555862332399641076324738839120815544432811566503174551735326387678621283249883091766325861497740614317\",\"3\":\"58486787977689017034592833190899828017343431922483563651969628402499947729293364026001243898136737211851089198526360764391403150763769829047179796728616126204105160762333590343947446892105646111520243793053992399512412375936746396187319527051818920531870855183738837254656664620975569939859368862778444291640228229744805843388153451336792379036403300211151424879060241580540910888241769468335914016289938374111481091198264912969768783884602931940994543804730631920434719776196148182987249363641941951160704928605829395517074202388967815738516252602903999010405305463910751219873354588685197134114358234107748126140977\",\"0\":\"60771874648036182010335841594233428920565254732600738082343398028553347795361460295011584446745121430144172025428394361648540904134739046923992231536160801306934272250969829886396340824213814702904457884984387666505055153957942221822193548673145705543973635530652570436109428474727638128773540793530691399549837156239786231362112148914687724325416768262058486101761972044802628459748878200584371058300150212485731451700436345975266860685549673168984700174294811561393162860595319582236734968601457003780816977537443267217411297266600994916897237305128142313335280264655603445636393371224354539882875937093696844430903\",\"DELTA\":\"32816484171372208266594641116109072545171919234551585018140151846920408763078147655907777031259225522515086979967895258126318315788662577171150780535509410112003001556402222994276811926864642497249250763185467678044678144507739529818566125668667424447792097244624010084189629269472698722402896445274092470014229247479740671263651727480322483037149584904549203417226525624083290572692241241259382947122018271686649224741832992966652878170311798126004447080305528487720923103595513611363001766063956060990267107048028416069435287244770875463867263571308182619338433913487209319707428378896314619624990311543563016697299\",\"2\":\"36428320569485697540634597755814766104888687488985202673924762266313135133244610404742081973550848160712054769198012193456278135847215508952327879544434490828380496286187725750283788811367824465072001959950807751252194618152990469069074061195618692339915840384087350671392595652921761835083158086795163935060896053332506433434451836095710383871272788002621913967538399141417857031787255744141437237474972197102809365346359345477248611632307159641948507043668113827177494748159094045928919209335044052792843664865311991178972383241855607627188111601119780878072683890170539599447876998109080150992209773901144245398001\"},\"predicate\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}}]},\"non_revoc_proof\":null},\"schema_seq_no\":1,\"revoc_reg_seq_no\":null,\"issuer_did\":\"did\"}},\"aggregated_proof\":{\"c_hash\":\"33103550379681684069592829341967479618752165928802550870585275205292715916069\",\"c_list\":[[1,121,77,5,144,154,14,192,190,190,145,180,128,71,22,60,168,20,46,163,139,194,71,165,220,188,121,76,25,146,231,114,65,54,69,68,19,200,250,192,47,123,157,132,74,50,28,69,226,195,243,118,45,63,237,197,216,202,206,101,33,56,225,200,128,3,89,12,182,38,113,221,165,119,228,201,156,201,172,136,59,64,51,72,164,198,49,228,223,117,80,64,166,226,37,8,29,146,186,80,210,119,76,252,4,255,62,218,112,163,164,147,247,190,108,76,140,191,76,217,214,184,152,179,193,149,15,70,197,46,90,60,255,247,197,219,252,73,76,0,125,104,114,22,182,161,110,36,162,103,27,42,88,18,161,237,198,43,177,189,181,86,135,207,71,114,0,26,175,12,199,125,25,124,178,87,36,208,251,15,191,127,202,148,152,43,142,92,191,7,89,153,130,195,223,248,176,109,97,164,126,162,181,124,237,130,155,197,66,59,40,197,72,84,32,100,64,55,227,60,214,143,200,200,89,115,236,172,145,56,100,73,20,242,233,95,130,58,112,153,120,115,119,42,199,30,205,88,223,42,196,184,41,19,100,19,244],[1,225,103,238,42,147,91,191,110,69,154,53,57,156,124,43,174,155,76,202,193,98,128,38,207,126,66,70,161,96,109,127,174,44,203,198,177,238,118,117,89,227,170,155,44,251,35,119,219,29,100,173,26,144,95,50,177,4,40,234,117,174,210,192,172,57,160,198,42,199,212,243,240,114,59,91,207,68,57,38,198,2,73,18,16,209,182,145,206,71,17,69,222,49,36,120,72,117,169,107,238,208,235,216,24,183,201,81,15,83,242,45,136,184,166,26,142,136,228,58,229,235,88,169,238,134,205,96,85,9,122,53,147,100,183,114,92,54,125,178,125,75,127,116,50,88,109,152,22,4,121,252,190,18,190,130,143,138,59,231,38,131,176,54,19,194,218,67,144,122,91,43,86,73,233,48,193,30,183,183,191,238,216,167,101,28,185,43,118,64,242,16,62,239,177,27,109,144,67,221,175,202,4,92,130,74,24,20,151,15,227,225,142,71,145,46,192,248,87,57,183,142,253,52,20,56,153,220,234,25,67,116,225,179,211,116,161,37,64,34,48,155,1,1,159,157,37,31,202,19,229,152,23,138,183,126,55],[1,38,181,193,191,72,2,239,34,83,49,36,179,160,82,112,172,98,255,63,60,22,177,249,67,215,220,198,181,7,49,254,133,243,221,214,47,64,229,82,11,94,175,57,86,152,229,192,184,96,136,116,226,123,128,217,23,244,19,204,36,44,123,208,88,24,217,120,145,139,25,233,227,5,119,90,47,147,1,115,92,39,119,194,167,17,229,39,163,167,237,14,116,234,106,252,216,54,33,233,21,54,183,130,144,161,177,142,177,240,51,73,21,202,188,103,244,153,204,219,123,231,139,135,189,155,143,28,4,180,44,148,0,27,103,26,13,203,31,32,166,67,84,87,23,72,234,236,20,1,84,70,86,76,192,164,235,124,86,128,78,230,119,155,95,121,125,20,244,181,121,250,169,9,67,85,213,177,139,111,187,183,114,165,249,177,161,181,175,46,226,66,86,84,124,86,69,143,217,158,161,30,107,133,44,239,89,209,24,150,1,238,122,144,138,179,121,114,90,13,212,209,60,126,37,62,177,180,131,222,168,2,201,156,169,220,224,53,8,203,220,215,163,104,195,184,73,35,241,182,177,80,41,253,230,90,173],[1,32,145,96,219,241,190,19,195,129,219,50,148,152,107,12,189,225,103,171,149,252,193,243,136,132,195,44,19,20,247,140,160,91,230,78,31,242,85,213,65,185,1,91,12,69,118,80,26,135,102,131,4,108,130,230,83,91,176,249,196,56,128,127,82,72,106,49,211,94,133,40,86,72,42,187,199,216,191,223,208,206,121,118,15,167,255,228,57,206,158,217,64,205,212,178,8,248,129,183,221,98,70,54,37,55,47,81,120,59,186,238,165,0,70,173,137,193,232,180,125,211,237,182,249,191,173,107,129,164,148,231,116,225,66,66,71,156,39,248,164,253,234,140,205,177,140,117,47,21,15,242,31,113,118,91,143,89,213,86,143,135,21,46,35,199,214,107,111,65,65,19,26,171,130,16,19,102,145,210,210,61,51,169,148,169,118,182,106,107,253,100,214,232,52,103,180,96,249,254,71,6,11,119,48,129,213,223,205,93,20,117,26,187,32,151,212,137,203,17,237,208,150,72,23,225,235,122,188,34,105,115,0,160,168,251,191,22,242,238,207,74,142,154,66,94,149,191,215,194,134,6,165,244,167,233,241],[1,207,77,250,146,127,242,229,44,172,182,201,183,242,32,242,182,129,233,10,8,180,23,191,163,21,238,158,5,27,216,146,253,173,127,99,95,168,209,132,242,196,242,34,25,25,249,211,51,236,164,153,175,61,65,150,82,251,174,102,186,47,195,82,44,90,252,184,74,89,251,177,254,108,151,136,230,220,93,224,173,247,244,116,132,59,170,215,194,30,87,84,166,147,57,156,201,207,132,203,222,191,253,15,19,228,173,81,156,4,51,121,227,159,50,18,148,129,205,42,42,227,252,138,62,176,115,227,253,52,125,110,178,167,132,244,14,116,195,194,172,44,45,63,38,121,215,136,68,230,21,108,133,159,197,179,94,78,233,107,236,114,92,165,248,22,124,161,23,142,236,224,175,233,134,25,97,150,131,61,220,203,104,154,199,247,146,47,205,56,209,0,133,132,18,103,136,8,202,37,29,100,105,12,232,74,33,6,255,202,96,170,52,229,244,4,235,2,201,125,86,168,179,224,130,81,54,221,185,184,187,141,0,114,98,38,70,225,228,60,157,53,210,238,60,216,215,154,48,73,3,157,192,245,81,170,49],[1,3,244,229,158,71,18,146,198,202,27,2,231,37,13,145,243,84,112,220,61,174,4,175,104,200,64,146,193,20,174,126,42,157,168,76,165,21,50,216,82,211,180,73,244,54,227,200,19,157,25,228,81,37,64,201,19,138,175,50,246,169,11,45,74,194,131,236,127,177,41,242,130,55,112,182,98,22,99,48,153,83,161,250,65,89,3,97,6,5,171,54,223,87,98,103,23,200,212,177,140,155,151,252,125,45,176,55,92,41,56,2,252,32,149,60,3,168,209,193,23,168,230,182,72,193,230,224,5,15,58,63,93,196,33,93,76,188,30,70,31,136,64,204,223,2,230,210,243,255,135,193,52,132,248,160,22,18,164,71,77,80,112,229,120,116,210,225,2,19,139,35,0,214,5,246,9,106,136,204,0,148,97,21,222,153,57,177,162,11,243,252,7,242,34,239,245,50,104,74,221,92,73,13,142,10,184,250,246,167,240,46,230,86,207,181,12,133,81,119,143,164,88,114,223,243,179,208,175,84,161,27,11,225,36,37,177,112,85,81,184,163,223,159,36,9,247,20,13,230,215,108,117,35,99,117,211]]},\"requested_proof\":{\"revealed_attrs\":{\"attr1_uuid\":[\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\",\"Alex\",\"1139481716457488690172217916278103335\"]},\"unrevealed_attrs\":{},\"self_attested_attrs\":{},\"predicates\":{\"predicate1_uuid\":\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\"}}}"; + + Boolean valid = Anoncreds.verifierVerifyProof(proofRequest, proofJson, schemasJson, claimDefsJson, revocRegsJson).get(); + assertTrue(valid); + } + + @Test + public void testVerifierVerifyProofWorksForProofDoesNotCorrespondToRequested() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String proofRequest = "{\"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1,\"name\":\"sex\"}},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"height\",\"p_type\":\"GE\",\"value\":180}}\n" + + " }"; + + String proofJson = "{\"proofs\":{\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\":{\"proof\":{\"primary_proof\":{\"eq_proof\":{\"revealed_attrs\":{\"name\":\"1139481716457488690172217916278103335\"},\"a_prime\":\"47629821806628155353444789773246165920681315271529392722265555946090524267165563309836167110610840740533588118152308411732923636370660640410661034994521654033599863817144282118006097899736622728860229305231675970853294584911572355833537271010861501353858292189045263114095480601737776505186511389129055847562085611741257601964074827979121349153316235245772819207422031038042586202074331681302501661153569340935741290924699468188826629478130140797677338573924284871118002193526319478550852287453975107498037063076866410320160118555629090040954555043934303307652160345244864713226315470541231435958298648179413077988340\",\"e\":\"13427639393364185909415877973872458621259927563729922146828001652769380799419438410309469022979920689628523901764614163117469683925816443\",\"v\":\"852136445143816932026946294488424887907102968158908948827421962603492187508454543239422067899916472317305416590471170842186669606584356963437132366711335927890209765986844538775191207999204354235774464468525274918097404114453069375363594310105209141774763909570100638835926337238009617444858777301355087706167735590386774813901740600054753028260344014744801229032610106838480523182317262113911183640784111960909501662169298536941919854667754097841344375972975021196106884215734228415868248724905018661498061287694439466570946597514142085096419985189064172035527690786158872698717583830848410994616274586162550376126607414773916066374234063208380831144157533076866210628625236440222547584539349936639548061601416341705483504386186280800509889531835172071717956251546280392606775903107774727736794828168898273891724336881907672405328368540895104468091907771325910937575557566831844131159128453840354307814975621978196047820\",\"m\":{\"age\":\"1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662\",\"height\":\"7064132689652704067914104576495132313294680087958177180391515757079548676035445873279966783996928425154050462229933823707574545166617858646442019030600136959459527533262821184869\",\"sex\":\"16084497853957041205729191269508720470626311156190485518484640641677445098603656354458362520541393995692536218820724164533958162674375198846036330444513484319280148335515891811530\"},\"m1\":\"154906224259819061652290487122980839849626068919893070220438585977323162319993111920906032317552959103520053742608858935542877608981244065301675821390065831113115709272412144796159984624494428122971995557415296140268002332169405587907128359886810433617416529821500995701094400375272097687818064435577784795275\",\"m2\":\"13805395408072590464827983892588030341708765524663545700917462089376137940485022437657208204460048097312372685954050370540389593952001973312378647790917367330461398089529292217752\"},\"ge_proofs\":[{\"u\":{\"1\":\"7698818972783845439601187851976452936638792889455287252542709653271706844173743185409084669157965935169942655008606334521674712818637940377261656468700786810566551698412412949418\",\"0\":\"11703047052430512223413711314521545616119146623040600935686474696241801697819280425232876917607198335376453682738553665221410353412906194951254558355994401995990233992518110582450\",\"3\":\"13210777821918317858818819091924507295018522783042111457450035423463340571245465760486275059291363621513532153389441883097799049597687545496359999443320001567152794884095192951040\",\"2\":\"15219471780524079156861690098171693383497641272226737821992208834301871102152362116211452788300889697214391366996966539871625433480959011635688106136537800706217506402845296449689\"},\"r\":{\"1\":\"46043242109380749151527145850513330956077996622769158245225343392397735706292106535150958053995712629189143692293204979798837951212291825184346767969751978730000071952944305252032332015837054475531407691352179423131405515518588355918925056889302269768343499864256747177988825578647189563088068257214198650437730618330249172716051559993880468542083352885474175039320848153156858562341041960950299312991459780503345784440261679263045723337629951517601461685539857683027034345542399365706329805317943096391758978877658949910614447086409173234155028671453929715706057153381022697673192590033507204548864311227048268516889390503318015295207078022755834130221198717787608473222789491216667698651180077661375273569115943192\",\"0\":\"135472587547410377947826119498467634347118057359097899596599164976338466445104141784869016998150489852448547539824768048351359572626675997498079394825940306636285481821620973655797996638210760710325933304918452142858879806106214845499670718704532018129553348815327362843246706518826311676917538452317818631484884032929252959289913274829848084561421467966320595980172006456003183536232790787521924655750157145207798486087511869939940023266736153366338179116840490184005332351004990854691988404031259910319601383696749511809898297656135548118786342107367065232798999979296280467063561892962526945512167505847049907450058650930480352253243357594344686769208712964458923557777584158831146374282687397585726706489164423632\",\"DELTA\":\"93540839493959971552865423901789226093328763011922445919928571946113703515842729132879472109395228387208764738970926484618949870591214627692618668077375153559192701474693025462226656116549337248146652482501255820930607033869432220667968682424554711616471973627651716863421554516577716366331699848682958681216261888139409101603059124344125075525791543312721162515584942523419876134808829569829529457617639955678189490257208141837196965948342373022812790844435050648360150869293836349223060722858500537182872294143846213258360218898475766641125493477502149553491502593654061863323857297998048614447925371606038801933864960337435890254277043261512846682042139570000962051463878026338583242360548041329046695667868842400\",\"3\":\"1227675452527605924725300993571504188580051470857656204064614533296779844072852823820754766175236321050062349182891221840452517985644028521499240739391613871973822807731772613052644168369405390658793869751915172749739844553410726807277698347769400977274750672880389943392076308065414059539317340070691852044062594715307024113666759844200606183662256825096857658837519571386467051003466014468855293015652584667669998830524947537781865745830650392641812221679438090257444660715937570193098993118585554478799821072396238689063767016402460690760792908977364175126682041704095200572282644311025594681667826054722587271200221036938804846621444065128275082392082327596239358623150786484106872933657139420542280145197712634108\",\"2\":\"596248147592834822582469335300585333722415132713749620075902332764163096347819006925876158892694742461036531935093982309708492066217459300117157420442081698140277277546563570823996272914068575482008392971932777453900260626542725308060927710122631763045025742980634216666560934260634907599194353151523256914796667535940073668465664206971169038864484235442207811974981191879443614478897291543702607764944403808380921189291059195014621592027660463072969363556421687131446107696579365265893962197300447027501604372738056016734644378437907931412654753728514905671605635291285742886484416973884856055084605172305967034292646171874483670469193852404511746786039743401185954843446037600121496137915619789351744485264614840070\"},\"mj\":\"1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662\",\"alpha\":\"76727612740067576380015106087224381023260815407331375101920043509817863645705120013304683427627332447210083684516403565749916480947649443674885388155460323163682547865307733144184097845709556309570345707127872162476432029772452433292049079349274445907295491125915363620615679995457134810061392296263970553630102299601689685622244925494554558218277670233361938142224820526392365740420502452466959099546877778248089664282581792213376636587293479012783947088070052463503335266180110771978445892744225891676396288437005847308189508347446490710626231658457908472341606549292437553353163031111068977301305043175839949352742711874426231072729977019365761072816602400121302646283352164756787266537474728685656685493249314400351742964904006326192403855909148605656818024621453179832395687665671245528217931951331393482249182516107670379946496778373\",\"t\":{\"1\":\"37203689290881948278188715497642400459048942241931994079434400288578680362970117779048886269388440270597283202033458042171954610700745461571112086648991639439510380585728148682202768590972068041537531136529323260832899360551065706810590032715173070285762675403853992183366951113799098912676809373169763887110420539387555392787590966452796271491986622992160642135480293110112269570862265489120557014181468118619500321000966443141863893743211690388599242584469856365803370202569641902205925191670838354052104480074127555862332399641076324738839120815544432811566503174551735326387678621283249883091766325861497740614317\",\"3\":\"58486787977689017034592833190899828017343431922483563651969628402499947729293364026001243898136737211851089198526360764391403150763769829047179796728616126204105160762333590343947446892105646111520243793053992399512412375936746396187319527051818920531870855183738837254656664620975569939859368862778444291640228229744805843388153451336792379036403300211151424879060241580540910888241769468335914016289938374111481091198264912969768783884602931940994543804730631920434719776196148182987249363641941951160704928605829395517074202388967815738516252602903999010405305463910751219873354588685197134114358234107748126140977\",\"0\":\"60771874648036182010335841594233428920565254732600738082343398028553347795361460295011584446745121430144172025428394361648540904134739046923992231536160801306934272250969829886396340824213814702904457884984387666505055153957942221822193548673145705543973635530652570436109428474727638128773540793530691399549837156239786231362112148914687724325416768262058486101761972044802628459748878200584371058300150212485731451700436345975266860685549673168984700174294811561393162860595319582236734968601457003780816977537443267217411297266600994916897237305128142313335280264655603445636393371224354539882875937093696844430903\",\"DELTA\":\"32816484171372208266594641116109072545171919234551585018140151846920408763078147655907777031259225522515086979967895258126318315788662577171150780535509410112003001556402222994276811926864642497249250763185467678044678144507739529818566125668667424447792097244624010084189629269472698722402896445274092470014229247479740671263651727480322483037149584904549203417226525624083290572692241241259382947122018271686649224741832992966652878170311798126004447080305528487720923103595513611363001766063956060990267107048028416069435287244770875463867263571308182619338433913487209319707428378896314619624990311543563016697299\",\"2\":\"36428320569485697540634597755814766104888687488985202673924762266313135133244610404742081973550848160712054769198012193456278135847215508952327879544434490828380496286187725750283788811367824465072001959950807751252194618152990469069074061195618692339915840384087350671392595652921761835083158086795163935060896053332506433434451836095710383871272788002621913967538399141417857031787255744141437237474972197102809365346359345477248611632307159641948507043668113827177494748159094045928919209335044052792843664865311991178972383241855607627188111601119780878072683890170539599447876998109080150992209773901144245398001\"},\"predicate\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}}]},\"non_revoc_proof\":null},\"schema_seq_no\":1,\"revoc_reg_seq_no\":null,\"issuer_did\":\"did\"}},\"aggregated_proof\":{\"c_hash\":\"33103550379681684069592829341967479618752165928802550870585275205292715916069\",\"c_list\":[[1,121,77,5,144,154,14,192,190,190,145,180,128,71,22,60,168,20,46,163,139,194,71,165,220,188,121,76,25,146,231,114,65,54,69,68,19,200,250,192,47,123,157,132,74,50,28,69,226,195,243,118,45,63,237,197,216,202,206,101,33,56,225,200,128,3,89,12,182,38,113,221,165,119,228,201,156,201,172,136,59,64,51,72,164,198,49,228,223,117,80,64,166,226,37,8,29,146,186,80,210,119,76,252,4,255,62,218,112,163,164,147,247,190,108,76,140,191,76,217,214,184,152,179,193,149,15,70,197,46,90,60,255,247,197,219,252,73,76,0,125,104,114,22,182,161,110,36,162,103,27,42,88,18,161,237,198,43,177,189,181,86,135,207,71,114,0,26,175,12,199,125,25,124,178,87,36,208,251,15,191,127,202,148,152,43,142,92,191,7,89,153,130,195,223,248,176,109,97,164,126,162,181,124,237,130,155,197,66,59,40,197,72,84,32,100,64,55,227,60,214,143,200,200,89,115,236,172,145,56,100,73,20,242,233,95,130,58,112,153,120,115,119,42,199,30,205,88,223,42,196,184,41,19,100,19,244],[1,225,103,238,42,147,91,191,110,69,154,53,57,156,124,43,174,155,76,202,193,98,128,38,207,126,66,70,161,96,109,127,174,44,203,198,177,238,118,117,89,227,170,155,44,251,35,119,219,29,100,173,26,144,95,50,177,4,40,234,117,174,210,192,172,57,160,198,42,199,212,243,240,114,59,91,207,68,57,38,198,2,73,18,16,209,182,145,206,71,17,69,222,49,36,120,72,117,169,107,238,208,235,216,24,183,201,81,15,83,242,45,136,184,166,26,142,136,228,58,229,235,88,169,238,134,205,96,85,9,122,53,147,100,183,114,92,54,125,178,125,75,127,116,50,88,109,152,22,4,121,252,190,18,190,130,143,138,59,231,38,131,176,54,19,194,218,67,144,122,91,43,86,73,233,48,193,30,183,183,191,238,216,167,101,28,185,43,118,64,242,16,62,239,177,27,109,144,67,221,175,202,4,92,130,74,24,20,151,15,227,225,142,71,145,46,192,248,87,57,183,142,253,52,20,56,153,220,234,25,67,116,225,179,211,116,161,37,64,34,48,155,1,1,159,157,37,31,202,19,229,152,23,138,183,126,55],[1,38,181,193,191,72,2,239,34,83,49,36,179,160,82,112,172,98,255,63,60,22,177,249,67,215,220,198,181,7,49,254,133,243,221,214,47,64,229,82,11,94,175,57,86,152,229,192,184,96,136,116,226,123,128,217,23,244,19,204,36,44,123,208,88,24,217,120,145,139,25,233,227,5,119,90,47,147,1,115,92,39,119,194,167,17,229,39,163,167,237,14,116,234,106,252,216,54,33,233,21,54,183,130,144,161,177,142,177,240,51,73,21,202,188,103,244,153,204,219,123,231,139,135,189,155,143,28,4,180,44,148,0,27,103,26,13,203,31,32,166,67,84,87,23,72,234,236,20,1,84,70,86,76,192,164,235,124,86,128,78,230,119,155,95,121,125,20,244,181,121,250,169,9,67,85,213,177,139,111,187,183,114,165,249,177,161,181,175,46,226,66,86,84,124,86,69,143,217,158,161,30,107,133,44,239,89,209,24,150,1,238,122,144,138,179,121,114,90,13,212,209,60,126,37,62,177,180,131,222,168,2,201,156,169,220,224,53,8,203,220,215,163,104,195,184,73,35,241,182,177,80,41,253,230,90,173],[1,32,145,96,219,241,190,19,195,129,219,50,148,152,107,12,189,225,103,171,149,252,193,243,136,132,195,44,19,20,247,140,160,91,230,78,31,242,85,213,65,185,1,91,12,69,118,80,26,135,102,131,4,108,130,230,83,91,176,249,196,56,128,127,82,72,106,49,211,94,133,40,86,72,42,187,199,216,191,223,208,206,121,118,15,167,255,228,57,206,158,217,64,205,212,178,8,248,129,183,221,98,70,54,37,55,47,81,120,59,186,238,165,0,70,173,137,193,232,180,125,211,237,182,249,191,173,107,129,164,148,231,116,225,66,66,71,156,39,248,164,253,234,140,205,177,140,117,47,21,15,242,31,113,118,91,143,89,213,86,143,135,21,46,35,199,214,107,111,65,65,19,26,171,130,16,19,102,145,210,210,61,51,169,148,169,118,182,106,107,253,100,214,232,52,103,180,96,249,254,71,6,11,119,48,129,213,223,205,93,20,117,26,187,32,151,212,137,203,17,237,208,150,72,23,225,235,122,188,34,105,115,0,160,168,251,191,22,242,238,207,74,142,154,66,94,149,191,215,194,134,6,165,244,167,233,241],[1,207,77,250,146,127,242,229,44,172,182,201,183,242,32,242,182,129,233,10,8,180,23,191,163,21,238,158,5,27,216,146,253,173,127,99,95,168,209,132,242,196,242,34,25,25,249,211,51,236,164,153,175,61,65,150,82,251,174,102,186,47,195,82,44,90,252,184,74,89,251,177,254,108,151,136,230,220,93,224,173,247,244,116,132,59,170,215,194,30,87,84,166,147,57,156,201,207,132,203,222,191,253,15,19,228,173,81,156,4,51,121,227,159,50,18,148,129,205,42,42,227,252,138,62,176,115,227,253,52,125,110,178,167,132,244,14,116,195,194,172,44,45,63,38,121,215,136,68,230,21,108,133,159,197,179,94,78,233,107,236,114,92,165,248,22,124,161,23,142,236,224,175,233,134,25,97,150,131,61,220,203,104,154,199,247,146,47,205,56,209,0,133,132,18,103,136,8,202,37,29,100,105,12,232,74,33,6,255,202,96,170,52,229,244,4,235,2,201,125,86,168,179,224,130,81,54,221,185,184,187,141,0,114,98,38,70,225,228,60,157,53,210,238,60,216,215,154,48,73,3,157,192,245,81,170,49],[1,3,244,229,158,71,18,146,198,202,27,2,231,37,13,145,243,84,112,220,61,174,4,175,104,200,64,146,193,20,174,126,42,157,168,76,165,21,50,216,82,211,180,73,244,54,227,200,19,157,25,228,81,37,64,201,19,138,175,50,246,169,11,45,74,194,131,236,127,177,41,242,130,55,112,182,98,22,99,48,153,83,161,250,65,89,3,97,6,5,171,54,223,87,98,103,23,200,212,177,140,155,151,252,125,45,176,55,92,41,56,2,252,32,149,60,3,168,209,193,23,168,230,182,72,193,230,224,5,15,58,63,93,196,33,93,76,188,30,70,31,136,64,204,223,2,230,210,243,255,135,193,52,132,248,160,22,18,164,71,77,80,112,229,120,116,210,225,2,19,139,35,0,214,5,246,9,106,136,204,0,148,97,21,222,153,57,177,162,11,243,252,7,242,34,239,245,50,104,74,221,92,73,13,142,10,184,250,246,167,240,46,230,86,207,181,12,133,81,119,143,164,88,114,223,243,179,208,175,84,161,27,11,225,36,37,177,112,85,81,184,163,223,159,36,9,247,20,13,230,215,108,117,35,99,117,211]]}," + + "\"requested_proof\":{\"revealed_attrs\":{\"attr1_uuid\":[\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\",\"Alex\",\"1139481716457488690172217916278103335\"]},\"unrevealed_attrs\":{},\"self_attested_attrs\":{},\"predicates\":{\"predicate1_uuid\":\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\"}}}"; + + Anoncreds.verifierVerifyProof(proofRequest, proofJson, schemasJson, claimDefsJson, revocRegsJson).get(); + } + + @Test + public void testVerifierVerifyProofWorksForWrongProof() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String proofJson = "{\"proofs\":{\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\":{\"proof\":{\"primary_proof\":{\"eq_proof\":\"a_prime\":\"47629821806628155353444789773246165920681315271529392722265555946090524267165563309836167110610840740533588118152308411732923636370660640410661034994521654033599863817144282118006097899736622728860229305231675970853294584911572355833537271010861501353858292189045263114095480601737776505186511389129055847562085611741257601964074827979121349153316235245772819207422031038042586202074331681302501661153569340935741290924699468188826629478130140797677338573924284871118002193526319478550852287453975107498037063076866410320160118555629090040954555043934303307652160345244864713226315470541231435958298648179413077988340\",\"e\":\"13427639393364185909415877973872458621259927563729922146828001652769380799419438410309469022979920689628523901764614163117469683925816443\",\"v\":\"852136445143816932026946294488424887907102968158908948827421962603492187508454543239422067899916472317305416590471170842186669606584356963437132366711335927890209765986844538775191207999204354235774464468525274918097404114453069375363594310105209141774763909570100638835926337238009617444858777301355087706167735590386774813901740600054753028260344014744801229032610106838480523182317262113911183640784111960909501662169298536941919854667754097841344375972975021196106884215734228415868248724905018661498061287694439466570946597514142085096419985189064172035527690786158872698717583830848410994616274586162550376126607414773916066374234063208380831144157533076866210628625236440222547584539349936639548061601416341705483504386186280800509889531835172071717956251546280392606775903107774727736794828168898273891724336881907672405328368540895104468091907771325910937575557566831844131159128453840354307814975621978196047820\",\"m\":{\"age\":\"1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662\",\"height\":\"7064132689652704067914104576495132313294680087958177180391515757079548676035445873279966783996928425154050462229933823707574545166617858646442019030600136959459527533262821184869\",\"sex\":\"16084497853957041205729191269508720470626311156190485518484640641677445098603656354458362520541393995692536218820724164533958162674375198846036330444513484319280148335515891811530\"},\"m1\":\"154906224259819061652290487122980839849626068919893070220438585977323162319993111920906032317552959103520053742608858935542877608981244065301675821390065831113115709272412144796159984624494428122971995557415296140268002332169405587907128359886810433617416529821500995701094400375272097687818064435577784795275\",\"m2\":\"13805395408072590464827983892588030341708765524663545700917462089376137940485022437657208204460048097312372685954050370540389593952001973312378647790917367330461398089529292217752\"},\"ge_proofs\":[{\"u\":{\"1\":\"7698818972783845439601187851976452936638792889455287252542709653271706844173743185409084669157965935169942655008606334521674712818637940377261656468700786810566551698412412949418\",\"0\":\"11703047052430512223413711314521545616119146623040600935686474696241801697819280425232876917607198335376453682738553665221410353412906194951254558355994401995990233992518110582450\",\"3\":\"13210777821918317858818819091924507295018522783042111457450035423463340571245465760486275059291363621513532153389441883097799049597687545496359999443320001567152794884095192951040\",\"2\":\"15219471780524079156861690098171693383497641272226737821992208834301871102152362116211452788300889697214391366996966539871625433480959011635688106136537800706217506402845296449689\"},\"r\":{\"1\":\"46043242109380749151527145850513330956077996622769158245225343392397735706292106535150958053995712629189143692293204979798837951212291825184346767969751978730000071952944305252032332015837054475531407691352179423131405515518588355918925056889302269768343499864256747177988825578647189563088068257214198650437730618330249172716051559993880468542083352885474175039320848153156858562341041960950299312991459780503345784440261679263045723337629951517601461685539857683027034345542399365706329805317943096391758978877658949910614447086409173234155028671453929715706057153381022697673192590033507204548864311227048268516889390503318015295207078022755834130221198717787608473222789491216667698651180077661375273569115943192\",\"0\":\"135472587547410377947826119498467634347118057359097899596599164976338466445104141784869016998150489852448547539824768048351359572626675997498079394825940306636285481821620973655797996638210760710325933304918452142858879806106214845499670718704532018129553348815327362843246706518826311676917538452317818631484884032929252959289913274829848084561421467966320595980172006456003183536232790787521924655750157145207798486087511869939940023266736153366338179116840490184005332351004990854691988404031259910319601383696749511809898297656135548118786342107367065232798999979296280467063561892962526945512167505847049907450058650930480352253243357594344686769208712964458923557777584158831146374282687397585726706489164423632\",\"DELTA\":\"93540839493959971552865423901789226093328763011922445919928571946113703515842729132879472109395228387208764738970926484618949870591214627692618668077375153559192701474693025462226656116549337248146652482501255820930607033869432220667968682424554711616471973627651716863421554516577716366331699848682958681216261888139409101603059124344125075525791543312721162515584942523419876134808829569829529457617639955678189490257208141837196965948342373022812790844435050648360150869293836349223060722858500537182872294143846213258360218898475766641125493477502149553491502593654061863323857297998048614447925371606038801933864960337435890254277043261512846682042139570000962051463878026338583242360548041329046695667868842400\",\"3\":\"1227675452527605924725300993571504188580051470857656204064614533296779844072852823820754766175236321050062349182891221840452517985644028521499240739391613871973822807731772613052644168369405390658793869751915172749739844553410726807277698347769400977274750672880389943392076308065414059539317340070691852044062594715307024113666759844200606183662256825096857658837519571386467051003466014468855293015652584667669998830524947537781865745830650392641812221679438090257444660715937570193098993118585554478799821072396238689063767016402460690760792908977364175126682041704095200572282644311025594681667826054722587271200221036938804846621444065128275082392082327596239358623150786484106872933657139420542280145197712634108\",\"2\":\"596248147592834822582469335300585333722415132713749620075902332764163096347819006925876158892694742461036531935093982309708492066217459300117157420442081698140277277546563570823996272914068575482008392971932777453900260626542725308060927710122631763045025742980634216666560934260634907599194353151523256914796667535940073668465664206971169038864484235442207811974981191879443614478897291543702607764944403808380921189291059195014621592027660463072969363556421687131446107696579365265893962197300447027501604372738056016734644378437907931412654753728514905671605635291285742886484416973884856055084605172305967034292646171874483670469193852404511746786039743401185954843446037600121496137915619789351744485264614840070\"},\"mj\":\"1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662\",\"alpha\":\"76727612740067576380015106087224381023260815407331375101920043509817863645705120013304683427627332447210083684516403565749916480947649443674885388155460323163682547865307733144184097845709556309570345707127872162476432029772452433292049079349274445907295491125915363620615679995457134810061392296263970553630102299601689685622244925494554558218277670233361938142224820526392365740420502452466959099546877778248089664282581792213376636587293479012783947088070052463503335266180110771978445892744225891676396288437005847308189508347446490710626231658457908472341606549292437553353163031111068977301305043175839949352742711874426231072729977019365761072816602400121302646283352164756787266537474728685656685493249314400351742964904006326192403855909148605656818024621453179832395687665671245528217931951331393482249182516107670379946496778373\",\"t\":{\"1\":\"37203689290881948278188715497642400459048942241931994079434400288578680362970117779048886269388440270597283202033458042171954610700745461571112086648991639439510380585728148682202768590972068041537531136529323260832899360551065706810590032715173070285762675403853992183366951113799098912676809373169763887110420539387555392787590966452796271491986622992160642135480293110112269570862265489120557014181468118619500321000966443141863893743211690388599242584469856365803370202569641902205925191670838354052104480074127555862332399641076324738839120815544432811566503174551735326387678621283249883091766325861497740614317\",\"3\":\"58486787977689017034592833190899828017343431922483563651969628402499947729293364026001243898136737211851089198526360764391403150763769829047179796728616126204105160762333590343947446892105646111520243793053992399512412375936746396187319527051818920531870855183738837254656664620975569939859368862778444291640228229744805843388153451336792379036403300211151424879060241580540910888241769468335914016289938374111481091198264912969768783884602931940994543804730631920434719776196148182987249363641941951160704928605829395517074202388967815738516252602903999010405305463910751219873354588685197134114358234107748126140977\",\"0\":\"60771874648036182010335841594233428920565254732600738082343398028553347795361460295011584446745121430144172025428394361648540904134739046923992231536160801306934272250969829886396340824213814702904457884984387666505055153957942221822193548673145705543973635530652570436109428474727638128773540793530691399549837156239786231362112148914687724325416768262058486101761972044802628459748878200584371058300150212485731451700436345975266860685549673168984700174294811561393162860595319582236734968601457003780816977537443267217411297266600994916897237305128142313335280264655603445636393371224354539882875937093696844430903\",\"DELTA\":\"32816484171372208266594641116109072545171919234551585018140151846920408763078147655907777031259225522515086979967895258126318315788662577171150780535509410112003001556402222994276811926864642497249250763185467678044678144507739529818566125668667424447792097244624010084189629269472698722402896445274092470014229247479740671263651727480322483037149584904549203417226525624083290572692241241259382947122018271686649224741832992966652878170311798126004447080305528487720923103595513611363001766063956060990267107048028416069435287244770875463867263571308182619338433913487209319707428378896314619624990311543563016697299\",\"2\":\"36428320569485697540634597755814766104888687488985202673924762266313135133244610404742081973550848160712054769198012193456278135847215508952327879544434490828380496286187725750283788811367824465072001959950807751252194618152990469069074061195618692339915840384087350671392595652921761835083158086795163935060896053332506433434451836095710383871272788002621913967538399141417857031787255744141437237474972197102809365346359345477248611632307159641948507043668113827177494748159094045928919209335044052792843664865311991178972383241855607627188111601119780878072683890170539599447876998109080150992209773901144245398001\"},\"predicate\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}}]},\"non_revoc_proof\":null},\"issuer_did\":\"NcYxiDXkpYi6ov5FcYDi1e\",\"revoc_reg_seq_no\":null}},\"aggregated_proof\":{\"c_hash\":\"33103550379681684069592829341967479618752165928802550870585275205292715916069\",\"c_list\":[[1,121,77,5,144,154,14,192,190,190,145,180,128,71,22,60,168,20,46,163,139,194,71,165,220,188,121,76,25,146,231,114,65,54,69,68,19,200,250,192,47,123,157,132,74,50,28,69,226,195,243,118,45,63,237,197,216,202,206,101,33,56,225,200,128,3,89,12,182,38,113,221,165,119,228,201,156,201,172,136,59,64,51,72,164,198,49,228,223,117,80,64,166,226,37,8,29,146,186,80,210,119,76,252,4,255,62,218,112,163,164,147,247,190,108,76,140,191,76,217,214,184,152,179,193,149,15,70,197,46,90,60,255,247,197,219,252,73,76,0,125,104,114,22,182,161,110,36,162,103,27,42,88,18,161,237,198,43,177,189,181,86,135,207,71,114,0,26,175,12,199,125,25,124,178,87,36,208,251,15,191,127,202,148,152,43,142,92,191,7,89,153,130,195,223,248,176,109,97,164,126,162,181,124,237,130,155,197,66,59,40,197,72,84,32,100,64,55,227,60,214,143,200,200,89,115,236,172,145,56,100,73,20,242,233,95,130,58,112,153,120,115,119,42,199,30,205,88,223,42,196,184,41,19,100,19,244],[1,225,103,238,42,147,91,191,110,69,154,53,57,156,124,43,174,155,76,202,193,98,128,38,207,126,66,70,161,96,109,127,174,44,203,198,177,238,118,117,89,227,170,155,44,251,35,119,219,29,100,173,26,144,95,50,177,4,40,234,117,174,210,192,172,57,160,198,42,199,212,243,240,114,59,91,207,68,57,38,198,2,73,18,16,209,182,145,206,71,17,69,222,49,36,120,72,117,169,107,238,208,235,216,24,183,201,81,15,83,242,45,136,184,166,26,142,136,228,58,229,235,88,169,238,134,205,96,85,9,122,53,147,100,183,114,92,54,125,178,125,75,127,116,50,88,109,152,22,4,121,252,190,18,190,130,143,138,59,231,38,131,176,54,19,194,218,67,144,122,91,43,86,73,233,48,193,30,183,183,191,238,216,167,101,28,185,43,118,64,242,16,62,239,177,27,109,144,67,221,175,202,4,92,130,74,24,20,151,15,227,225,142,71,145,46,192,248,87,57,183,142,253,52,20,56,153,220,234,25,67,116,225,179,211,116,161,37,64,34,48,155,1,1,159,157,37,31,202,19,229,152,23,138,183,126,55],[1,38,181,193,191,72,2,239,34,83,49,36,179,160,82,112,172,98,255,63,60,22,177,249,67,215,220,198,181,7,49,254,133,243,221,214,47,64,229,82,11,94,175,57,86,152,229,192,184,96,136,116,226,123,128,217,23,244,19,204,36,44,123,208,88,24,217,120,145,139,25,233,227,5,119,90,47,147,1,115,92,39,119,194,167,17,229,39,163,167,237,14,116,234,106,252,216,54,33,233,21,54,183,130,144,161,177,142,177,240,51,73,21,202,188,103,244,153,204,219,123,231,139,135,189,155,143,28,4,180,44,148,0,27,103,26,13,203,31,32,166,67,84,87,23,72,234,236,20,1,84,70,86,76,192,164,235,124,86,128,78,230,119,155,95,121,125,20,244,181,121,250,169,9,67,85,213,177,139,111,187,183,114,165,249,177,161,181,175,46,226,66,86,84,124,86,69,143,217,158,161,30,107,133,44,239,89,209,24,150,1,238,122,144,138,179,121,114,90,13,212,209,60,126,37,62,177,180,131,222,168,2,201,156,169,220,224,53,8,203,220,215,163,104,195,184,73,35,241,182,177,80,41,253,230,90,173],[1,32,145,96,219,241,190,19,195,129,219,50,148,152,107,12,189,225,103,171,149,252,193,243,136,132,195,44,19,20,247,140,160,91,230,78,31,242,85,213,65,185,1,91,12,69,118,80,26,135,102,131,4,108,130,230,83,91,176,249,196,56,128,127,82,72,106,49,211,94,133,40,86,72,42,187,199,216,191,223,208,206,121,118,15,167,255,228,57,206,158,217,64,205,212,178,8,248,129,183,221,98,70,54,37,55,47,81,120,59,186,238,165,0,70,173,137,193,232,180,125,211,237,182,249,191,173,107,129,164,148,231,116,225,66,66,71,156,39,248,164,253,234,140,205,177,140,117,47,21,15,242,31,113,118,91,143,89,213,86,143,135,21,46,35,199,214,107,111,65,65,19,26,171,130,16,19,102,145,210,210,61,51,169,148,169,118,182,106,107,253,100,214,232,52,103,180,96,249,254,71,6,11,119,48,129,213,223,205,93,20,117,26,187,32,151,212,137,203,17,237,208,150,72,23,225,235,122,188,34,105,115,0,160,168,251,191,22,242,238,207,74,142,154,66,94,149,191,215,194,134,6,165,244,167,233,241],[1,207,77,250,146,127,242,229,44,172,182,201,183,242,32,242,182,129,233,10,8,180,23,191,163,21,238,158,5,27,216,146,253,173,127,99,95,168,209,132,242,196,242,34,25,25,249,211,51,236,164,153,175,61,65,150,82,251,174,102,186,47,195,82,44,90,252,184,74,89,251,177,254,108,151,136,230,220,93,224,173,247,244,116,132,59,170,215,194,30,87,84,166,147,57,156,201,207,132,203,222,191,253,15,19,228,173,81,156,4,51,121,227,159,50,18,148,129,205,42,42,227,252,138,62,176,115,227,253,52,125,110,178,167,132,244,14,116,195,194,172,44,45,63,38,121,215,136,68,230,21,108,133,159,197,179,94,78,233,107,236,114,92,165,248,22,124,161,23,142,236,224,175,233,134,25,97,150,131,61,220,203,104,154,199,247,146,47,205,56,209,0,133,132,18,103,136,8,202,37,29,100,105,12,232,74,33,6,255,202,96,170,52,229,244,4,235,2,201,125,86,168,179,224,130,81,54,221,185,184,187,141,0,114,98,38,70,225,228,60,157,53,210,238,60,216,215,154,48,73,3,157,192,245,81,170,49],[1,3,244,229,158,71,18,146,198,202,27,2,231,37,13,145,243,84,112,220,61,174,4,175,104,200,64,146,193,20,174,126,42,157,168,76,165,21,50,216,82,211,180,73,244,54,227,200,19,157,25,228,81,37,64,201,19,138,175,50,246,169,11,45,74,194,131,236,127,177,41,242,130,55,112,182,98,22,99,48,153,83,161,250,65,89,3,97,6,5,171,54,223,87,98,103,23,200,212,177,140,155,151,252,125,45,176,55,92,41,56,2,252,32,149,60,3,168,209,193,23,168,230,182,72,193,230,224,5,15,58,63,93,196,33,93,76,188,30,70,31,136,64,204,223,2,230,210,243,255,135,193,52,132,248,160,22,18,164,71,77,80,112,229,120,116,210,225,2,19,139,35,0,214,5,246,9,106,136,204,0,148,97,21,222,153,57,177,162,11,243,252,7,242,34,239,245,50,104,74,221,92,73,13,142,10,184,250,246,167,240,46,230,86,207,181,12,133,81,119,143,164,88,114,223,243,179,208,175,84,161,27,11,225,36,37,177,112,85,81,184,163,223,159,36,9,247,20,13,230,215,108,117,35,99,117,211]]},\"requested_proof\":{\"revealed_attrs\":{\"attr1_uuid\":[\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\",\"Alex\",\"1139481716457488690172217916278103335\"]},\"unrevealed_attrs\":{},\"self_attested_attrs\":{},\"predicates\":{\"predicate1_uuid\":\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\"}}}"; + + Boolean valid = Anoncreds.verifierVerifyProof(proofRequest, proofJson, schemasJson, claimDefsJson, revocRegsJson).get(); + assertFalse(valid); + } + + @Test + public void testVerifierVerifyProofWorksForInvalidProofJson() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String proofJson = "{\"proofs\":{\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\":{\"proof\":{\"primary_proof\":{\"eq_proof\":\"a_prime\":\"47629821806628155353444789773246165920681315271529392722265555946090524267165563309836167110610840740533588118152308411732923636370660640410661034994521654033599863817144282118006097899736622728860229305231675970853294584911572355833537271010861501353858292189045263114095480601737776505186511389129055847562085611741257601964074827979121349153316235245772819207422031038042586202074331681302501661153569340935741290924699468188826629478130140797677338573924284871118002193526319478550852287453975107498037063076866410320160118555629090040954555043934303307652160345244864713226315470541231435958298648179413077988340\",\"e\":\"13427639393364185909415877973872458621259927563729922146828001652769380799419438410309469022979920689628523901764614163117469683925816443\",\"v\":\"852136445143816932026946294488424887907102968158908948827421962603492187508454543239422067899916472317305416590471170842186669606584356963437132366711335927890209765986844538775191207999204354235774464468525274918097404114453069375363594310105209141774763909570100638835926337238009617444858777301355087706167735590386774813901740600054753028260344014744801229032610106838480523182317262113911183640784111960909501662169298536941919854667754097841344375972975021196106884215734228415868248724905018661498061287694439466570946597514142085096419985189064172035527690786158872698717583830848410994616274586162550376126607414773916066374234063208380831144157533076866210628625236440222547584539349936639548061601416341705483504386186280800509889531835172071717956251546280392606775903107774727736794828168898273891724336881907672405328368540895104468091907771325910937575557566831844131159128453840354307814975621978196047820\",\"m\":{\"age\":\"1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662\",\"height\":\"7064132689652704067914104576495132313294680087958177180391515757079548676035445873279966783996928425154050462229933823707574545166617858646442019030600136959459527533262821184869\",\"sex\":\"16084497853957041205729191269508720470626311156190485518484640641677445098603656354458362520541393995692536218820724164533958162674375198846036330444513484319280148335515891811530\"},\"m1\":\"154906224259819061652290487122980839849626068919893070220438585977323162319993111920906032317552959103520053742608858935542877608981244065301675821390065831113115709272412144796159984624494428122971995557415296140268002332169405587907128359886810433617416529821500995701094400375272097687818064435577784795275\",\"m2\":\"13805395408072590464827983892588030341708765524663545700917462089376137940485022437657208204460048097312372685954050370540389593952001973312378647790917367330461398089529292217752\"},\"ge_proofs\":[{\"u\":{\"1\":\"7698818972783845439601187851976452936638792889455287252542709653271706844173743185409084669157965935169942655008606334521674712818637940377261656468700786810566551698412412949418\",\"0\":\"11703047052430512223413711314521545616119146623040600935686474696241801697819280425232876917607198335376453682738553665221410353412906194951254558355994401995990233992518110582450\",\"3\":\"13210777821918317858818819091924507295018522783042111457450035423463340571245465760486275059291363621513532153389441883097799049597687545496359999443320001567152794884095192951040\",\"2\":\"15219471780524079156861690098171693383497641272226737821992208834301871102152362116211452788300889697214391366996966539871625433480959011635688106136537800706217506402845296449689\"},\"r\":{\"1\":\"46043242109380749151527145850513330956077996622769158245225343392397735706292106535150958053995712629189143692293204979798837951212291825184346767969751978730000071952944305252032332015837054475531407691352179423131405515518588355918925056889302269768343499864256747177988825578647189563088068257214198650437730618330249172716051559993880468542083352885474175039320848153156858562341041960950299312991459780503345784440261679263045723337629951517601461685539857683027034345542399365706329805317943096391758978877658949910614447086409173234155028671453929715706057153381022697673192590033507204548864311227048268516889390503318015295207078022755834130221198717787608473222789491216667698651180077661375273569115943192\",\"0\":\"135472587547410377947826119498467634347118057359097899596599164976338466445104141784869016998150489852448547539824768048351359572626675997498079394825940306636285481821620973655797996638210760710325933304918452142858879806106214845499670718704532018129553348815327362843246706518826311676917538452317818631484884032929252959289913274829848084561421467966320595980172006456003183536232790787521924655750157145207798486087511869939940023266736153366338179116840490184005332351004990854691988404031259910319601383696749511809898297656135548118786342107367065232798999979296280467063561892962526945512167505847049907450058650930480352253243357594344686769208712964458923557777584158831146374282687397585726706489164423632\",\"DELTA\":\"93540839493959971552865423901789226093328763011922445919928571946113703515842729132879472109395228387208764738970926484618949870591214627692618668077375153559192701474693025462226656116549337248146652482501255820930607033869432220667968682424554711616471973627651716863421554516577716366331699848682958681216261888139409101603059124344125075525791543312721162515584942523419876134808829569829529457617639955678189490257208141837196965948342373022812790844435050648360150869293836349223060722858500537182872294143846213258360218898475766641125493477502149553491502593654061863323857297998048614447925371606038801933864960337435890254277043261512846682042139570000962051463878026338583242360548041329046695667868842400\",\"3\":\"1227675452527605924725300993571504188580051470857656204064614533296779844072852823820754766175236321050062349182891221840452517985644028521499240739391613871973822807731772613052644168369405390658793869751915172749739844553410726807277698347769400977274750672880389943392076308065414059539317340070691852044062594715307024113666759844200606183662256825096857658837519571386467051003466014468855293015652584667669998830524947537781865745830650392641812221679438090257444660715937570193098993118585554478799821072396238689063767016402460690760792908977364175126682041704095200572282644311025594681667826054722587271200221036938804846621444065128275082392082327596239358623150786484106872933657139420542280145197712634108\",\"2\":\"596248147592834822582469335300585333722415132713749620075902332764163096347819006925876158892694742461036531935093982309708492066217459300117157420442081698140277277546563570823996272914068575482008392971932777453900260626542725308060927710122631763045025742980634216666560934260634907599194353151523256914796667535940073668465664206971169038864484235442207811974981191879443614478897291543702607764944403808380921189291059195014621592027660463072969363556421687131446107696579365265893962197300447027501604372738056016734644378437907931412654753728514905671605635291285742886484416973884856055084605172305967034292646171874483670469193852404511746786039743401185954843446037600121496137915619789351744485264614840070\"},\"mj\":\"1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662\",\"alpha\":\"76727612740067576380015106087224381023260815407331375101920043509817863645705120013304683427627332447210083684516403565749916480947649443674885388155460323163682547865307733144184097845709556309570345707127872162476432029772452433292049079349274445907295491125915363620615679995457134810061392296263970553630102299601689685622244925494554558218277670233361938142224820526392365740420502452466959099546877778248089664282581792213376636587293479012783947088070052463503335266180110771978445892744225891676396288437005847308189508347446490710626231658457908472341606549292437553353163031111068977301305043175839949352742711874426231072729977019365761072816602400121302646283352164756787266537474728685656685493249314400351742964904006326192403855909148605656818024621453179832395687665671245528217931951331393482249182516107670379946496778373\",\"t\":{\"1\":\"37203689290881948278188715497642400459048942241931994079434400288578680362970117779048886269388440270597283202033458042171954610700745461571112086648991639439510380585728148682202768590972068041537531136529323260832899360551065706810590032715173070285762675403853992183366951113799098912676809373169763887110420539387555392787590966452796271491986622992160642135480293110112269570862265489120557014181468118619500321000966443141863893743211690388599242584469856365803370202569641902205925191670838354052104480074127555862332399641076324738839120815544432811566503174551735326387678621283249883091766325861497740614317\",\"3\":\"58486787977689017034592833190899828017343431922483563651969628402499947729293364026001243898136737211851089198526360764391403150763769829047179796728616126204105160762333590343947446892105646111520243793053992399512412375936746396187319527051818920531870855183738837254656664620975569939859368862778444291640228229744805843388153451336792379036403300211151424879060241580540910888241769468335914016289938374111481091198264912969768783884602931940994543804730631920434719776196148182987249363641941951160704928605829395517074202388967815738516252602903999010405305463910751219873354588685197134114358234107748126140977\",\"0\":\"60771874648036182010335841594233428920565254732600738082343398028553347795361460295011584446745121430144172025428394361648540904134739046923992231536160801306934272250969829886396340824213814702904457884984387666505055153957942221822193548673145705543973635530652570436109428474727638128773540793530691399549837156239786231362112148914687724325416768262058486101761972044802628459748878200584371058300150212485731451700436345975266860685549673168984700174294811561393162860595319582236734968601457003780816977537443267217411297266600994916897237305128142313335280264655603445636393371224354539882875937093696844430903\",\"DELTA\":\"32816484171372208266594641116109072545171919234551585018140151846920408763078147655907777031259225522515086979967895258126318315788662577171150780535509410112003001556402222994276811926864642497249250763185467678044678144507739529818566125668667424447792097244624010084189629269472698722402896445274092470014229247479740671263651727480322483037149584904549203417226525624083290572692241241259382947122018271686649224741832992966652878170311798126004447080305528487720923103595513611363001766063956060990267107048028416069435287244770875463867263571308182619338433913487209319707428378896314619624990311543563016697299\",\"2\":\"36428320569485697540634597755814766104888687488985202673924762266313135133244610404742081973550848160712054769198012193456278135847215508952327879544434490828380496286187725750283788811367824465072001959950807751252194618152990469069074061195618692339915840384087350671392595652921761835083158086795163935060896053332506433434451836095710383871272788002621913967538399141417857031787255744141437237474972197102809365346359345477248611632307159641948507043668113827177494748159094045928919209335044052792843664865311991178972383241855607627188111601119780878072683890170539599447876998109080150992209773901144245398001\"},\"predicate\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}}]},\"non_revoc_proof\":null},\"issuer_did\":\"NcYxiDXkpYi6ov5FcYDi1e\",\"revoc_reg_seq_no\":null}},\"aggregated_proof\":{\"c_hash\":\"33103550379681684069592829341967479618752165928802550870585275205292715916069\",\"c_list\":[[1,121,77,5,144,154,14,192,190,190,145,180,128,71,22,60,168,20,46,163,139,194,71,165,220,188,121,76,25,146,231,114,65,54,69,68,19,200,250,192,47,123,157,132,74,50,28,69,226,195,243,118,45,63,237,197,216,202,206,101,33,56,225,200,128,3,89,12,182,38,113,221,165,119,228,201,156,201,172,136,59,64,51,72,164,198,49,228,223,117,80,64,166,226,37,8,29,146,186,80,210,119,76,252,4,255,62,218,112,163,164,147,247,190,108,76,140,191,76,217,214,184,152,179,193,149,15,70,197,46,90,60,255,247,197,219,252,73,76,0,125,104,114,22,182,161,110,36,162,103,27,42,88,18,161,237,198,43,177,189,181,86,135,207,71,114,0,26,175,12,199,125,25,124,178,87,36,208,251,15,191,127,202,148,152,43,142,92,191,7,89,153,130,195,223,248,176,109,97,164,126,162,181,124,237,130,155,197,66,59,40,197,72,84,32,100,64,55,227,60,214,143,200,200,89,115,236,172,145,56,100,73,20,242,233,95,130,58,112,153,120,115,119,42,199,30,205,88,223,42,196,184,41,19,100,19,244],[1,225,103,238,42,147,91,191,110,69,154,53,57,156,124,43,174,155,76,202,193,98,128,38,207,126,66,70,161,96,109,127,174,44,203,198,177,238,118,117,89,227,170,155,44,251,35,119,219,29,100,173,26,144,95,50,177,4,40,234,117,174,210,192,172,57,160,198,42,199,212,243,240,114,59,91,207,68,57,38,198,2,73,18,16,209,182,145,206,71,17,69,222,49,36,120,72,117,169,107,238,208,235,216,24,183,201,81,15,83,242,45,136,184,166,26,142,136,228,58,229,235,88,169,238,134,205,96,85,9,122,53,147,100,183,114,92,54,125,178,125,75,127,116,50,88,109,152,22,4,121,252,190,18,190,130,143,138,59,231,38,131,176,54,19,194,218,67,144,122,91,43,86,73,233,48,193,30,183,183,191,238,216,167,101,28,185,43,118,64,242,16,62,239,177,27,109,144,67,221,175,202,4,92,130,74,24,20,151,15,227,225,142,71,145,46,192,248,87,57,183,142,253,52,20,56,153,220,234,25,67,116,225,179,211,116,161,37,64,34,48,155,1,1,159,157,37,31,202,19,229,152,23,138,183,126,55],[1,38,181,193,191,72,2,239,34,83,49,36,179,160,82,112,172,98,255,63,60,22,177,249,67,215,220,198,181,7,49,254,133,243,221,214,47,64,229,82,11,94,175,57,86,152,229,192,184,96,136,116,226,123,128,217,23,244,19,204,36,44,123,208,88,24,217,120,145,139,25,233,227,5,119,90,47,147,1,115,92,39,119,194,167,17,229,39,163,167,237,14,116,234,106,252,216,54,33,233,21,54,183,130,144,161,177,142,177,240,51,73,21,202,188,103,244,153,204,219,123,231,139,135,189,155,143,28,4,180,44,148,0,27,103,26,13,203,31,32,166,67,84,87,23,72,234,236,20,1,84,70,86,76,192,164,235,124,86,128,78,230,119,155,95,121,125,20,244,181,121,250,169,9,67,85,213,177,139,111,187,183,114,165,249,177,161,181,175,46,226,66,86,84,124,86,69,143,217,158,161,30,107,133,44,239,89,209,24,150,1,238,122,144,138,179,121,114,90,13,212,209,60,126,37,62,177,180,131,222,168,2,201,156,169,220,224,53,8,203,220,215,163,104,195,184,73,35,241,182,177,80,41,253,230,90,173],[1,32,145,96,219,241,190,19,195,129,219,50,148,152,107,12,189,225,103,171,149,252,193,243,136,132,195,44,19,20,247,140,160,91,230,78,31,242,85,213,65,185,1,91,12,69,118,80,26,135,102,131,4,108,130,230,83,91,176,249,196,56,128,127,82,72,106,49,211,94,133,40,86,72,42,187,199,216,191,223,208,206,121,118,15,167,255,228,57,206,158,217,64,205,212,178,8,248,129,183,221,98,70,54,37,55,47,81,120,59,186,238,165,0,70,173,137,193,232,180,125,211,237,182,249,191,173,107,129,164,148,231,116,225,66,66,71,156,39,248,164,253,234,140,205,177,140,117,47,21,15,242,31,113,118,91,143,89,213,86,143,135,21,46,35,199,214,107,111,65,65,19,26,171,130,16,19,102,145,210,210,61,51,169,148,169,118,182,106,107,253,100,214,232,52,103,180,96,249,254,71,6,11,119,48,129,213,223,205,93,20,117,26,187,32,151,212,137,203,17,237,208,150,72,23,225,235,122,188,34,105,115,0,160,168,251,191,22,242,238,207,74,142,154,66,94,149,191,215,194,134,6,165,244,167,233,241],[1,207,77,250,146,127,242,229,44,172,182,201,183,242,32,242,182,129,233,10,8,180,23,191,163,21,238,158,5,27,216,146,253,173,127,99,95,168,209,132,242,196,242,34,25,25,249,211,51,236,164,153,175,61,65,150,82,251,174,102,186,47,195,82,44,90,252,184,74,89,251,177,254,108,151,136,230,220,93,224,173,247,244,116,132,59,170,215,194,30,87,84,166,147,57,156,201,207,132,203,222,191,253,15,19,228,173,81,156,4,51,121,227,159,50,18,148,129,205,42,42,227,252,138,62,176,115,227,253,52,125,110,178,167,132,244,14,116,195,194,172,44,45,63,38,121,215,136,68,230,21,108,133,159,197,179,94,78,233,107,236,114,92,165,248,22,124,161,23,142,236,224,175,233,134,25,97,150,131,61,220,203,104,154,199,247,146,47,205,56,209,0,133,132,18,103,136,8,202,37,29,100,105,12,232,74,33,6,255,202,96,170,52,229,244,4,235,2,201,125,86,168,179,224,130,81,54,221,185,184,187,141,0,114,98,38,70,225,228,60,157,53,210,238,60,216,215,154,48,73,3,157,192,245,81,170,49],[1,3,244,229,158,71,18,146,198,202,27,2,231,37,13,145,243,84,112,220,61,174,4,175,104,200,64,146,193,20,174,126,42,157,168,76,165,21,50,216,82,211,180,73,244,54,227,200,19,157,25,228,81,37,64,201,19,138,175,50,246,169,11,45,74,194,131,236,127,177,41,242,130,55,112,182,98,22,99,48,153,83,161,250,65,89,3,97,6,5,171,54,223,87,98,103,23,200,212,177,140,155,151,252,125,45,176,55,92,41,56,2,252,32,149,60,3,168,209,193,23,168,230,182,72,193,230,224,5,15,58,63,93,196,33,93,76,188,30,70,31,136,64,204,223,2,230,210,243,255,135,193,52,132,248,160,22,18,164,71,77,80,112,229,120,116,210,225,2,19,139,35,0,214,5,246,9,106,136,204,0,148,97,21,222,153,57,177,162,11,243,252,7,242,34,239,245,50,104,74,221,92,73,13,142,10,184,250,246,167,240,46,230,86,207,181,12,133,81,119,143,164,88,114,223,243,179,208,175,84,161,27,11,225,36,37,177,112,85,81,184,163,223,159,36,9,247,20,13,230,215,108,117,35,99,117,211]]},\"requested_proof\":{\"revealed_attrs\":{\"attr1_uuid\":[\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\",\"Alex\",\"1139481716457488690172217916278103335\"]},\"unrevealed_attrs\":{},\"self_attested_attrs\":{},\"predicates\":{\"predicate1_uuid\":\"claim::277478db-bf57-42c3-8530-b1b13cfe0bfd\"}}}"; + + Anoncreds.verifierVerifyProof(proofRequest, proofJson, schemasJson, claimDefsJson, revocRegsJson).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/demo/AgentDemoTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/demo/AgentDemoTest.java new file mode 100644 index 0000000000..52dc56aaee --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/demo/AgentDemoTest.java @@ -0,0 +1,131 @@ +package org.hyperledger.indy.sdk.demo; + +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.agent.Agent; +import org.hyperledger.indy.sdk.agent.Agent.Connection; +import org.hyperledger.indy.sdk.agent.Agent.Listener; +import org.hyperledger.indy.sdk.agent.AgentObservers.ConnectionObserver; +import org.hyperledger.indy.sdk.agent.AgentObservers.MessageObserver; +import org.hyperledger.indy.sdk.ledger.Ledger; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.pool.PoolJSONParameters; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusJSONParameters; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.CompletableFuture; + + +public class AgentDemoTest extends IndyIntegrationTest { + + @Test + public void testAgentDemo() throws Exception { + String endpoint = "127.0.0.1:9801"; + String listenerWalletName = "listenerWallet"; + String trusteeWalletName = "trusteeWallet"; + String message = "test"; + + //1. Create and Open Pool + String poolName = PoolUtils.createPoolLedgerConfig(); + + PoolJSONParameters.OpenPoolLedgerJSONParameter config2 = new PoolJSONParameters.OpenPoolLedgerJSONParameter(null, null, null); + Pool pool = Pool.openPoolLedger(poolName, config2.toJson()).get(); + + //2. Create and Open Listener Wallet + Wallet.createWallet(poolName, listenerWalletName, "default", null, null).get(); + Wallet listenerWallet = Wallet.openWallet(listenerWalletName, null, null).get(); + + //3. Create and Open Trustee Wallet + Wallet.createWallet(poolName, trusteeWalletName, "default", null, null).get(); + Wallet trusteeWallet = Wallet.openWallet(trusteeWalletName, null, null).get(); + Wallet senderWallet = trusteeWallet; + + //4. Create My Did + SignusResults.CreateAndStoreMyDidResult createMyDidResult = Signus.createAndStoreMyDid(listenerWallet, "{}").get(); + String listenerDid = createMyDidResult.getDid(); + String listenerVerkey = createMyDidResult.getVerkey(); + String listenerPk = createMyDidResult.getPk(); + + //5. Create Their Did from Trustee seed + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(trusteeWallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + String senderDid = trusteeDid; + + // 6. Prepare and Send NYM request with signing + String nymRequest = Ledger.buildNymRequest(trusteeDid, listenerDid, listenerVerkey, null, null).get(); + Ledger.signAndSubmitRequest(pool, trusteeWallet, trusteeDid, nymRequest).get(); + + // 7. Prepare and Send Attrib for listener (will be requested from ledger and used by sender at start connection) + String attribRequest = Ledger.buildAttribRequest(listenerDid, listenerDid, null, + String.format("{\"endpoint\":{\"ha\":\"%s\",\"verkey\":\"%s\"}}", endpoint, listenerPk), null).get(); + Ledger.signAndSubmitRequest(pool, listenerWallet, listenerDid, attribRequest).get(); + + CompletableFuture clientToServerMsgFuture = new CompletableFuture(); + + final MessageObserver messageObserver = new MessageObserver() { + + public void onMessage(Connection connection, String message) { + + System.out.println("Received message '" + message + "' on connection " + connection); + } + }; + + final MessageObserver messageObserverForIncoming = new MessageObserver() { + + public void onMessage(Connection connection, String receivedMessage) { + + System.out.println("Received message '" + receivedMessage + "' on incoming connection " + connection); + + clientToServerMsgFuture.complete(receivedMessage); + } + }; + + final ConnectionObserver incomingConnectionObserver = new ConnectionObserver() { + + public MessageObserver onConnection(Listener listener, Connection connection, String senderDid, String receiverDid) { + + System.out.println("New connection " + connection); + + return messageObserverForIncoming; + } + }; + + // 8. start listener on endpoint + Listener activeListener = Agent.agentListen(endpoint, incomingConnectionObserver).get(); + + // 9. Allow listener accept incoming connection for specific DID (listener_did) + activeListener.agentAddIdentity(pool, listenerWallet, listenerDid).get(); + + // 10. Initiate connection from sender to listener + Connection connection = Agent.agentConnect(pool, senderWallet, senderDid, listenerDid, messageObserver).get(); + + // 11. Send test message from sender to listener + connection.agentSend("test").get(); + + Assert.assertEquals(message, clientToServerMsgFuture.get()); + + // 12. Close connection + connection.agentCloseConnection(); + + // 13. Close listener + activeListener.agentCloseListener(); + + // 14. Close and delete Issuer Wallet + listenerWallet.closeWallet().get(); + Wallet.deleteWallet(listenerWalletName, null).get(); + + // 15. Close and delete Prover Wallet + trusteeWallet.closeWallet().get(); + Wallet.deleteWallet(trusteeWalletName, null).get(); + + //16. Close Pool + pool.closePoolLedger().get(); + } +} \ No newline at end of file diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/demo/AnoncredsDemoTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/demo/AnoncredsDemoTest.java new file mode 100644 index 0000000000..52203c5ba6 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/demo/AnoncredsDemoTest.java @@ -0,0 +1,592 @@ +package org.hyperledger.indy.sdk.demo; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.anoncreds.Anoncreds; +import org.hyperledger.indy.sdk.anoncreds.AnoncredsResults; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.pool.PoolJSONParameters; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.json.JSONArray; +import org.json.JSONObject; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNotNull; + +public class AnoncredsDemoTest extends IndyIntegrationTest { + + @Rule + public Timeout globalTimeout = new Timeout(1, TimeUnit.MINUTES); + + private Pool pool; + private Wallet issuerWallet; + private Wallet proverWallet; + private String poolName; + + @Before + public void createWallet() throws Exception { + //1. Create and Open Pool + poolName = PoolUtils.createPoolLedgerConfig(); + + PoolJSONParameters.OpenPoolLedgerJSONParameter config2 = new PoolJSONParameters.OpenPoolLedgerJSONParameter(null, null, null); + pool = Pool.openPoolLedger(poolName, config2.toJson()).get(); + + //2. Issuer Create and Open Wallet + Wallet.createWallet(poolName, "issuerWallet", "default", null, null).get(); + issuerWallet = Wallet.openWallet("issuerWallet", null, null).get(); + + //3. Prover Create and Open Wallet + Wallet.createWallet(poolName, "proverWallet", "default", null, null).get(); + proverWallet = Wallet.openWallet("proverWallet", null, null).get(); + } + + @After + public void deleteWallet() throws Exception { + issuerWallet.closeWallet().get(); + Wallet.deleteWallet("issuerWallet", null).get(); + + proverWallet.closeWallet().get(); + Wallet.deleteWallet("proverWallet", null).get(); + + pool.closePoolLedger(); + } + + @Test + public void testAnoncredsDemo() throws Exception { + + //4. Issuer create ClaimDef + String schemaJson = "{\n" + + " \"seqNo\":1,\n" + + " \"data\": {\n" + + " \"name\":\"gvt\",\n" + + " \"version\":\"1.0\",\n" + + " \"keys\":[\"age\",\"sex\",\"height\",\"name\"]\n" + + " }\n" + + " }"; + String issuerDid = "NcYxiDXkpYi6ov5FcYDi1e"; + + String claimDef = Anoncreds.issuerCreateAndStoreClaimDef(issuerWallet, issuerDid, schemaJson, null, false).get(); + assertNotNull(claimDef); + + //5. Prover create Master Secret + String masterSecret = "masterSecretName"; + Anoncreds.proverCreateMasterSecret(proverWallet, masterSecret).get(); + + //6. Prover store Claim Offer + String claimOffer = String.format("{\"issuer_did\":\"%s\", \"schema_seq_no\":%d}", issuerDid, 1); + Anoncreds.proverStoreClaimOffer(proverWallet, claimOffer).get(); + + //7. Prover get Claim Offers + String claimOfferFilter = String.format("{\"issuer_did\":\"%s\"}", issuerDid); + String claimOffersJson = Anoncreds.proverGetClaimOffers(proverWallet, claimOfferFilter).get(); + + JSONArray claimOffersObject = new JSONArray(claimOffersJson); + assertEquals(claimOffersObject.length(), 1); + + JSONObject claimOfferObject = claimOffersObject.getJSONObject(0); + String claimOfferJson = claimOfferObject.toString(); + + //8. Prover create ClaimReq + String proverDid = "BzfFCYk"; + String claimReq = Anoncreds.proverCreateClaimReq(proverWallet, proverDid, claimOfferJson, claimDef, masterSecret).get(); + assertNotNull(claimReq); + + //9. Issuer create Claim + String claimAttributesJson = "{\n" + + " \"sex\":[\"male\",\"5944657099558967239210949258394887428692050081607692519917050011144233115103\"],\n" + + " \"name\":[\"Alex\",\"1139481716457488690172217916278103335\"],\n" + + " \"height\":[\"175\",\"175\"],\n" + + " \"age\":[\"28\",\"28\"]\n" + + " }"; + + AnoncredsResults.IssuerCreateClaimResult createClaimResult = Anoncreds.issuerCreateClaim(issuerWallet, claimReq, claimAttributesJson, - 1, - 1).get(); + assertNotNull(createClaimResult); + String claimJson = createClaimResult.getClaimJson(); + + //10. Prover store Claim + Anoncreds.proverStoreClaim(proverWallet, claimJson).get(); + + //11. Prover gets Claims for Proof Request + String proofRequestJson = "{\n" + + " \"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1,\"name\":\"name\"},\n" + + " \"attr2_uuid\":{\"schema_seq_no\":1,\"name\":\"sex\"}},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}}\n" + + " }"; + + String claimsForProofJson = Anoncreds.proverGetClaimsForProofReq(proverWallet, proofRequestJson).get(); + assertNotNull(claimsForProofJson); + + JSONObject claimsForProof = new JSONObject(claimsForProofJson); + JSONArray claimsForAttribute1 = claimsForProof.getJSONObject("attrs").getJSONArray("attr1_uuid"); + JSONArray claimsForAttribute2 = claimsForProof.getJSONObject("attrs").getJSONArray("attr1_uuid"); + JSONArray claimsForPredicate = claimsForProof.getJSONObject("predicates").getJSONArray("predicate1_uuid"); + + assertEquals(claimsForAttribute1.length(), 1); + assertEquals(claimsForAttribute2.length(), 1); + assertEquals(claimsForPredicate.length(), 1); + + String claimUuid = claimsForAttribute1.getJSONObject(0).getString("claim_uuid"); + + //12. Prover create Proof + String selfAttestedValue = "yes"; + String requestedClaimsJson = String.format("{\n" + + " \"self_attested_attributes\":{\"self1\":\"%s\"},\n" + + " \"requested_attrs\":{\"attr1_uuid\":[\"%s\", true],\n" + + " \"attr2_uuid\":[\"%s\", false]},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":\"%s\"}\n" + + " }", selfAttestedValue, claimUuid, claimUuid, claimUuid); + + String schemasJson = String.format("{\"%s\":%s}", claimUuid, schemaJson); + String claimDefsJson = String.format("{\"%s\":%s}", claimUuid, claimDef); + String revocRegsJson = "{}"; + + + String proofJson = Anoncreds.proverCreateProof(proverWallet, proofRequestJson, requestedClaimsJson, schemasJson, + masterSecret, claimDefsJson, revocRegsJson).get(); + assertNotNull(proofJson); + + JSONObject proof = new JSONObject(proofJson); + + //13. Verifier verify Proof + assertEquals("Alex", + proof.getJSONObject("requested_proof").getJSONObject("revealed_attrs").getJSONArray("attr1_uuid").getString(1)); + + assertNotNull(proof.getJSONObject("requested_proof").getJSONObject("unrevealed_attrs").getString("attr2_uuid")); + + assertEquals(selfAttestedValue, proof.getJSONObject("requested_proof").getJSONObject("self_attested_attrs").getString("self1")); + + Boolean valid = Anoncreds.verifierVerifyProof(proofRequestJson, proofJson, schemasJson, claimDefsJson, revocRegsJson).get(); + assertTrue(valid); + } + + @Test + public void testAnoncredsWorksForMultiplyIssuerSingleProver() throws Exception { + + String issuerDid = "NcYxiDXkpYi6ov5FcYDi1e"; + String issuerDid2 = "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW"; + + Wallet issuerGvtWallet = issuerWallet; + + //1. Issuer2 Create and Open Wallet + Wallet.createWallet(poolName, "issuer2Wallet", "default", null, null).get(); + Wallet issuerXyzWallet = Wallet.openWallet("issuer2Wallet", null, null).get(); + + //2. Issuer create ClaimDef + String gvtSchemaJson = "{\n" + + " \"seqNo\":1,\n" + + " \"data\": {\n" + + " \"name\":\"gvt\",\n" + + " \"version\":\"1.0\",\n" + + " \"keys\":[\"age\",\"sex\",\"height\",\"name\"]\n" + + " }\n" + + " }"; + + String gvtClaimDef = Anoncreds.issuerCreateAndStoreClaimDef(issuerGvtWallet, issuerDid, gvtSchemaJson, null, false).get(); + + //3. Issuer create ClaimDef + String xyzSchemaJson = "{\n" + + " \"seqNo\":2,\n" + + " \"data\": {\n" + + " \"name\":\"xyz\",\n" + + " \"version\":\"1.0\",\n" + + " \"keys\":[\"status\",\"period\"]\n" + + " }\n" + + " }"; + + String xyzClaimDef = Anoncreds.issuerCreateAndStoreClaimDef(issuerXyzWallet, issuerDid2, xyzSchemaJson, null, false).get(); + + //4. Prover create Master Secret + String masterSecret = "masterSecretName"; + Anoncreds.proverCreateMasterSecret(proverWallet, masterSecret).get(); + + //5. Prover store Claim Offer received from Issuer1 + String claimOffer = String.format("{\"issuer_did\":\"%s\", \"schema_seq_no\":%d}", issuerDid, 1); + Anoncreds.proverStoreClaimOffer(proverWallet, claimOffer).get(); + + //6. Prover store Claim Offer received from Issuer2 + String claimOffer2 = String.format("{\"issuer_did\":\"%s\", \"schema_seq_no\":%d}", issuerDid2, 2); + Anoncreds.proverStoreClaimOffer(proverWallet, claimOffer2).get(); + + //7. Prover get Claim Offers + String claimOffersJson = Anoncreds.proverGetClaimOffers(proverWallet, "{}").get(); + + JSONArray claimOffersObject = new JSONArray(claimOffersJson); + assertEquals(2, claimOffersObject.length()); + + JSONObject claimOfferObj1 = claimOffersObject.getJSONObject(0); + JSONObject claimOfferObj2 = claimOffersObject.getJSONObject(1); + + String gvtClaimOffer = claimOfferObj1.getString("issuer_did").equals(issuerDid) ? claimOfferObj1.toString() : claimOfferObj2.toString(); + String xyzClaimOffer = claimOfferObj1.getString("issuer_did").equals(issuerDid2) ? claimOfferObj1.toString() : claimOfferObj2.toString(); + + + //8. Prover create ClaimReq for GVT Claim Offer + String proverDid = "BzfFCYk"; + String gvtClaimReq = Anoncreds.proverCreateClaimReq(proverWallet, proverDid, gvtClaimOffer, gvtClaimDef, masterSecret).get(); + + //9. Issuer create Claim + String gvtClaimAttributesJson = "{\n" + + " \"sex\":[\"male\",\"5944657099558967239210949258394887428692050081607692519917050011144233115103\"],\n" + + " \"name\":[\"Alex\",\"1139481716457488690172217916278103335\"],\n" + + " \"height\":[\"175\",\"175\"],\n" + + " \"age\":[\"28\",\"28\"]\n" + + " }"; + + AnoncredsResults.IssuerCreateClaimResult gvtCreateClaimResult = Anoncreds.issuerCreateClaim(issuerGvtWallet, gvtClaimReq, gvtClaimAttributesJson, - 1, - 1).get(); + String gvtClaimJson = gvtCreateClaimResult.getClaimJson(); + + //10. Prover store Claim + Anoncreds.proverStoreClaim(proverWallet, gvtClaimJson).get(); + + //11. Prover create ClaimReq for GVT Claim Offer + String xyzClaimReq = Anoncreds.proverCreateClaimReq(proverWallet, proverDid, xyzClaimOffer, xyzClaimDef, masterSecret).get(); + + //12. Issuer create Claim + String xyzClaimAttributesJson = "{\n" + + " \"status\":[\"partial\",\"51792877103171595686471452153480627530895\"],\n" + + " \"period\":[\"8\",\"8\"]\n" + + " }"; + + AnoncredsResults.IssuerCreateClaimResult xyzCreateClaimResult = Anoncreds.issuerCreateClaim(issuerXyzWallet, xyzClaimReq, xyzClaimAttributesJson, - 1, - 1).get(); + String xyzClaimJson = xyzCreateClaimResult.getClaimJson(); + + //13. Prover store Claim + Anoncreds.proverStoreClaim(proverWallet, xyzClaimJson).get(); + + //14. Prover gets Claims for Proof Request + String proofRequestJson = "{\n" + + " \"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1,\"name\":\"name\"},\n" + + " \"attr2_uuid\":{\"schema_seq_no\":2,\"name\":\"status\"}},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}," + + " \"predicate2_uuid\":{\"attr_name\":\"period\",\"p_type\":\"GE\",\"value\":5}}\n" + + " }"; + + + String claimsForProofJson = Anoncreds.proverGetClaimsForProofReq(proverWallet, proofRequestJson).get(); + assertNotNull(claimsForProofJson); + + JSONObject claimsForProof = new JSONObject(claimsForProofJson); + JSONArray claimsForAttribute1 = claimsForProof.getJSONObject("attrs").getJSONArray("attr1_uuid"); + JSONArray claimsForAttribute2 = claimsForProof.getJSONObject("attrs").getJSONArray("attr2_uuid"); + JSONArray claimsForPredicate1 = claimsForProof.getJSONObject("predicates").getJSONArray("predicate1_uuid"); + JSONArray claimsForPredicate2 = claimsForProof.getJSONObject("predicates").getJSONArray("predicate2_uuid"); + + assertEquals(claimsForAttribute1.length(), 1); + assertEquals(claimsForAttribute2.length(), 1); + assertEquals(claimsForPredicate1.length(), 1); + assertEquals(claimsForPredicate2.length(), 1); + + String claimUuidForAttr1 = claimsForAttribute1.getJSONObject(0).getString("claim_uuid"); + String claimUuidForAttr2 = claimsForAttribute2.getJSONObject(0).getString("claim_uuid"); + String claimUuidForPredicate1 = claimsForPredicate1.getJSONObject(0).getString("claim_uuid"); + String claimUuidForPredicate2 = claimsForPredicate2.getJSONObject(0).getString("claim_uuid"); + + //15. Prover create Proof + String requestedClaimsJson = String.format("{\n" + + " \"self_attested_attributes\":{},\n" + + " \"requested_attrs\":{\"attr1_uuid\":[\"%s\", true],\n" + + " \"attr2_uuid\":[\"%s\", true]},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":\"%s\"," + + " \"predicate2_uuid\":\"%s\"}\n" + + " }", claimUuidForAttr1, claimUuidForAttr2, claimUuidForPredicate1, claimUuidForPredicate2); + + String schemasJson = String.format("{\"%s\":%s, \"%s\":%s}", claimUuidForAttr1, gvtSchemaJson, claimUuidForAttr2, xyzSchemaJson); + String claimDefsJson = String.format("{\"%s\":%s, \"%s\":%s}", claimUuidForAttr1, gvtClaimDef, claimUuidForAttr2, xyzClaimDef); + + String revocRegsJson = "{}"; + + String proofJson = Anoncreds.proverCreateProof(proverWallet, proofRequestJson, requestedClaimsJson, schemasJson, + masterSecret, claimDefsJson, revocRegsJson).get(); + assertNotNull(proofJson); + + JSONObject proof = new JSONObject(proofJson); + + //16. Verifier verify Proof + assertEquals("Alex", + proof.getJSONObject("requested_proof").getJSONObject("revealed_attrs").getJSONArray("attr1_uuid").getString(1)); + + assertEquals("partial", + proof.getJSONObject("requested_proof").getJSONObject("revealed_attrs").getJSONArray("attr2_uuid").getString(1)); + + Boolean valid = Anoncreds.verifierVerifyProof(proofRequestJson, proofJson, schemasJson, claimDefsJson, revocRegsJson).get(); + assertTrue(valid); + + //18. Close and delete Issuer2 Wallet + issuerXyzWallet.closeWallet().get(); + Wallet.deleteWallet("issuer2Wallet", null).get(); + } + + @Test + public void testAnoncredsWorksForSingleIssuerSingleProverMultiplyClaims() throws Exception { + + String issuerDid = "NcYxiDXkpYi6ov5FcYDi1e"; + + //1. Issuer create ClaimDef + String gvtSchemaJson = "{\n" + + " \"seqNo\":1,\n" + + " \"data\": {\n" + + " \"name\":\"gvt\",\n" + + " \"version\":\"1.0\",\n" + + " \"keys\":[\"age\",\"sex\",\"height\",\"name\"]\n" + + " }\n" + + " }"; + + String gvtClaimDef = Anoncreds.issuerCreateAndStoreClaimDef(issuerWallet, issuerDid, gvtSchemaJson, null, false).get(); + + //2. Issuer create ClaimDef + String xyzSchemaJson = "{\n" + + " \"seqNo\":2,\n" + + " \"data\": {\n" + + " \"name\":\"xyz\",\n" + + " \"version\":\"1.0\",\n" + + " \"keys\":[\"status\",\"period\"]\n" + + " }\n" + + " }"; + + String xyzClaimDef = Anoncreds.issuerCreateAndStoreClaimDef(issuerWallet, issuerDid, xyzSchemaJson, null, false).get(); + + //3. Prover create Master Secret + String masterSecret = "masterSecretName"; + Anoncreds.proverCreateMasterSecret(proverWallet, masterSecret).get(); + + //4. Prover store Claim Offer received from Issuer + String claimOffer = String.format("{\"issuer_did\":\"%s\", \"schema_seq_no\":%d}", issuerDid, 1); + Anoncreds.proverStoreClaimOffer(proverWallet, claimOffer).get(); + + //5. Prover store Claim Offer received from Issuer + String claimOffer2 = String.format("{\"issuer_did\":\"%s\", \"schema_seq_no\":%d}", issuerDid, 2); + Anoncreds.proverStoreClaimOffer(proverWallet, claimOffer2).get(); + + //6. Prover get Claim Offers + String claimOffersJson = Anoncreds.proverGetClaimOffers(proverWallet, "{}").get(); + + JSONArray claimOffersObject = new JSONArray(claimOffersJson); + assertEquals(2, claimOffersObject.length()); + + JSONObject claimOfferObj1 = claimOffersObject.getJSONObject(0); + JSONObject claimOfferObj2 = claimOffersObject.getJSONObject(1); + + String gvtClaimOffer = claimOfferObj1.getInt("schema_seq_no") == 1 ? claimOfferObj1.toString() : claimOfferObj2.toString(); + String xyzClaimOffer = claimOfferObj1.getInt("schema_seq_no") == 2 ? claimOfferObj1.toString() : claimOfferObj2.toString(); + + + //7. Prover create ClaimReq for GVT Claim Offer + String proverDid = "BzfFCYk"; + String gvtClaimReq = Anoncreds.proverCreateClaimReq(proverWallet, proverDid, gvtClaimOffer, gvtClaimDef, masterSecret).get(); + + //8. Issuer create Claim + String gvtClaimAttributesJson = "{\n" + + " \"sex\":[\"male\",\"5944657099558967239210949258394887428692050081607692519917050011144233115103\"],\n" + + " \"name\":[\"Alex\",\"1139481716457488690172217916278103335\"],\n" + + " \"height\":[\"175\",\"175\"],\n" + + " \"age\":[\"28\",\"28\"]\n" + + " }"; + + AnoncredsResults.IssuerCreateClaimResult gvtCreateClaimResult = Anoncreds.issuerCreateClaim(issuerWallet, gvtClaimReq, gvtClaimAttributesJson, - 1, - 1).get(); + String gvtClaimJson = gvtCreateClaimResult.getClaimJson(); + + //9. Prover store Claim + Anoncreds.proverStoreClaim(proverWallet, gvtClaimJson).get(); + + //10. Prover create ClaimReq for GVT Claim Offer + String xyzClaimReq = Anoncreds.proverCreateClaimReq(proverWallet, proverDid, xyzClaimOffer, xyzClaimDef, masterSecret).get(); + + //11. Issuer create Claim + String xyzClaimAttributesJson = "{\n" + + " \"status\":[\"partial\",\"51792877103171595686471452153480627530895\"],\n" + + " \"period\":[\"8\",\"8\"]\n" + + " }"; + + AnoncredsResults.IssuerCreateClaimResult xyzCreateClaimResult = Anoncreds.issuerCreateClaim(issuerWallet, xyzClaimReq, xyzClaimAttributesJson, - 1, - 1).get(); + String xyzClaimJson = xyzCreateClaimResult.getClaimJson(); + + //12. Prover store Claim + Anoncreds.proverStoreClaim(proverWallet, xyzClaimJson).get(); + + //13. Prover gets Claims for Proof Request + String proofRequestJson = "{\n" + + " \"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1,\"name\":\"name\"}},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":{\"attr_name\":\"age\",\"p_type\":\"GE\",\"value\":18}," + + " \"predicate2_uuid\":{\"attr_name\":\"period\",\"p_type\":\"GE\",\"value\":5}}\n" + + " }"; + + + String claimsForProofJson = Anoncreds.proverGetClaimsForProofReq(proverWallet, proofRequestJson).get(); + assertNotNull(claimsForProofJson); + + JSONObject claimsForProof = new JSONObject(claimsForProofJson); + JSONArray claimsForAttribute1 = claimsForProof.getJSONObject("attrs").getJSONArray("attr1_uuid"); + JSONArray claimsForPredicate1 = claimsForProof.getJSONObject("predicates").getJSONArray("predicate1_uuid"); + JSONArray claimsForPredicate2 = claimsForProof.getJSONObject("predicates").getJSONArray("predicate2_uuid"); + + assertEquals(claimsForAttribute1.length(), 1); + assertEquals(claimsForPredicate1.length(), 1); + assertEquals(claimsForPredicate2.length(), 1); + + String claimUuidForAttr1 = claimsForAttribute1.getJSONObject(0).getString("claim_uuid"); + String claimUuidForPredicate1 = claimsForPredicate1.getJSONObject(0).getString("claim_uuid"); + String claimUuidForPredicate2 = claimsForPredicate2.getJSONObject(0).getString("claim_uuid"); + + //14. Prover create Proof + String requestedClaimsJson = String.format("{\n" + + " \"self_attested_attributes\":{},\n" + + " \"requested_attrs\":{\"attr1_uuid\":[\"%s\", true]},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":\"%s\"," + + " \"predicate2_uuid\":\"%s\"}\n" + + " }", claimUuidForAttr1, claimUuidForPredicate1, claimUuidForPredicate2); + + String schemasJson = String.format("{\"%s\":%s, \"%s\":%s}", claimUuidForAttr1, gvtSchemaJson, claimUuidForPredicate2, xyzSchemaJson); + String claimDefsJson = String.format("{\"%s\":%s, \"%s\":%s}", claimUuidForAttr1, gvtClaimDef, claimUuidForPredicate2, xyzClaimDef); + + String revocRegsJson = "{}"; + + String proofJson = Anoncreds.proverCreateProof(proverWallet, proofRequestJson, requestedClaimsJson, schemasJson, + masterSecret, claimDefsJson, revocRegsJson).get(); + assertNotNull(proofJson); + + JSONObject proof = new JSONObject(proofJson); + + //15. Verifier verify Proof + assertEquals("Alex", + proof.getJSONObject("requested_proof").getJSONObject("revealed_attrs").getJSONArray("attr1_uuid").getString(1)); + + Boolean valid = Anoncreds.verifierVerifyProof(proofRequestJson, proofJson, schemasJson, claimDefsJson, revocRegsJson).get(); + assertTrue(valid); + } + + @Test + public void testVerifyProofWorksForProofDoesNotCorrespondToProofRequest() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + //1. Issuer create ClaimDef + String schemaJson = "{\n" + + " \"seqNo\":1,\n" + + " \"data\": {\n" + + " \"name\":\"gvt\",\n" + + " \"version\":\"1.0\",\n" + + " \"keys\":[\"age\",\"sex\",\"height\",\"name\"]\n" + + " }\n" + + " }"; + String issuerDid = "NcYxiDXkpYi6ov5FcYDi1e"; + + String claimDef = Anoncreds.issuerCreateAndStoreClaimDef(issuerWallet, issuerDid, schemaJson, null, false).get(); + assertNotNull(claimDef); + + //2. Prover create Master Secret + String masterSecret = "masterSecretName"; + Anoncreds.proverCreateMasterSecret(proverWallet, masterSecret).get(); + + //3. Prover store Claim Offer + String claimOffer = String.format("{\"issuer_did\":\"%s\", \"schema_seq_no\":%d}", issuerDid, 1); + Anoncreds.proverStoreClaimOffer(proverWallet, claimOffer).get(); + + //4. Prover get Claim Offers + String claimOfferFilter = String.format("{\"issuer_did\":\"%s\"}", issuerDid); + String claimOffersJson = Anoncreds.proverGetClaimOffers(proverWallet, claimOfferFilter).get(); + + JSONArray claimOffersObject = new JSONArray(claimOffersJson); + assertEquals(claimOffersObject.length(), 1); + + JSONObject claimOfferObject = claimOffersObject.getJSONObject(0); + String claimOfferJson = claimOfferObject.toString(); + + //5. Prover create ClaimReq + String proverDid = "BzfFCYk"; + String claimReq = Anoncreds.proverCreateClaimReq(proverWallet, proverDid, claimOfferJson, claimDef, masterSecret).get(); + assertNotNull(claimReq); + + //6. Issuer create Claim + String claimAttributesJson = "{\n" + + " \"sex\":[\"male\",\"5944657099558967239210949258394887428692050081607692519917050011144233115103\"],\n" + + " \"name\":[\"Alex\",\"1139481716457488690172217916278103335\"],\n" + + " \"height\":[\"175\",\"175\"],\n" + + " \"age\":[\"28\",\"28\"]\n" + + " }"; + + AnoncredsResults.IssuerCreateClaimResult createClaimResult = Anoncreds.issuerCreateClaim(issuerWallet, claimReq, claimAttributesJson, - 1, - 1).get(); + assertNotNull(createClaimResult); + String claimJson = createClaimResult.getClaimJson(); + + //7. Prover store Claim + Anoncreds.proverStoreClaim(proverWallet, claimJson).get(); + + //8. Prover gets Claims for Proof Request + String proofRequestJson = "{\n" + + " \"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1,\"name\":\"name\"}},\n" + + " \"requested_predicates\":{}\n" + + " }"; + + String claimsForProofJson = Anoncreds.proverGetClaimsForProofReq(proverWallet, proofRequestJson).get(); + assertNotNull(claimsForProofJson); + + JSONObject claimsForProof = new JSONObject(claimsForProofJson); + JSONArray claimsForAttribute1 = claimsForProof.getJSONObject("attrs").getJSONArray("attr1_uuid"); + + assertEquals(claimsForAttribute1.length(), 1); + + String claimUuid = claimsForAttribute1.getJSONObject(0).getString("claim_uuid"); + + //9. Prover create Proof + String selfAttestedValue = "yes"; + String requestedClaimsJson = String.format("{\n" + + " \"self_attested_attributes\":{\"self1\":\"%s\"},\n" + + " \"requested_attrs\":{\"attr1_uuid\":[\"%s\", true],\n" + + " \"attr2_uuid\":[\"%s\", false]},\n" + + " \"requested_predicates\":{\"predicate1_uuid\":\"%s\"}\n" + + " }", selfAttestedValue, claimUuid, claimUuid, claimUuid); + + String schemasJson = String.format("{\"%s\":%s}", claimUuid, schemaJson); + String claimDefsJson = String.format("{\"%s\":%s}", claimUuid, claimDef); + String revocRegsJson = "{}"; + + + String proofJson = Anoncreds.proverCreateProof(proverWallet, proofRequestJson, requestedClaimsJson, schemasJson, + masterSecret, claimDefsJson, revocRegsJson).get(); + assertNotNull(proofJson); + + JSONObject proof = new JSONObject(proofJson); + + //10. Verifier verify Proof + assertEquals("Alex", + proof.getJSONObject("requested_proof").getJSONObject("revealed_attrs").getJSONArray("attr1_uuid").getString(1)); + + assertNotNull(proof.getJSONObject("requested_proof").getJSONObject("unrevealed_attrs").getString("attr2_uuid")); + + assertEquals(selfAttestedValue, proof.getJSONObject("requested_proof").getJSONObject("self_attested_attrs").getString("self1")); + + proofRequestJson = "{\n" + + " \"nonce\":\"123432421212\",\n" + + " \"name\":\"proof_req_1\",\n" + + " \"version\":\"0.1\",\n" + + " \"requested_attrs\":{\"attr1_uuid\":{\"schema_seq_no\":1,\"name\":\"name\"}},\n" + + " \"requested_predicates\":{}\n" + + " }"; + + Anoncreds.verifierVerifyProof(proofRequestJson, proofJson, schemasJson, claimDefsJson, revocRegsJson).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/demo/LedgerDemoTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/demo/LedgerDemoTest.java new file mode 100644 index 0000000000..4a92c09411 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/demo/LedgerDemoTest.java @@ -0,0 +1,75 @@ +package org.hyperledger.indy.sdk.demo; + +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.ledger.Ledger; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.pool.PoolJSONParameters; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusJSONParameters; +import org.hyperledger.indy.sdk.signus.SignusResults.CreateAndStoreMyDidResult; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.json.JSONObject; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class LedgerDemoTest extends IndyIntegrationTest { + + @Test + public void testLedgerDemo() throws Exception { + + // 1. Create ledger config from genesis txn file + String poolName = PoolUtils.createPoolLedgerConfig(); + + PoolJSONParameters.OpenPoolLedgerJSONParameter config2 = new PoolJSONParameters.OpenPoolLedgerJSONParameter(null, null, null); + Pool pool = Pool.openPoolLedger(poolName, config2.toJson()).get(); + + // 2. Create and Open My Wallet + Wallet.createWallet(poolName, "myWallet", "default", null, null).get(); + Wallet myWallet = Wallet.openWallet("myWallet", null, null).get(); + + // 3. Create and Open Trustee Wallet + Wallet.createWallet(poolName, "theirWallet", "default", null, null).get(); + Wallet trusteeWallet = Wallet.openWallet("theirWallet", null, null).get(); + + // 4. Create My Did + CreateAndStoreMyDidResult createMyDidResult = Signus.createAndStoreMyDid(myWallet, "{}").get(); + assertNotNull(createMyDidResult); + String myDid = createMyDidResult.getDid(); + String myVerkey = createMyDidResult.getVerkey(); + + // 5. Create Did from Trustee1 seed + SignusJSONParameters.CreateAndStoreMyDidJSONParameter theirDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + CreateAndStoreMyDidResult createTheirDidResult = Signus.createAndStoreMyDid(trusteeWallet, theirDidJson.toJson()).get(); + assertNotNull(createTheirDidResult); + String trusteeDid = createTheirDidResult.getDid(); + + // 6. Build Nym Request + String nymRequest = Ledger.buildNymRequest(trusteeDid, myDid, myVerkey, null, null).get(); + assertNotNull(nymRequest); + + // 7. Trustee Sign Nym Request + String nymResponseJson = Ledger.signAndSubmitRequest(pool, trusteeWallet, trusteeDid, nymRequest).get(); + assertNotNull(nymResponseJson); + + JSONObject nymResponse = new JSONObject(nymResponseJson); + + assertEquals(myDid, nymResponse.getJSONObject("result").getString("dest")); + assertEquals(myVerkey, nymResponse.getJSONObject("result").getString("verkey")); + + // 8. Close and delete My Wallet + myWallet.closeWallet().get(); + Wallet.deleteWallet("myWallet", null).get(); + + // 9. Close and delete Their Wallet + trusteeWallet.closeWallet().get(); + Wallet.deleteWallet("theirWallet", null).get(); + + // 10. Close Pool + pool.closePoolLedger().get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/demo/SignusDemoTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/demo/SignusDemoTest.java new file mode 100644 index 0000000000..27fd6f246e --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/demo/SignusDemoTest.java @@ -0,0 +1,76 @@ +package org.hyperledger.indy.sdk.demo; + +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.pool.PoolJSONParameters; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusResults.CreateAndStoreMyDidResult; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class SignusDemoTest extends IndyIntegrationTest { + + @Test + public void testSignusDemo() throws Exception { + + //1. Create and Open Pool + String poolName = PoolUtils.createPoolLedgerConfig(); + + PoolJSONParameters.OpenPoolLedgerJSONParameter config2 = new PoolJSONParameters.OpenPoolLedgerJSONParameter(null, null, null); + Pool pool = Pool.openPoolLedger(poolName, config2.toJson()).get(); + + //2. Create and Open My Wallet + Wallet.createWallet(poolName, "myWallet", "default", null, null).get(); + Wallet myWallet = Wallet.openWallet("myWallet", null, null).get(); + + //3. Create and Open Their Wallet + Wallet.createWallet(poolName, "theirWallet", "default", null, null).get(); + Wallet theirWallet = Wallet.openWallet("theirWallet", null, null).get(); + + //4. Create My Did + CreateAndStoreMyDidResult createMyDidResult = Signus.createAndStoreMyDid(myWallet, "{}").get(); + assertNotNull(createMyDidResult); + + //5. Create Their Did + CreateAndStoreMyDidResult createTheirDidResult = Signus.createAndStoreMyDid(theirWallet, "{}").get(); + assertNotNull(createTheirDidResult); + String theirDid = createTheirDidResult.getDid(); + String theirVerkey = createTheirDidResult.getVerkey(); + + // 6. Store Their DID + String identityJson = String.format("{\"did\":\"%s\", \"verkey\":\"%s\"}", theirDid, theirVerkey); + Signus.storeTheirDid(myWallet, identityJson).get(); + + // 7. Their sign message + String msg = "{\n" + + " \"reqId\":1495034346617224651,\n" + + " \"identifier\":\"GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL\",\n" + + " \"operation\":{\n" + + " \"type\":\"1\",\n" + + " \"dest\":\"4efZu2SXufS556yss7W5k6Po37jt4371RM4whbPKBKdB\"\n" + + " }\n" + + " }"; + + String signedMessage = Signus.sign(theirWallet, theirDid, msg).get(); + assertNotNull(signedMessage); + + // 8. I verify message + Boolean valid = Signus.verifySignature(myWallet, pool, theirDid, signedMessage).get(); + assertTrue(valid); + + // 9. Close and delete My Wallet + myWallet.closeWallet().get(); + Wallet.deleteWallet("myWallet", null).get(); + + // 10. Close and delete Their Wallet + theirWallet.closeWallet().get(); + Wallet.deleteWallet("theirWallet", null).get(); + + //11. Close Pool + pool.closePoolLedger().get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/AttribRequestsTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/AttribRequestsTest.java new file mode 100644 index 0000000000..20424f5ae6 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/AttribRequestsTest.java @@ -0,0 +1,137 @@ +package org.hyperledger.indy.sdk.ledger; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusJSONParameters; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.json.JSONObject; +import org.junit.*; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class AttribRequestsTest extends IndyIntegrationTest { + + private Pool pool; + private Wallet wallet; + private String walletName = "ledgerWallet"; + private String identifier = "Th7MpTaRZVRYnPiabds81Y"; + private String dest = "FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4"; + private String endpoint = "{\"endpoint\":{\"ha\":\"127.0.0.1:5555\"}}"; + + @Before + public void openPool() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(); + pool = Pool.openPoolLedger(poolName, null).get(); + + Wallet.createWallet(poolName, walletName, "default", null, null).get(); + wallet = Wallet.openWallet(walletName, null, null).get(); + } + + @After + public void closePool() throws Exception { + pool.closePoolLedger().get(); + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + @Test + public void testBuildAttribRequestWorksForRawData() throws Exception { + + String expectedResult = String.format("\"identifier\":\"%s\"," + + "\"operation\":{" + + "\"type\":\"100\"," + + "\"dest\":\"%s\"," + + "\"raw\":\"%s\"" + + "}", identifier, dest, endpoint); + + String attribRequest = Ledger.buildAttribRequest(identifier, dest, null, endpoint, null).get(); + + assertTrue(attribRequest.replace("\\", "").contains(expectedResult)); + } + + @Test + public void testBuildAttribRequestWorksForMissedAttribute() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + Ledger.buildAttribRequest(identifier, dest, null, null, null).get(); + } + + @Test + public void testBuildGetAttribRequestWorks() throws Exception { + + String raw = "endpoint"; + + String expectedResult = String.format("\"identifier\":\"%s\"," + + "\"operation\":{" + + "\"type\":\"104\"," + + "\"dest\":\"%s\"," + + "\"raw\":\"%s\"" + + "}", identifier, dest, raw); + + String getAttribRequest = Ledger.buildGetAttribRequest(identifier, dest, raw).get(); + + assertTrue(getAttribRequest.contains(expectedResult)); + } + + @Test + public void testSendAttribRequestWorksWithoutSignature() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.LedgerInvalidTransaction)); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + + String attribRequest = Ledger.buildAttribRequest(trusteeDid, trusteeDid, null, endpoint, null).get(); + Ledger.submitRequest(pool, attribRequest).get(); + } + + @Test + public void testAttribRequestsWorks() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + + SignusResults.CreateAndStoreMyDidResult myDidResult = Signus.createAndStoreMyDid(wallet, "{}").get(); + String myDid = myDidResult.getDid(); + String myVerkey = myDidResult.getVerkey(); + + String nymRequest = Ledger.buildNymRequest(trusteeDid, myDid, myVerkey, null, null).get(); + Ledger.signAndSubmitRequest(pool, wallet, trusteeDid, nymRequest).get(); + + String attribRequest = Ledger.buildAttribRequest(myDid, myDid, null, endpoint, null).get(); + Ledger.signAndSubmitRequest(pool, wallet, myDid, attribRequest).get(); + + String getAttribRequest = Ledger.buildGetAttribRequest(myDid, myDid, "endpoint").get(); + String getAttribResponse = Ledger.submitRequest(pool, getAttribRequest).get(); + + JSONObject getAttribResponseObject = new JSONObject(getAttribResponse); + + assertEquals(endpoint, getAttribResponseObject.getJSONObject("result").getString("data")); + } + + @Test + public void testBuildAttribRequestWorksForInvalidIdentifier() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + Ledger.buildAttribRequest("invalid_base58_identifier", dest, null, endpoint, null).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/ClaimDefRequestsTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/ClaimDefRequestsTest.java new file mode 100644 index 0000000000..73d4c206bc --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/ClaimDefRequestsTest.java @@ -0,0 +1,217 @@ +package org.hyperledger.indy.sdk.ledger; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusJSONParameters; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.json.JSONObject; +import org.junit.*; +import org.junit.rules.Timeout; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertTrue; + +public class ClaimDefRequestsTest extends IndyIntegrationTest { + + private Pool pool; + private Wallet wallet; + private String walletName = "ledgerWallet"; + + @Rule + public Timeout globalTimeout = new Timeout(1, TimeUnit.MINUTES); + + @Before + public void openPool() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(); + pool = Pool.openPoolLedger(poolName, null).get(); + + Wallet.createWallet(poolName, walletName, "default", null, null).get(); + wallet = Wallet.openWallet(walletName, null, null).get(); + } + + @After + public void closePool() throws Exception { + pool.closePoolLedger().get(); + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + private String claimDefTemplate = "{\n" + + " \"ref\":%d,\n" + + " \"signature_type\":\"CL\",\n" + + " \"origin\":\"%s\",\n" + + " \"data\":{\n" + + " \"primary\":{\n" + + " \"n\":\"83469852984476956871633111285697420678256060723156580163068122759469567425381600849138438902552107548539766861666590365174848381535291010418041757276710240953030842046122202402016906205924972182252295487319094577329593677544393592632224714613427822130473474379696616183721440743475053734247824037725487533789856061706740833324717788602268746116297029721621398888459529131593826880823126900285858832457134377949183677639585442886904844793608783831753240185678448312284269486845497720949217396146132958861735347072722092449280372574205841746312833280031873247525372459800132930201998084029506922484661426185450002143461\",\n" + + " \"s\":\"36598527821865478336201608644402887021319976830281254144922838415193047189326184120876650311572665920640111967758238425066565864958446810892401358531545590342401290056836149703549220109981509774843525259400920352082531560361277411808530872594109525982462491998670199872903823657869742599086495624835178373073050767142081484206776345277546531080450529061958937980460303537107061046725579009809137197541389237618812289642185603461102513124991949835948586623327143696280240600789928383168220919049794681181861776889681393339729944540218566460627715413465709316412838042632482652979005394086058441511591756153781159121227\",\n" + + " \"rms\":\"23836382972046033209463023456985914927629254782286444334728987813724281765327660893337383450653748691133061782449580026414785334582859397732571499366000805280757877601804441568263743400086744823885203441870748890135445454347495577599234477813361254101857848089907496868136222777024967328411073984887059985103475100012787049491016895625234124538894645853939428009610771524580099452739392988318945585946758355611531582519514003714424216836334706370901576611410508113637778751976890941210538254418937285168453791223070083264852447713991114719905171445881819334587600693321106919667204512182250084258986170095774914769107\",\n" + + " \"r\":{\n" + + " \"age\":\"15428480888651268593621235736458685943389726269437020388313417035842991073151072061010468945249435098482625869236498750525662874597991333642865524104221652457788998109101749530884821300954337535472137069380551054204373136155978715752232238326100335828797868667735730830741789880726890058203015780792583471770404478023662994191588489722949795849990796063953164194432710764145637578113087142419634074378464118254848566088943085760634805903735300398689750649630456000759025366784986694635635510206166144055869823907120081668956271923743188342071093889666111639924270726451727101864752767708690529389259470017692442002767\",\n" + + " \"name\":\"74008461204977705404956807338714891429397387365673402608947856456696416827848931951447004905350314563364442667940680669672331872875260077257474781261367591510351742401708951175978700805098470304211391452678992053755170054677498844656517106987419550598382601263743442309896367374279461481792679346472671426558385003925845431219156475505665973289508268634194964491418902859845301351562575713510002838692825728016254605821829245646855474149449192539144107522081712005891593405826343897070114168186645885993480245755494685105636168333649181939830898090651120926156152753918086493335382129839850609934233944397884745134858\",\n" + + " \"sex\":\"40646934914193532541511585946883243600955533193734077080129022860038019728021796610599139377923881754708640252789475144625086755150150612623804964347576907276705600241268266301487516824189453869193926251791711672689649199860304727280764676403810510047397326018392955950249975529169980045664874433828266623495515931483137318724210483205730962036282580749206735450480976847188040030165278917936054139926609849181885654646269083459580415131952938813839182742590617440550773580790446467896469090164142755499827316294406540664375065617280568303837662431668218593808092907551353093044984225946834165309588512359379032847125\",\n" + + " \"height\":\"60077310006190228182950362501472785016827894350517184186566050586806482282196022414888288252599211919680339352529750982779980002923071031258837648242708410943080288964834346858544959217874890558006056551949543916094446891954292824146212277550956558692224016968153138097595802008943263818064605343108607131298420107448075252583276684858815371561492996587478784667827675142382692061950832554910690663724101360454494298013020706080246986445114235542283015624510836206522238238728405826712730615187235709554561445384409566940622412591208469650855059870671771721035756205878334354791247751663679130847366069215369484993653\"\n" + + " },\n" + + " \"rctxt\":\"36378575722516953828830668112614685244571602424420162720244033008706985740860180373728219883172046821464173434592331868657297711725743060654773725561634332269874655603697872022630999786617840856366807034806938874090561725454026277048301648000835861491030368037108847175790943895107305383779598585532854170748970999977490244057635358075906501562932970296830906796719844887269636297064678777638050708353254894155336111384638276041851818109156194135995350001255928374102089400812445206030019103440866343736761861049159446083221399575945128480681798837648578166327164995640582517916904912672875184928940552983440410245037\",\n" + + " \"z\":\"65210811645114955910002482704691499297899796787292244564644467629838455625296674951468505972574512639263601600908664306008863647466643899294681985964775001929521624341158696866597713112430928402519124073453804861185882073381514901830347278653016300430179820703804228663001232136885036042101307423527913402600370741689559698469878576457899715687929448757963179899698951620405467976414716277505767979494596626867505828267832223147104774684678295400387894506425769550011471322118172087199519094477785389750318762521728398390891214426117908390767403438354009767291938975195751081032073309083309746656253788033721103313036\"\n" + + " }\n" + + " }\n" + + " }"; + private String signatureType = "CL"; + private String identifier = "Th7MpTaRZVRYnPiabds81Y"; + private String signature_type = "CL"; + + @Test + public void testBuildClaimDefRequestWorks() throws Exception { + + int schema_seq_no = 1; + String data = "{\"primary\":{\"n\":\"1\",\"s\":\"2\",\"rms\":\"3\",\"r\":{\"name\":\"1\"},\"rctxt\":\"1\",\"z\":\"1\"}}"; + + String expectedResult = String.format("\"identifier\":\"%s\"," + + "\"operation\":{" + + "\"ref\":%d," + + "\"data\":\"%s\"," + + "\"type\":\"102\"," + + "\"signature_type\":\"%s\"" + + "}", identifier, schema_seq_no, data, signature_type); + + String claimDefRequest = Ledger.buildClaimDefTxn(identifier, schema_seq_no, signature_type, data).get(); + + assertTrue(claimDefRequest.replace("\\", "").contains(expectedResult)); + } + + @Test + public void testBuildGetClaimDefRequestWorks() throws Exception { + + int ref = 1; + + String expectedResult = String.format("\"identifier\":\"%s\"," + + "\"operation\":{" + + "\"type\":\"108\"," + + "\"ref\":%d," + + "\"signature_type\":\"%s\"," + + "\"origin\":\"%s\"" + + "}", identifier, ref, signature_type, identifier); + + String getClaimDefRequest = Ledger.buildGetClaimDefTxn(identifier, ref, signature_type, identifier).get(); + + assertTrue(getClaimDefRequest.replace("\\", "").contains(expectedResult)); + } + + @Test + public void testBuildClaimDefRequestWorksForInvalidJson() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + int schema_seq_no = 1; + String data = "{\"primary\":{\"n\":\"1\",\"s\":\"2\",\"rms\":\"3\",\"r\":{\"name\":\"1\"}}}"; + + Ledger.buildClaimDefTxn(identifier, schema_seq_no, signature_type, data).get(); + } + + @Test + public void testClaimDefRequestsWorks() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter myDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, null, null, null); + + SignusResults.CreateAndStoreMyDidResult myDidResult = Signus.createAndStoreMyDid(wallet, myDidJson.toJson()).get(); + String myDid = myDidResult.getDid(); + String myVerkey = myDidResult.getVerkey(); + + String nymRequest = Ledger.buildNymRequest(trusteeDid, myDid, myVerkey, null, null).get(); + Ledger.signAndSubmitRequest(pool, wallet, trusteeDid, nymRequest).get(); + + String schemaData = "{\"name\":\"gvt2\",\"version\":\"2.0\",\"keys\": [\"name\", \"male\"]}"; + + String schemaRequest = Ledger.buildSchemaRequest(myDid, schemaData).get(); + Ledger.signAndSubmitRequest(pool, wallet, myDid, schemaRequest).get(); + + String getSchemaData = "{\"name\":\"gvt2\",\"version\":\"2.0\"}"; + String getSchemaRequest = Ledger.buildGetSchemaRequest(myDid, myDid, getSchemaData).get(); + String getSchemaResponse = Ledger.submitRequest(pool, getSchemaRequest).get(); + + JSONObject schemaObj = new JSONObject(getSchemaResponse); + + int schemaSeqNo = schemaObj.getJSONObject("result").getInt("seqNo"); + + String claimDef = String.format(claimDefTemplate, schemaSeqNo, myDid); + + JSONObject claimDefObj = new JSONObject(claimDef); + + String claimDefJson = String.format("%s", claimDefObj.getJSONObject("data")); + + String claimDefRequest = Ledger.buildClaimDefTxn(myDid, schemaSeqNo, signatureType, claimDefJson).get(); + Ledger.signAndSubmitRequest(pool, wallet, myDid, claimDefRequest).get(); + + String getClaimDefRequest = Ledger.buildGetClaimDefTxn(myDid, schemaSeqNo, signatureType, claimDefObj.getString("origin")).get(); + String getClaimDefResponse = Ledger.submitRequest(pool, getClaimDefRequest).get(); + + JSONObject getClaimDefResponseObj = new JSONObject(getClaimDefResponse); + + JSONObject expectedClaimDef = claimDefObj.getJSONObject("data").getJSONObject("primary"); + JSONObject actualClaimDef = getClaimDefResponseObj.getJSONObject("result").getJSONObject("data").getJSONObject("primary"); + + Assert.assertEquals(expectedClaimDef.getString("n"), actualClaimDef.getString("n")); + Assert.assertEquals(expectedClaimDef.getString("rms"), actualClaimDef.getString("rms")); + Assert.assertEquals(expectedClaimDef.getString("rctxt"), actualClaimDef.getString("rctxt")); + Assert.assertEquals(expectedClaimDef.getString("z"), actualClaimDef.getString("z")); + Assert.assertEquals(expectedClaimDef.getString("n"), actualClaimDef.getString("n")); + Assert.assertEquals(expectedClaimDef.getJSONObject("r").toString(), actualClaimDef.getJSONObject("r").toString()); + + } + + @Test + public void testClaimDefRequestWorksWithoutSignature() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.LedgerInvalidTransaction)); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter myDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, null, null, null); + + SignusResults.CreateAndStoreMyDidResult myDidResult = Signus.createAndStoreMyDid(wallet, myDidJson.toJson()).get(); + String myDid = myDidResult.getDid(); + String myVerkey = myDidResult.getVerkey(); + + String nymRequest = Ledger.buildNymRequest(trusteeDid, myDid, myVerkey, null, null).get(); + Ledger.signAndSubmitRequest(pool, wallet, trusteeDid, nymRequest).get(); + + String schemaData = "{\"name\":\"gvt2\",\"version\":\"2.0\",\"keys\": [\"name\", \"male\"]}"; + + String schemaRequest = Ledger.buildSchemaRequest(myDid, schemaData).get(); + String schemaResponse = Ledger.signAndSubmitRequest(pool, wallet, myDid, schemaRequest).get(); + + JSONObject schemaObj = new JSONObject(schemaResponse); + + int schemaSeqNo = schemaObj.getJSONObject("result").getInt("seqNo"); + + String claimDef = String.format(claimDefTemplate, schemaSeqNo, myDid); + + JSONObject claimDefObj = new JSONObject(claimDef); + + String claimDefJson = String.format("%s", claimDefObj.getJSONObject("data")); + + String claimDefRequest = Ledger.buildClaimDefTxn(myDid, schemaSeqNo, signatureType, claimDefJson).get(); + Ledger.submitRequest(pool, claimDefRequest).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/GetTxnRequestTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/GetTxnRequestTest.java new file mode 100644 index 0000000000..3657add3cd --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/GetTxnRequestTest.java @@ -0,0 +1,110 @@ +package org.hyperledger.indy.sdk.ledger; + +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusJSONParameters; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.json.JSONObject; +import org.junit.*; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class GetTxnRequestTest extends IndyIntegrationTest { + + private Pool pool; + private Wallet wallet; + private String walletName = "ledgerWallet"; + + @Before + public void openPool() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(); + pool = Pool.openPoolLedger(poolName, null).get(); + + Wallet.createWallet(poolName, walletName, "default", null, null).get(); + wallet = Wallet.openWallet(walletName, null, null).get(); + } + + @After + public void closePool() throws Exception { + pool.closePoolLedger().get(); + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + @Test + public void testBuildGetTxnRequestWorks() throws Exception { + + String identifier = "Th7MpTaRZVRYnPiabds81Y"; + int data = 1; + + String expectedResult = String.format("\"identifier\":\"%s\"," + + "\"operation\":{" + + "\"type\":\"3\"," + + "\"data\":%s" + + "}", identifier, data); + + String getTxnRequest = Ledger.buildGetTxnRequest(identifier, data).get(); + + assertTrue(getTxnRequest.replace("\\", "").contains(expectedResult)); + } + + @Test + public void testGetTxnRequestWorks() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult didResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String did = didResult.getDid(); + + String schemaData = "{\"name\":\"gvt2\",\"version\":\"3.0\",\"keys\": [\"name\", \"male\"]}"; + + String schemaRequest = Ledger.buildSchemaRequest(did, schemaData).get(); + String schemaResponse = Ledger.signAndSubmitRequest(pool, wallet, did, schemaRequest).get(); + + JSONObject schemaResponseObj = new JSONObject(schemaResponse); + + int seqNo = schemaResponseObj.getJSONObject("result").getInt("seqNo"); + + String getTxnRequest = Ledger.buildGetTxnRequest(did, seqNo).get(); + String getTxnResponse = Ledger.submitRequest(pool, getTxnRequest).get(); + + JSONObject getTxnResponseObj = new JSONObject(getTxnResponse); + + String schemaTransaction = getTxnResponseObj.getJSONObject("result").getString("data"); + JSONObject schemaTransactionObj = new JSONObject(schemaTransaction); + + assertEquals(schemaData, schemaTransactionObj.getString("data")); + } + + @Test + public void testGetTxnRequestWorksForInvalidSeqNo() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult didResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String did = didResult.getDid(); + + String schemaData = "{\"name\":\"gvt2\",\"version\":\"3.0\",\"keys\": [\"name\", \"male\"]}"; + + String schemaRequest = Ledger.buildSchemaRequest(did, schemaData).get(); + String schemaResponse = Ledger.signAndSubmitRequest(pool, wallet, did, schemaRequest).get(); + + JSONObject schemaResponseObj = new JSONObject(schemaResponse); + + int seqNo = schemaResponseObj.getJSONObject("result").getInt("seqNo") + 1; + + String getTxnRequest = Ledger.buildGetTxnRequest(did, seqNo).get(); + String getTxnResponse = Ledger.submitRequest(pool, getTxnRequest).get(); + + JSONObject getTxnResponseObj = new JSONObject(getTxnResponse); + + String schemaTransaction = getTxnResponseObj.getJSONObject("result").getString("data"); + assertEquals("{}", schemaTransaction); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/NodeRequestsTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/NodeRequestsTest.java new file mode 100644 index 0000000000..dbb48edf37 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/NodeRequestsTest.java @@ -0,0 +1,175 @@ +package org.hyperledger.indy.sdk.ledger; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusJSONParameters; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.junit.*; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertTrue; + +public class NodeRequestsTest extends IndyIntegrationTest { + + private Pool pool; + private Wallet wallet; + private String walletName = "ledgerWallet"; + private String identifier = "Th7MpTaRZVRYnPiabds81Y"; + private String dest = "Th7MpTaRZVRYnPiabds81Y"; + + @Before + public void openPool() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(); + pool = Pool.openPoolLedger(poolName, null).get(); + + Wallet.createWallet(poolName, walletName, "default", null, null).get(); + wallet = Wallet.openWallet(walletName, null, null).get(); + } + + @After + public void closePool() throws Exception { + pool.closePoolLedger().get(); + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + @Test + public void testBuildNodeRequestWorks() throws Exception { + + String data = "{\"node_ip\":\"10.0.0.100\"," + + "\"node_port\":910," + + "\"client_ip\":\"10.0.0.100\"," + + "\"client_port\":911," + + "\"alias\":\"some\"," + + "\"services\":[\"VALIDATOR\"]}"; + + String expectedResult = String.format("\"identifier\":\"%s\"," + + "\"operation\":{" + + "\"type\":\"0\"," + + "\"dest\":\"%s\"," + + "\"data\":%s" + + "}", identifier, dest, data); + + String nodeRequest = Ledger.buildNodeRequest(identifier, dest, data).get(); + + assertTrue(nodeRequest.replace("\\", "").contains(expectedResult)); + } + + @Test + public void testSendNodeRequestWorksWithoutSignature() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.LedgerInvalidTransaction)); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, "000000000000000000000000Steward1", null, null); + + SignusResults.CreateAndStoreMyDidResult didResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String did = didResult.getDid(); + + String data = "{\"node_ip\":\"10.0.0.100\"," + + "\"node_port\":910," + + "\"client_ip\":\"10.0.0.100\"," + + "\"client_port\":910," + + "\"alias\":\"some\"," + + "\"services\":[\"VALIDATOR\"]}"; + + String nodeRequest = Ledger.buildNodeRequest(did, did, data).get(); + Ledger.submitRequest(pool, nodeRequest).get(); + } + + @Test + public void testBuildNodeRequestWorksForWrongServiceType() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String data = "{\"node_ip\":\"10.0.0.100\"," + + "\"node_port\":910," + + "\"client_ip\":\"10.0.0.100\"," + + "\"client_port\":911," + + "\"alias\":\"some\"," + + "\"services\":[\"SERVICE\"]}"; + + Ledger.buildNodeRequest(identifier, dest, data).get(); + } + + @Test + public void testBuildNodeRequestWorksForMissedField() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String data = "{\"node_ip\":\"10.0.0.100\"," + + "\"node_port\":910," + + "\"client_ip\":\"10.0.0.100\"," + + "\"client_port\":910," + + "\"services\":[\"VALIDATOR\"]}"; + + Ledger.buildNodeRequest(identifier, dest, data).get(); + } + + @Test + public void testSendNodeRequestWorksForWrongRole() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.LedgerInvalidTransaction)); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult didResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String did = didResult.getDid(); + + String data = "{\"node_ip\":\"10.0.0.100\"," + + "\"node_port\":910," + + "\"client_ip\":\"10.0.0.100\"," + + "\"client_port\":911," + + "\"alias\":\"some\"," + + "\"services\":[\"VALIDATOR\"]}"; + + String nodeRequest = Ledger.buildNodeRequest(did, did, data).get(); + Ledger.signAndSubmitRequest(pool, wallet, did, nodeRequest).get(); + } + + @Test + @Ignore + public void testSendNodeRequestWorksForNewSteward() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult didResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String trusteeDid = didResult.getDid(); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter myDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, null, null, null); + + SignusResults.CreateAndStoreMyDidResult myDidResult = Signus.createAndStoreMyDid(wallet, myDidJson.toJson()).get(); + String myDid = myDidResult.getDid(); + String myVerkey = myDidResult.getVerkey(); + + String role = "STEWARD"; + + String nymRequest = Ledger.buildNymRequest(trusteeDid, myDid, myVerkey, null, role).get(); + Ledger.signAndSubmitRequest(pool, wallet, trusteeDid, nymRequest).get(); + + String data = "{\"node_ip\":\"10.0.0.100\"," + + "\"node_port\":910," + + "\"client_ip\":\"10.0.0.100\"," + + "\"client_port\":911," + + "\"alias\":\"some\"," + + "\"services\":[\"VALIDATOR\"]}"; + + String dest = "A5iWQVT3k8Zo9nXj4otmeqaUziPQPCiDqcydXkAJBk1Y"; + + String nodeRequest = Ledger.buildNodeRequest(myDid, dest, data).get(); + Ledger.signAndSubmitRequest(pool, wallet, myDid, nodeRequest).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/NymRequestsTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/NymRequestsTest.java new file mode 100644 index 0000000000..310a02622c --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/NymRequestsTest.java @@ -0,0 +1,242 @@ +package org.hyperledger.indy.sdk.ledger; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusJSONParameters; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.json.JSONObject; +import org.junit.*; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class NymRequestsTest extends IndyIntegrationTest { + + private Pool pool; + private Wallet wallet; + private String walletName = "ledgerWallet"; + private String identifier = "Th7MpTaRZVRYnPiabds81Y"; + private String dest = "FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4"; + + @Before + public void openPool() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(); + pool = Pool.openPoolLedger(poolName, null).get(); + + Wallet.createWallet(poolName, walletName, "default", null, null).get(); + wallet = Wallet.openWallet(walletName, null, null).get(); + } + + @After + public void closePool() throws Exception { + pool.closePoolLedger().get(); + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + @Test + public void testBuildNymRequestWorksForOnlyRequiredFields() throws Exception { + + String expectedResult = String.format("\"identifier\":\"%s\",\"operation\":{\"type\":\"1\",\"dest\":\"%s\"}", identifier, dest); + + String nymRequest = Ledger.buildNymRequest(identifier, dest, null, null, null).get(); + + assertTrue(nymRequest.contains(expectedResult)); + } + + @Test + public void testBuildNymRequestWorksForOnlyOptionalFields() throws Exception { + + String verkey = "Anfh2rjAcxkE249DcdsaQl"; + String role = "STEWARD"; + String alias = "some_alias"; + + String expectedResult = String.format("\"identifier\":\"%s\"," + + "\"operation\":{" + + "\"type\":\"1\"," + + "\"dest\":\"%s\"," + + "\"verkey\":\"%s\"," + + "\"alias\":\"%s\"," + + "\"role\":\"2\"" + + "}", identifier, dest, verkey, alias); + + String nymRequest = Ledger.buildNymRequest(identifier, dest, verkey, alias, role).get(); + + assertTrue(nymRequest.contains(expectedResult)); + } + + @Test + public void testBuildGetNymRequestWorks() throws Exception { + + String expectedResult = String.format("\"identifier\":\"%s\",\"operation\":{\"type\":\"105\",\"dest\":\"%s\"}", identifier, dest); + + String nymRequest = Ledger.buildGetNymRequest(identifier, dest).get(); + + assertTrue(nymRequest.contains(expectedResult)); + } + + @Test + public void testNymRequestWorksWithoutSignature() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.LedgerInvalidTransaction)); + + SignusResults.CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(wallet, "{}").get(); + String did = result.getDid(); + + String nymRequest = Ledger.buildNymRequest(did, did, null, null, null).get(); + Ledger.submitRequest(pool, nymRequest).get(); + } + + @Test + public void testSendNymRequestsWorksForOnlyRequiredFields() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + + SignusResults.CreateAndStoreMyDidResult myDidResult = Signus.createAndStoreMyDid(wallet, "{}").get(); + String myDid = myDidResult.getDid(); + + String nymRequest = Ledger.buildNymRequest(trusteeDid, myDid, null, null, null).get(); + String nymResponse = Ledger.signAndSubmitRequest(pool, wallet, trusteeDid, nymRequest).get(); + + assertNotNull(nymResponse); + } + + @Test + public void testSendNymRequestsWorksForOptionalFields() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + + SignusResults.CreateAndStoreMyDidResult myDidResult = Signus.createAndStoreMyDid(wallet, "{}").get(); + String myDid = myDidResult.getDid(); + String myVerkey = myDidResult.getVerkey(); + String role = "STEWARD"; + String alias = "some_alias"; + + String nymRequest = Ledger.buildNymRequest(trusteeDid, myDid, myVerkey, alias, role).get(); + String nymResponse = Ledger.signAndSubmitRequest(pool, wallet, trusteeDid, nymRequest).get(); + + assertNotNull(nymResponse); + } + + @Test + public void testGetNymRequestWorks() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(wallet, didJson.toJson()).get(); + String did = result.getDid(); + + String getNymRequest = Ledger.buildGetNymRequest(did, did).get(); + String getNymResponseJson = Ledger.submitRequest(pool, getNymRequest).get(); + + JSONObject getNymResponse = new JSONObject(getNymResponseJson); + + assertEquals(did, getNymResponse.getJSONObject("result").getString("dest")); + } + + @Test + public void testSendNymRequestsWorksForWrongSignerRole() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.LedgerInvalidTransaction)); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter myDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, null, null, null); + + SignusResults.CreateAndStoreMyDidResult myDidResult = Signus.createAndStoreMyDid(wallet, myDidJson.toJson()).get(); + String myDid = myDidResult.getDid(); + + String nymRequest = Ledger.buildNymRequest(trusteeDid, myDid, null, null, null).get(); + Ledger.signAndSubmitRequest(pool, wallet, trusteeDid, nymRequest).get(); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter myDidJson2 = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, null, null, null); + + SignusResults.CreateAndStoreMyDidResult myDidResult2 = Signus.createAndStoreMyDid(wallet, myDidJson2.toJson()).get(); + String myDid2 = myDidResult2.getDid(); + + String nymRequest2 = Ledger.buildNymRequest(myDid, myDid2, null, null, null).get(); + Ledger.signAndSubmitRequest(pool, wallet, myDid, nymRequest2).get(); + } + + @Test + public void testSendNymRequestsWorksForUnknownSigner() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.LedgerInvalidTransaction)); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, "000000000000000000000000Trustee9", null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter myDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, null, null, null); + + SignusResults.CreateAndStoreMyDidResult myDidResult = Signus.createAndStoreMyDid(wallet, myDidJson.toJson()).get(); + String myDid = myDidResult.getDid(); + + String nymRequest = Ledger.buildNymRequest(trusteeDid, myDid, null, null, null).get(); + Ledger.signAndSubmitRequest(pool, wallet, trusteeDid, nymRequest).get(); + } + + @Test + public void testNymRequestsWorks() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + + SignusResults.CreateAndStoreMyDidResult myDidResult = Signus.createAndStoreMyDid(wallet, "{}").get(); + String myDid = myDidResult.getDid(); + String myVerkey = myDidResult.getVerkey(); + + String nymRequest = Ledger.buildNymRequest(trusteeDid, myDid, myVerkey, null, null).get(); + Ledger.signAndSubmitRequest(pool, wallet, trusteeDid, nymRequest).get(); + + String getNymRequest = Ledger.buildGetNymRequest(myDid, myDid).get(); + String getNymResponseJson = Ledger.submitRequest(pool, getNymRequest).get(); + + JSONObject getNymResponse = new JSONObject(getNymResponseJson); + + assertEquals("REPLY", getNymResponse.getString("op")); + assertEquals("105", getNymResponse.getJSONObject("result").getString("type")); + assertEquals(myDid, getNymResponse.getJSONObject("result").getString("dest")); + } + + @Test + public void testSendNymRequestsWorksForWrongRole() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + Ledger.buildNymRequest(identifier, dest, null, null, "WRONG_ROLE").get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/RequestsTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/RequestsTest.java new file mode 100644 index 0000000000..16053a8f6f --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/RequestsTest.java @@ -0,0 +1,128 @@ +package org.hyperledger.indy.sdk.ledger; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusJSONParameters; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.json.JSONObject; +import org.junit.*; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertNotNull; + +public class RequestsTest extends IndyIntegrationTest { + + private Pool pool; + private Wallet wallet; + private String walletName = "ledgerWallet"; + + @Before + public void openPool() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(); + pool = Pool.openPoolLedger(poolName, null).get(); + + Wallet.createWallet(poolName, walletName, "default", null, null).get(); + wallet = Wallet.openWallet(walletName, null, null).get(); + } + + @After + public void closePool() throws Exception { + pool.closePoolLedger().get(); + + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + @Test + public void testSubmitRequestWorks() throws Exception { + + String request = "{\"reqId\":1491566332010860,\n" + + " \"identifier\":\"Th7MpTaRZVRYnPiabds81Y\",\n" + + " \"operation\":{\n" + + " \"type\":\"105\",\n" + + " \"dest\":\"Th7MpTaRZVRYnPiabds81Y\"\n" + + " },\n" + + " \"signature\":\"4o86XfkiJ4e2r3J6Ufoi17UU3W5Zi9sshV6FjBjkVw4sgEQFQov9dxqDEtLbAJAWffCWd5KfAk164QVo7mYwKkiV\"}"; + + String response = Ledger.submitRequest(pool, request).get(); + + JSONObject responseObject = new JSONObject(response); + + Assert.assertEquals("REPLY", responseObject.getString("op")); + Assert.assertEquals("105", responseObject.getJSONObject("result").getString("type")); + Assert.assertEquals(1491566332010860L, responseObject.getJSONObject("result").getLong("reqId")); + Assert.assertEquals("{\"dest\":\"Th7MpTaRZVRYnPiabds81Y\",\"identifier\":\"V4SGRU86Z58d6TV7PBUe6f\",\"role\":\"2\",\"verkey\":\"~7TYfekw4GUagBnBVCqPjiC\"}", responseObject.getJSONObject("result").getString("data")); + Assert.assertEquals("Th7MpTaRZVRYnPiabds81Y", responseObject.getJSONObject("result").getString("identifier")); + Assert.assertEquals("Th7MpTaRZVRYnPiabds81Y", responseObject.getJSONObject("result").getString("dest")); + } + + @Test + public void testSignAndSubmitRequestWorks() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + + SignusResults.CreateAndStoreMyDidResult myDidResult = Signus.createAndStoreMyDid(wallet, "{}").get(); + String myDid = myDidResult.getDid(); + + String nymRequest = Ledger.buildNymRequest(trusteeDid, myDid, null, null, null).get(); + String nymResponse = Ledger.signAndSubmitRequest(pool, wallet, trusteeDid, nymRequest).get(); + assertNotNull(nymResponse); + } + + @Test + public void testSignAndSubmitRequestWorksForNotFoundSigner() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.LedgerInvalidTransaction)); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, "00000000000000000000UnknowSigner", null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String signerDid = trusteeDidResult.getDid(); + + SignusResults.CreateAndStoreMyDidResult myDidResult = Signus.createAndStoreMyDid(wallet, "{}").get(); + String myDid = myDidResult.getDid(); + + String nymRequest = Ledger.buildNymRequest(signerDid, myDid, null, null, null).get(); + String nymResponse = Ledger.signAndSubmitRequest(pool, wallet, signerDid, nymRequest).get(); + assertNotNull(nymResponse); + } + + @Test + public void testSignAndSubmitRequestWorksForIncompatibleWalletAndPool() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.WalletIncompatiblePoolError)); + + String walletName = "incompatibleWallet"; + + Wallet.createWallet("otherPoolName", walletName, "default", null, null).get(); + Wallet wallet = Wallet.openWallet(walletName, null, null).get(); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult trusteeDidResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String trusteeDid = trusteeDidResult.getDid(); + + SignusResults.CreateAndStoreMyDidResult myDidResult = Signus.createAndStoreMyDid(wallet, "{}").get(); + String myDid = myDidResult.getDid(); + + String nymRequest = Ledger.buildNymRequest(trusteeDid, myDid, null, null, null).get(); + Ledger.signAndSubmitRequest(pool, wallet, trusteeDid, nymRequest).get(); + + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/SchemaRequestsTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/SchemaRequestsTest.java new file mode 100644 index 0000000000..f7d06c7eac --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/ledger/SchemaRequestsTest.java @@ -0,0 +1,153 @@ +package org.hyperledger.indy.sdk.ledger; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.signus.Signus; +import org.hyperledger.indy.sdk.signus.SignusJSONParameters; +import org.hyperledger.indy.sdk.signus.SignusResults; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.json.JSONObject; +import org.junit.*; + +import java.util.concurrent.ExecutionException; + +import static junit.framework.TestCase.assertNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class SchemaRequestsTest extends IndyIntegrationTest { + + private Pool pool; + private Wallet wallet; + private String walletName = "ledgerWallet"; + private String identifier = "Th7MpTaRZVRYnPiabds81Y"; + + @Before + public void openPool() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(); + pool = Pool.openPoolLedger(poolName, null).get(); + + Wallet.createWallet(poolName, walletName, "default", null, null).get(); + wallet = Wallet.openWallet(walletName, null, null).get(); + } + + @After + public void closePool() throws Exception { + pool.closePoolLedger().get(); + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + @Test + public void testBuildSchemaRequestWorks() throws Exception { + + String data = "{\"name\":\"name\", \"version\":\"1.0\", \"keys\":[\"name\",\"male\"]}"; + + String expectedResult = String.format("\"identifier\":\"%s\"," + + "\"operation\":{" + + "\"type\":\"101\"," + + "\"data\":\"%s\"" + + "}", identifier, data); + + String schemaRequest = Ledger.buildSchemaRequest(identifier, data).get(); + + assertTrue(schemaRequest.replace("\\", "").contains(expectedResult)); + } + + @Test + public void testBuildGetSchemaRequestWorks() throws Exception { + + String data = "{\"name\":\"name\",\"version\":\"1.0\"}"; + + String expectedResult = String.format("\"identifier\":\"%s\"," + + "\"operation\":{" + + "\"type\":\"107\"," + + "\"dest\":\"%s\"," + + "\"data\":%s" + + "}", identifier, identifier, data); + + String getSchemaRequest = Ledger.buildGetSchemaRequest(identifier, identifier, data).get(); + + assertTrue(getSchemaRequest.contains(expectedResult)); + } + + @Test + public void testSchemaRequestWorksWithoutSignature() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.LedgerInvalidTransaction)); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult didResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String did = didResult.getDid(); + + String schemaData = "{\"name\":\"gvt2\",\n" + + " \"version\":\"2.0\",\n" + + " \"keys\": [\"name\", \"male\"]}"; + + String schemaRequest = Ledger.buildSchemaRequest(did, schemaData).get(); + String schemaResponse = Ledger.submitRequest(pool, schemaRequest).get(); + + assertNotNull(schemaResponse); + } + + @Test + public void testSchemaRequestsWorks() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult didResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String did = didResult.getDid(); + + String schemaData = "{\"name\":\"gvt2\",\"version\":\"2.0\",\"keys\": [\"name\", \"male\"]}"; + + String schemaRequest = Ledger.buildSchemaRequest(did, schemaData).get(); + Ledger.signAndSubmitRequest(pool, wallet, did, schemaRequest).get(); + + String getSchemaData = "{\"name\":\"gvt2\",\"version\":\"2.0\"}"; + String getSchemaRequest = Ledger.buildGetSchemaRequest(did, did, getSchemaData).get(); + String getSchemaResponse = Ledger.submitRequest(pool, getSchemaRequest).get(); + + JSONObject getSchemaResponseObject = new JSONObject(getSchemaResponse); + + assertEquals("gvt2", getSchemaResponseObject.getJSONObject("result").getJSONObject("data").getString("name")); + assertEquals("2.0", getSchemaResponseObject.getJSONObject("result").getJSONObject("data").getString("version")); + assertEquals(did, getSchemaResponseObject.getJSONObject("result").getJSONObject("data").getString("origin")); + } + + @Test + public void testGetSchemaRequestsWorksForUnknownSchema() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter trusteeDidJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + SignusResults.CreateAndStoreMyDidResult didResult = Signus.createAndStoreMyDid(wallet, trusteeDidJson.toJson()).get(); + String did = didResult.getDid(); + + String getSchemaData = "{\"name\":\"schema_name\",\"version\":\"2.0\"}"; + String getSchemaRequest = Ledger.buildGetSchemaRequest(did, did, getSchemaData).get(); + String getSchemaResponse = Ledger.submitRequest(pool, getSchemaRequest).get(); + + JSONObject getSchemaResponseObject = new JSONObject(getSchemaResponse); + + assertNull(getSchemaResponseObject.getJSONObject("result").optJSONObject("data")); + } + + @Test + public void testBuildSchemaRequestWorksForMissedFields() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String data = "{\"name\":\"name\",\"version\":\"1.0\"}"; + + Ledger.buildSchemaRequest(identifier, data).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/ClosePoolTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/ClosePoolTest.java new file mode 100644 index 0000000000..cceb3a8750 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/ClosePoolTest.java @@ -0,0 +1,48 @@ +package org.hyperledger.indy.sdk.pool; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; + +public class ClosePoolTest extends IndyIntegrationTest { + + @Test + public void testClosePoolWorks() throws Exception { + Pool pool = PoolUtils.createAndOpenPoolLedger(); + assertNotNull(pool); + openedPools.add(pool); + + pool.closePoolLedger().get(); + openedPools.remove(pool); + } + + @Test + public void testClosePoolWorksForTwice() throws Exception { + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.PoolLedgerInvalidPoolHandle)); + + Pool pool = PoolUtils.createAndOpenPoolLedger(); + assertNotNull(pool); + openedPools.add(pool); + + pool.closePoolLedger().get(); + openedPools.remove(pool); + pool.closePoolLedger().get(); + } + + @Test + public void testClosePoolWorksForReopenAfterClose() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(); + + Pool pool = Pool.openPoolLedger(poolName, null).get(); + assertNotNull(pool); + + pool.closePoolLedger().get(); + + pool = Pool.openPoolLedger(poolName, null).get(); + openedPools.add(pool); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/CreatePoolTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/CreatePoolTest.java new file mode 100644 index 0000000000..848bf042f5 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/CreatePoolTest.java @@ -0,0 +1,43 @@ +package org.hyperledger.indy.sdk.pool; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.junit.Test; + +import java.io.File; + +import static org.junit.Assert.assertTrue; + +public class CreatePoolTest extends IndyIntegrationTest { + + @Test + public void testCreatePoolWorksForNullConfig() throws Exception { + File file = new File("testCreatePoolWorks.txn"); + file.deleteOnExit(); + assertTrue(file.createNewFile()); + + Pool.createPoolLedgerConfig("testCreatePoolWorks", null).get(); + } + + @Test + public void testCreatePoolWorksForConfigJSON() throws Exception { + File genesisTxnFile = PoolUtils.createGenesisTxnFile("genesis.txn"); + + PoolJSONParameters.CreatePoolLedgerConfigJSONParameter createPoolLedgerConfigJSONParameter + = new PoolJSONParameters.CreatePoolLedgerConfigJSONParameter(genesisTxnFile.getAbsolutePath()); + Pool.createPoolLedgerConfig("testCreatePoolWorks", createPoolLedgerConfigJSONParameter.toJson()).get(); + } + + @Test + public void testCreatePoolWorksForEmptyName() throws Exception { + thrown.expect(new ErrorCodeMatcher(ErrorCode.CommonInvalidParam2)); + + File genesisTxnFile = PoolUtils.createGenesisTxnFile("genesis.txn"); + + PoolJSONParameters.CreatePoolLedgerConfigJSONParameter createPoolLedgerConfigJSONParameter + = new PoolJSONParameters.CreatePoolLedgerConfigJSONParameter(genesisTxnFile.getAbsolutePath()); + Pool.createPoolLedgerConfig("", createPoolLedgerConfigJSONParameter.toJson()).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/DeletePoolTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/DeletePoolTest.java new file mode 100644 index 0000000000..a2fd14aba3 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/DeletePoolTest.java @@ -0,0 +1,29 @@ +package org.hyperledger.indy.sdk.pool; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; + +public class DeletePoolTest extends IndyIntegrationTest { + + @Test + public void testDeletePoolWorks() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(); + Pool.deletePoolLedgerConfig(poolName).get(); + } + + @Test + public void testDeletePoolWorksForOpened() throws Exception { + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidState)); + + String poolName = PoolUtils.createPoolLedgerConfig(); + Pool pool = Pool.openPoolLedger(poolName, null).get(); + assertNotNull(pool); + openedPools.add(pool); + Pool.deletePoolLedgerConfig(poolName).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/OpenPoolTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/OpenPoolTest.java new file mode 100644 index 0000000000..20cae4b4a9 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/OpenPoolTest.java @@ -0,0 +1,68 @@ +package org.hyperledger.indy.sdk.pool; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.pool.PoolJSONParameters.OpenPoolLedgerJSONParameter; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; + +public class OpenPoolTest extends IndyIntegrationTest { + + @Test + public void testOpenPoolWorksForNullConfig() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(); + + Pool pool = Pool.openPoolLedger(poolName, null).get(); + + assertNotNull(pool); + openedPools.add(pool); + } + + @Test + public void testOpenPoolWorksForConfig() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(); + + OpenPoolLedgerJSONParameter config = new OpenPoolLedgerJSONParameter(true, null, null); + Pool pool = Pool.openPoolLedger(poolName, config.toJson()).get(); + + assertNotNull(pool); + openedPools.add(pool); + } + + @Test + public void testOpenPoolWorksForTwice() throws Exception { + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.PoolLedgerInvalidPoolHandle)); + + String poolName = PoolUtils.createPoolLedgerConfig(); + + Pool pool = Pool.openPoolLedger(poolName, null).get(); + assertNotNull(pool); + openedPools.add(pool); + + Pool.openPoolLedger(poolName, null).get(); + } + + @Test + public void testOpenPoolWorksForTwoNodes() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(2); + + Pool pool = Pool.openPoolLedger(poolName, null).get(); + + assertNotNull(pool); + openedPools.add(pool); + } + + @Test + public void testOpenPoolWorksForThreeNodes() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(3); + + Pool pool = Pool.openPoolLedger(poolName, null).get(); + + assertNotNull(pool); + openedPools.add(pool); + } + +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/RefreshPoolTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/RefreshPoolTest.java new file mode 100644 index 0000000000..645d7938cf --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/pool/RefreshPoolTest.java @@ -0,0 +1,19 @@ +package org.hyperledger.indy.sdk.pool; + +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; + +public class RefreshPoolTest extends IndyIntegrationTest { + + @Test + public void testRefreshPoolWorks() throws Exception { + Pool pool = PoolUtils.createAndOpenPoolLedger(); + assertNotNull(pool); + openedPools.add(pool); + + pool.refreshPoolLedger().get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/CreateMyDidTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/CreateMyDidTest.java new file mode 100644 index 0000000000..5a54d117be --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/CreateMyDidTest.java @@ -0,0 +1,144 @@ +package org.hyperledger.indy.sdk.signus; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.signus.SignusResults.CreateAndStoreMyDidResult; +import org.hyperledger.indy.sdk.wallet.Wallet; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.bitcoinj.core.Base58; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +public class CreateMyDidTest extends IndyIntegrationTest { + + private Wallet wallet; + private String walletName = "signusWallet"; + + @Before + public void createWallet() throws Exception { + + Wallet.createWallet("default", walletName, "default", null, null).get(); + this.wallet = Wallet.openWallet(walletName, null, null).get(); + } + + @After + public void deleteWallet() throws Exception { + this.wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + private String seed = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + private String did = "8wZcEriaNLNKtteJvx7f8i"; + private String expectedVerkey = "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW"; + private String existsCryptoType = "ed25519"; + private String expectedDid = "NcYxiDXkpYi6ov5FcYDi1e"; + + + @Test + public void testCreateMyDidWorksForEmptyJson() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, null, null, null); + + CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(this.wallet, didJson.toJson()).get(); + assertNotNull(result); + + assertEquals(16, Base58.decode(result.getDid()).length); + assertEquals(32, Base58.decode(result.getVerkey()).length); + } + + @Test + public void testCreateMyDidWorksForSeed() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, seed, null, null); + + CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(this.wallet, didJson.toJson()).get(); + assertNotNull(result); + + assertEquals(expectedDid, result.getDid()); + assertEquals(expectedVerkey, result.getVerkey()); + } + + @Test + public void testCreateMyDidWorksAsCid() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, seed, null, true); + + CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(this.wallet, didJson.toJson()).get(); + assertNotNull(result); + + assertEquals(expectedVerkey, result.getDid()); + assertEquals(expectedVerkey, result.getVerkey()); + } + + @Test + public void testCreateMyDidWorksForPassedDid() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(did, null, null, false); + + CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(this.wallet, didJson.toJson()).get(); + assertNotNull(result); + + assertEquals(did, result.getDid()); + } + + @Test + public void testCreateMyDidWorksForCorrectCryptoType() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, seed, existsCryptoType, null); + + CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(this.wallet, didJson.toJson()).get(); + assertNotNull(result); + + assertEquals(expectedDid, result.getDid()); + assertEquals(expectedVerkey, result.getVerkey()); + } + + @Test + public void testCreateMyDidWorksForInvalidSeed() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, "aaaaaaaaaaa", null, null); + + Signus.createAndStoreMyDid(this.wallet, didJson.toJson()).get(); + } + + @Test + public void testCreateMyDidWorksForInvalidCryptoType() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.SignusUnknownCryptoError)); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, null, "crypto_type", null); + + Signus.createAndStoreMyDid(this.wallet, didJson.toJson()).get(); + } + + @Test + public void testCreateMyDidWorksForAllParams() throws Exception { + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(did, seed, existsCryptoType, true); + + CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(this.wallet, didJson.toJson()).get(); + assertNotNull(result); + + assertEquals(did, result.getDid()); + assertEquals(expectedVerkey, result.getVerkey()); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/ReplaceKeysTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/ReplaceKeysTest.java new file mode 100644 index 0000000000..928f74e6bb --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/ReplaceKeysTest.java @@ -0,0 +1,75 @@ +package org.hyperledger.indy.sdk.signus; + +import org.bitcoinj.core.Base58; +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.signus.SignusResults.CreateAndStoreMyDidResult; +import org.hyperledger.indy.sdk.wallet.Wallet; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +public class ReplaceKeysTest extends IndyIntegrationTest { + + private Wallet wallet; + private String did; + private String verkey; + private String walletName = "signusWallet"; + + @Before + public void createWalletWithDid() throws Exception { + Wallet.createWallet("default", walletName, "default", null, null).get(); + wallet = Wallet.openWallet(walletName, null, null).get(); + + CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(this.wallet, "{}").get(); + + did = result.getDid(); + verkey = result.getVerkey(); + } + + @After + public void deleteWallet() throws Exception { + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + @Test + public void testReplaceKeysWorksForEmptyJson() throws Exception { + SignusResults.ReplaceKeysResult result = Signus.replaceKeys(wallet, did, "{}").get(); + assertNotNull(result); + + assertEquals(32, Base58.decode(result.getVerkey()).length); + } + + @Test + public void testReplaceKeysWorksForInvalidDid() throws Exception { + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + Signus.replaceKeys(this.wallet, "invalid_base58_string", "{}").get(); + } + + @Test + public void testReplaceKeysWorksForNotExistsDid() throws Exception { + SignusResults.ReplaceKeysResult result = Signus.replaceKeys(this.wallet, "8wZcEriaNLNKtteJvx7f8i", "{}").get(); + assertNotNull(result); + } + + @Test + public void testReplaceKeysWorksForSeed() throws Exception { + SignusResults.ReplaceKeysResult result = Signus.replaceKeys(this.wallet, this.did, "{\"seed\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}").get(); + assertNotNull(result); + String verkey = result.getVerkey(); + + assertEquals("CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW", verkey); + assertNotEquals(this.verkey, verkey); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/SignTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/SignTest.java new file mode 100644 index 0000000000..842324adef --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/SignTest.java @@ -0,0 +1,81 @@ +package org.hyperledger.indy.sdk.signus; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.signus.SignusResults.CreateAndStoreMyDidResult; +import org.hyperledger.indy.sdk.wallet.Wallet; + +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +public class SignTest extends IndyIntegrationTest { + + + private Wallet wallet; + private String did; + private String walletName = "signusWallet"; + + @Before + public void createWalletWhitDid() throws Exception { + Wallet.createWallet("default", walletName, "default", null, null).get(); + this.wallet = Wallet.openWallet(walletName, null, null).get(); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, null); + + CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(this.wallet, didJson.toJson()).get(); + did = result.getDid(); + } + + @After + public void deleteWallet() throws Exception { + this.wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + @Test + public void testSignWorks() throws Exception { + + String msg = "{\n" + + " \"reqId\":1496822211362017764,\n" + + " \"identifier\":\"GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL\",\n" + + " \"operation\":{\n" + + " \"type\":\"1\",\n" + + " \"dest\":\"VsKV7grR1BUE29mG2Fm2kX\",\n" + + " \"verkey\":\"GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa\"\n" + + " }\n" + + " }"; + + String expectedSignature = "\"signature\":\"65hzs4nsdQsTUqLCLy2qisbKLfwYKZSWoyh1C6CU59p5pfG3EHQXGAsjW4Qw4QdwkrvjSgQuyv8qyABcXRBznFKW\""; + + String signedMessage = Signus.sign(this.wallet, did, msg).get(); + + assertTrue(signedMessage.contains(expectedSignature)); + } + + @Test + public void testSignWorksForUnknowDid() throws Exception { + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.WalletNotFoundError)); + + String msg = "{\"reqId\":1496822211362017764}"; + + Signus.sign(this.wallet, "8wZcEriaNLNKtteJvx7f8i", msg).get(); + } + + @Test + public void testSignWorksForInvalidMessageFormat() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String msg = "reqId:1495034346617224651"; + Signus.sign(this.wallet, did, msg).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/StoreTheirDidTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/StoreTheirDidTest.java new file mode 100644 index 0000000000..97a5d6fe39 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/StoreTheirDidTest.java @@ -0,0 +1,73 @@ +package org.hyperledger.indy.sdk.signus; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +public class StoreTheirDidTest extends IndyIntegrationTest { + + + private Wallet wallet; + private String walletName = "signusWallet"; + private String did = "8wZcEriaNLNKtteJvx7f8i"; + private String verkey = "GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa"; + + @Before + public void createWallet() throws Exception { + Wallet.createWallet("default", walletName, "default", null, null).get(); + this.wallet = Wallet.openWallet(walletName, null, null).get(); + + } + + @After + public void deleteWallet() throws Exception { + + this.wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + } + + @Test + public void testStoreTheirDidWorks() throws Exception { + Signus.storeTheirDid(this.wallet, String.format("{\"did\":\"%s\"}", did)).get(); + } + + @Test + public void testCreateMyDidWorksForInvalidIdentityJson() throws Exception { + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + Signus.storeTheirDid(this.wallet, "{\"field\":\"value\"}").get(); + } + + @Test + public void testStoreTheirDidWorksWithVerkey() throws Exception { + Signus.storeTheirDid(this.wallet, String.format("{\"did\":\"%s\", \"verkey\":\"%s\"}", did, verkey)).get(); + } + + @Test + public void testStoreTheirDidWorksWithoutDid() throws Exception { + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + Signus.storeTheirDid(this.wallet, String.format("{\"verkey\":\"%s\"}", verkey)).get(); + } + + @Test + public void testStoreTheirDidWorksForCorrectCryptoType() throws Exception { + Signus.storeTheirDid(this.wallet, String.format("{\"did\":\"%s\", \"verkey\":\"%s\", \"crypto_type\": \"ed25519\"}", did, verkey)).get(); + } + + @Test + public void testStoreTheirDidWorksForInvalidCryptoType() throws Exception { + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.SignusUnknownCryptoError)); + + Signus.storeTheirDid(this.wallet, String.format("{\"did\":\"%s\", \"verkey\":\"%s\", \"crypto_type\": \"some_type\"}", did, verkey)).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/VerifyTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/VerifyTest.java new file mode 100644 index 0000000000..02fb556c76 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/signus/VerifyTest.java @@ -0,0 +1,177 @@ +package org.hyperledger.indy.sdk.signus; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.hyperledger.indy.sdk.ledger.Ledger; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.pool.PoolJSONParameters; +import org.hyperledger.indy.sdk.signus.SignusResults.CreateAndStoreMyDidResult; +import org.hyperledger.indy.sdk.utils.PoolUtils; +import org.hyperledger.indy.sdk.wallet.Wallet; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; + +import static junit.framework.TestCase.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +public class VerifyTest extends IndyIntegrationTest { + + private Pool pool; + private Wallet wallet; + private String trusteeDid; + private String trusteeVerkey; + private String identityJson; + private String newDid; + private String walletName = "signusWallet"; + + @Before + public void createWalletWithDid() throws Exception { + String poolName = PoolUtils.createPoolLedgerConfig(); + + PoolJSONParameters.OpenPoolLedgerJSONParameter config2 = new PoolJSONParameters.OpenPoolLedgerJSONParameter(null, null, null); + pool = Pool.openPoolLedger(poolName, config2.toJson()).get(); + + Wallet.createWallet(poolName, walletName, "default", null, null).get(); + wallet = Wallet.openWallet(walletName, null, null).get(); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, TRUSTEE_SEED, null, false); + + CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(wallet, didJson.toJson()).get(); + assertNotNull(result); + + trusteeDid = result.getDid(); + trusteeVerkey = result.getVerkey(); + } + + @After + public void deleteWallet() throws Exception { + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + pool.closePoolLedger().get(); + } + + private void createNewNymWithDidInLedger() throws Exception { + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, "00000000000000000000000000000My1", null, null); + + CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(wallet, didJson.toJson()).get(); + newDid = result.getDid(); + String newVerkey = result.getVerkey(); + + String nymRequest = Ledger.buildNymRequest(trusteeDid, newDid, newVerkey, null, null).get(); + Ledger.signAndSubmitRequest(pool, wallet, trusteeDid, nymRequest).get(); + } + + @Test + public void testVerifyWorksForVerkeyCachedInWallet() throws Exception { + identityJson = String.format("{\"did\":\"%s\",\"verkey\":\"%s\"}", trusteeDid, trusteeVerkey); + Signus.storeTheirDid(wallet, identityJson).get(); + + String msg = "{\n" + + " \"reqId\":1496822211362017764,\n" + + " \"identifier\":\"GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL\",\n" + + " \"operation\":{\n" + + " \"type\":\"1\",\n" + + " \"dest\":\"VsKV7grR1BUE29mG2Fm2kX\",\n" + + " \"verkey\":\"GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa\"\n" + + " },\n" + + " \"signature\":\"65hzs4nsdQsTUqLCLy2qisbKLfwYKZSWoyh1C6CU59p5pfG3EHQXGAsjW4Qw4QdwkrvjSgQuyv8qyABcXRBznFKW\"\n" + + " }"; + + Boolean valid = Signus.verifySignature(wallet, pool, trusteeDid, msg).get(); + assertTrue(valid); + } + + @Test + public void testVerifyWorksForGetVerkeyFromLedger() throws Exception { + createNewNymWithDidInLedger(); + Signus.storeTheirDid(wallet, String.format("{\"did\":\"%s\"}", newDid)).get(); + + String msg = "{\"reqId\":1496822211362017764,\n" + + "\"signature\":\"tibTuE59pZn1sCeZpNL5rDzpkpqV3EkDmRpFTizys9Gr3ZieLdGEGyq4h8jsVWW9zSaXSRnfYcVb1yTjUJ7vJai\"}"; + + Boolean valid = Signus.verifySignature(wallet, pool, newDid, msg).get(); + assertTrue(valid); + } + + @Test + public void testVerifyWorksForGetNymFromLedger() throws Exception { + createNewNymWithDidInLedger(); + String msg = "{\"reqId\":1496822211362017764,\n" + + "\"signature\":\"tibTuE59pZn1sCeZpNL5rDzpkpqV3EkDmRpFTizys9Gr3ZieLdGEGyq4h8jsVWW9zSaXSRnfYcVb1yTjUJ7vJai\"}"; + + Boolean valid = Signus.verifySignature(wallet, pool, newDid, msg).get(); + assertTrue(valid); + } + + @Test + public void testVerifyWorksForInvalidMessageFormat() throws Exception { + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String msg = "\"signature\":\"65hzs4nsdQsTUqLCLy2qisbKLfwYKZSWoyh1C6CU59p5pfG3EHQXGAsjW4Qw4QdwkrvjSgQuyv8qyABcXRBznFKW\""; + + Signus.verifySignature(wallet, pool, trusteeDid, msg).get(); + } + + @Test + public void testVerifyWorksForMessageWithoutSignature() throws Exception { + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonInvalidStructure)); + + String msg = "{\n" + + " \"reqId\":1496822211362017764,\n" + + " \"identifier\":\"GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL\",\n" + + " \"operation\":{\n" + + " \"type\":\"1\",\n" + + " \"dest\":\"VsKV7grR1BUE29mG2Fm2kX\",\n" + + " \"verkey\":\"GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa\"\n" + + " },\n" + + " }"; + + Signus.verifySignature(wallet, pool, trusteeDid, msg).get(); + } + + @Test + public void testVerifyWorksForOtherSigner() throws Exception { + identityJson = String.format("{\"did\":\"%s\", \"verkey\":\"%s\"}", trusteeDid, trusteeVerkey); + + Signus.storeTheirDid(wallet, identityJson).get(); + + SignusJSONParameters.CreateAndStoreMyDidJSONParameter didJson = + new SignusJSONParameters.CreateAndStoreMyDidJSONParameter(null, "000000000000000000000000Steward1", null, null); + + CreateAndStoreMyDidResult result = Signus.createAndStoreMyDid(wallet, didJson.toJson()).get(); + String stewardDid = result.getDid(); + String stewardVerkey = result.getVerkey(); + + identityJson = String.format("{\"did\":\"%s\", \"verkey\":\"%s\"}", stewardDid, stewardVerkey); + + Signus.storeTheirDid(wallet, identityJson).get(); + + String msg = "{\n" + + " \"reqId\":1496822211362017764,\n" + + " \"identifier\":\"GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL\",\n" + + " \"operation\":{\n" + + " \"type\":\"1\",\n" + + " \"dest\":\"VsKV7grR1BUE29mG2Fm2kX\",\n" + + " \"verkey\":\"GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa\"\n" + + " }\n" + + " }"; + + String signedMessage = Signus.sign(wallet, trusteeDid, msg).get(); + + Boolean valid = Signus.verifySignature(wallet, pool, stewardDid, signedMessage).get(); + + assertFalse(valid); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/utils/InitHelper.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/utils/InitHelper.java new file mode 100644 index 0000000000..68f42af497 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/utils/InitHelper.java @@ -0,0 +1,14 @@ +package org.hyperledger.indy.sdk.utils; + + +import org.hyperledger.indy.sdk.LibIndy; + +import java.io.File; + +public class InitHelper { + public static void init() { + + if (!LibIndy.isInitialized()) LibIndy.init(new File("./lib/libindy.so")); + + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/utils/PoolUtils.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/utils/PoolUtils.java new file mode 100644 index 0000000000..80cd869ec9 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/utils/PoolUtils.java @@ -0,0 +1,67 @@ +package org.hyperledger.indy.sdk.utils; + +import org.apache.commons.io.FileUtils; +import org.hyperledger.indy.sdk.IndyException; +import org.hyperledger.indy.sdk.pool.Pool; +import org.hyperledger.indy.sdk.pool.PoolJSONParameters; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class PoolUtils { + + public static final String DEFAULT_POOL_NAME = "default_pool"; + + public static File createGenesisTxnFile(String filename) throws IOException { + return createGenesisTxnFile(filename, 4); + } + + public static File createGenesisTxnFile(String filename, int nodesCnt) throws IOException { + String path = StorageUtils.getTmpPath(filename); + String[] defaultTxns = new String[]{ + "{\"data\":{\"alias\":\"Node1\",\"client_ip\":\"10.0.0.2\",\"client_port\":9702,\"node_ip\":\"10.0.0.2\",\"node_port\":9701,\"services\":[\"VALIDATOR\"]},\"dest\":\"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv\",\"identifier\":\"Th7MpTaRZVRYnPiabds81Y\",\"txnId\":\"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62\",\"type\":\"0\"}", + "{\"data\":{\"alias\":\"Node2\",\"client_ip\":\"10.0.0.2\",\"client_port\":9704,\"node_ip\":\"10.0.0.2\",\"node_port\":9703,\"services\":[\"VALIDATOR\"]},\"dest\":\"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb\",\"identifier\":\"EbP4aYNeTHL6q385GuVpRV\",\"txnId\":\"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc\",\"type\":\"0\"}", + "{\"data\":{\"alias\":\"Node3\",\"client_ip\":\"10.0.0.2\",\"client_port\":9706,\"node_ip\":\"10.0.0.2\",\"node_port\":9705,\"services\":[\"VALIDATOR\"]},\"dest\":\"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya\",\"identifier\":\"4cU41vWW82ArfxJxHkzXPG\",\"txnId\":\"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4\",\"type\":\"0\"}", + "{\"data\":{\"alias\":\"Node4\",\"client_ip\":\"10.0.0.2\",\"client_port\":9708,\"node_ip\":\"10.0.0.2\",\"node_port\":9707,\"services\":[\"VALIDATOR\"]},\"dest\":\"4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA\",\"identifier\":\"TWwCRQRZ2ZHMJFn9TzLp7W\",\"txnId\":\"aa5e817d7cc626170eca175822029339a444eb0ee8f0bd20d3b0b76e566fb008\",\"type\":\"0\"}" + }; + + File file = new File(path); + + FileUtils.forceMkdirParent(file); + + FileWriter fw = new FileWriter(file); + for (int i = 0; i < nodesCnt; i++) { + fw.write(defaultTxns[i]); + fw.write("\n"); + } + + fw.close(); + + return file; + } + + public static String createPoolLedgerConfig() throws InterruptedException, ExecutionException, IndyException, IOException { + return createPoolLedgerConfig(4); + } + + public static String createPoolLedgerConfig(int nodesCnt) throws InterruptedException, ExecutionException, IndyException, IOException { + createPoolLedgerConfig(DEFAULT_POOL_NAME, nodesCnt); + return DEFAULT_POOL_NAME; + } + + public static void createPoolLedgerConfig(String poolName, int nodesCnt) throws IOException, InterruptedException, java.util.concurrent.ExecutionException, IndyException { + File genesisTxnFile = createGenesisTxnFile("temp.txn", nodesCnt); + PoolJSONParameters.CreatePoolLedgerConfigJSONParameter createPoolLedgerConfigJSONParameter + = new PoolJSONParameters.CreatePoolLedgerConfigJSONParameter(genesisTxnFile.getAbsolutePath()); + Pool.createPoolLedgerConfig(poolName, createPoolLedgerConfigJSONParameter.toJson()).get(); + } + + public static Pool createAndOpenPoolLedger() throws IndyException, InterruptedException, ExecutionException, IOException { + String poolName = PoolUtils.createPoolLedgerConfig(); + + PoolJSONParameters.OpenPoolLedgerJSONParameter config = new PoolJSONParameters.OpenPoolLedgerJSONParameter(true, null, null); + return Pool.openPoolLedger(poolName, config.toJson()).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/utils/StorageUtils.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/utils/StorageUtils.java new file mode 100644 index 0000000000..9826e8b80f --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/utils/StorageUtils.java @@ -0,0 +1,41 @@ +package org.hyperledger.indy.sdk.utils; + +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; + + +public class StorageUtils { + + private static void cleanDirectory(File path) throws IOException { + if (path.isDirectory()) { + FileUtils.cleanDirectory(path); + } + } + + public static void cleanupStorage() throws IOException { + + File tmpDir = new File(getTmpPath()); + File homeDir = new File(getIndyHomePath()); + + StorageUtils.cleanDirectory(tmpDir); + StorageUtils.cleanDirectory(homeDir); + } + + public static String getIndyHomePath() { + return FileUtils.getUserDirectoryPath() + "/.indy/"; + } + + public static String getIndyHomePath(String filename) { + return getIndyHomePath() + filename; + } + + public static String getTmpPath() { + return FileUtils.getTempDirectoryPath() + "/indy/"; + } + + public static String getTmpPath(String filename) { + return getTmpPath() + filename; + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/CloseWalletTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/CloseWalletTest.java new file mode 100644 index 0000000000..29bd43510f --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/CloseWalletTest.java @@ -0,0 +1,62 @@ +package org.hyperledger.indy.sdk.wallet; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + + +public class CloseWalletTest extends IndyIntegrationTest { + + @Test + public void testCloseWalletWorks() throws Exception { + + String walletName = "closeWalletWorks"; + + Wallet.createWallet("default", walletName, "default", null, null).get(); + + Wallet wallet = Wallet.openWallet(walletName, null, null).get(); + assertNotNull(wallet); + + wallet.closeWallet().get(); + } + + @Test + public void testCloseWalletWorksForTwice() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.WalletInvalidHandle)); + + String walletName = "closeWalletWorksForTwice"; + + Wallet.createWallet("default", walletName, "default", null, null).get(); + + Wallet wallet = Wallet.openWallet(walletName, null, null).get(); + assertNotNull(wallet); + + wallet.closeWallet().get(); + wallet.closeWallet().get(); + } + + @Test + public void testCloseWalletWorksForPlugged() throws Exception { + WalletTypeInmem.getInstance().clear(); + + String type = "inmem"; + String walletName = "testCloseWalletWorksForPlugged"; + + Wallet.registerWalletType(type, WalletTypeInmem.getInstance(), false).get(); + Wallet.createWallet("default", walletName, type, null, null).get(); + + Wallet wallet = Wallet.openWallet(walletName, null, null).get(); + wallet.closeWallet().get(); + Wallet.openWallet(walletName, null, null).get(); + + WalletTypeInmem.getInstance().clear(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/CreateWalletTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/CreateWalletTest.java new file mode 100644 index 0000000000..a2a7615db8 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/CreateWalletTest.java @@ -0,0 +1,71 @@ +package org.hyperledger.indy.sdk.wallet; + +import java.util.concurrent.ExecutionException; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; +import org.junit.Test; + + +public class CreateWalletTest extends IndyIntegrationTest { + + @Test + public void testCreateWalletWorks() throws Exception { + + Wallet.createWallet("default", "createWalletWorks", "default", null, null).get(); + } + + @Test + public void testCreateWalletWorksForPlugged() throws Exception { + WalletTypeInmem.getInstance().clear(); + + Wallet.registerWalletType("inmem", WalletTypeInmem.getInstance(), false).get(); + Wallet.createWallet("default", "createWalletWorks", "default", null, null).get(); + + WalletTypeInmem.getInstance().clear(); + } + + @Test + public void testCreateWalletWorksForEmptyType() throws Exception { + + Wallet.createWallet("default", "createWalletWorks", null, null, null).get(); + } + + @Test + public void testCreateWalletWorksForConfigJson() throws Exception { + + Wallet.createWallet("default", "createWalletWorks", null, "{\"freshness_time\":1000}", null).get(); + } + + @Test + public void testCreateWalletWorksForUnknowType() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.WalletUnknownTypeError)); + + Wallet.createWallet("default", "createWalletWorks", "unknow_type", null, null).get(); + } + + @Test + public void testCreateWalletWorksForEmptyName() throws Exception { + + thrown.expect(new ErrorCodeMatcher(ErrorCode.CommonInvalidParam3)); + + Wallet.createWallet("pool", "", "default", null, null).get(); + } + + @Test + public void testCreateWalletWorksForDuplicateName() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.WalletAlreadyExistsError)); + + String poolName = "default"; + String walletName = "deleteWalletWorks"; + String type = "default"; + + Wallet.createWallet(poolName, walletName, type, null, null).get(); + Wallet.createWallet(poolName, walletName, type, null, null).get(); + } +} \ No newline at end of file diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/DeleteWalletTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/DeleteWalletTest.java new file mode 100644 index 0000000000..179b62bb86 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/DeleteWalletTest.java @@ -0,0 +1,102 @@ +package org.hyperledger.indy.sdk.wallet; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Ignore; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + + +public class DeleteWalletTest extends IndyIntegrationTest { + + @Test + public void testDeleteWalletWorks() throws Exception { + + String poolName = "default"; + String walletName = "deleteWalletWorks"; + String type = "default"; + + Wallet.createWallet(poolName, walletName, type, null, null).get(); + Wallet.deleteWallet(walletName, null).get(); + Wallet.createWallet(poolName, walletName, type, null, null).get(); + } + + @Test + public void testDeleteWalletWorksForClosed() throws Exception { + + String poolName = "default"; + String walletName = "deleteWalletWorksForOpened"; + + Wallet.createWallet(poolName, walletName, null, null, null).get(); + + Wallet wallet = Wallet.openWallet(walletName, null, null).get(); + assertNotNull(wallet); + + wallet.closeWallet().get(); + Wallet.deleteWallet(walletName, null).get(); + Wallet.createWallet(poolName, walletName, null, null, null).get(); + } + + @Test + @Ignore//TODO THERE IS BUG IN INDY + public void testDeleteWalletWorksForOpened() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonIOError)); + + String walletName = "deleteWalletWorksForOpened"; + + Wallet.createWallet("default", walletName, null, null, null).get(); + Wallet.openWallet(walletName, null, null).get(); + Wallet.deleteWallet(walletName, null).get(); + } + + @Test + public void testDeleteWalletWorksForTwice() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonIOError)); + + String walletName = "deleteWalletWorksForTwice"; + + Wallet.createWallet("default", walletName, null, null, null).get(); + + Wallet wallet = Wallet.openWallet(walletName, null, null).get(); + assertNotNull(wallet); + + wallet.closeWallet().get(); + + Wallet.deleteWallet(walletName, null).get(); + Wallet.deleteWallet(walletName, null).get(); + } + + @Test + public void testDeleteWalletWorksForPlugged() throws Exception { + WalletTypeInmem.getInstance().clear(); + + String type = "inmem"; + String poolName = "default"; + String walletName = "wallet"; + + Wallet.registerWalletType(type, WalletTypeInmem.getInstance(), false).get(); + Wallet.createWallet(poolName, walletName, type, null, null).get(); + Wallet.deleteWallet(walletName, null).get(); + Wallet.createWallet(poolName, walletName, type, null, null).get(); + + WalletTypeInmem.getInstance().clear(); + } + + @Test + public void testDeleteWalletWorksForNotCreated() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonIOError)); + + Wallet.deleteWallet("deleteWalletWorksForTwice", null).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/OpenWalletTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/OpenWalletTest.java new file mode 100644 index 0000000000..a3cc8d27bc --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/OpenWalletTest.java @@ -0,0 +1,76 @@ +package org.hyperledger.indy.sdk.wallet; + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + + +public class OpenWalletTest extends IndyIntegrationTest { + + @Test + public void testOpenWalletWorks() throws Exception { + + String walletName = "deleteWalletWorks"; + + Wallet.createWallet("default", walletName, "default", null, null).get(); + + Wallet wallet = Wallet.openWallet(walletName, null, null).get(); + assertNotNull(wallet); + } + + @Test + public void testOpenWalletWorksForConfig() throws Exception { + + String walletName = "openWalletWorksForConfig"; + + Wallet.createWallet("default", walletName, "default", null, null).get(); + + Wallet wallet = Wallet.openWallet(walletName, "{\"freshness_time\":1000}", null).get(); + assertNotNull(wallet); + } + + @Test + public void testOpenWalletWorksForPlugged() throws Exception { + WalletTypeInmem.getInstance().clear(); + + String type = "inmem"; + String poolName = "default"; + String walletName = "testOpenWalletWorksForPlugged"; + + Wallet.registerWalletType(type, WalletTypeInmem.getInstance(), false).get(); + Wallet.createWallet(poolName, walletName, type, null, null).get(); + Wallet wallet = Wallet.openWallet(walletName, null, null).get(); + assertNotNull(wallet); + + WalletTypeInmem.getInstance().clear(); + } + + @Test + public void testOpenWalletWorksForNotCreatedWallet() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.CommonIOError)); + + Wallet.openWallet("openWalletWorksForNotCreatedWallet", null, null).get(); + } + + @Test + public void testOpenWalletWorksForTwice() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.WalletAlreadyOpenedError)); + + String walletName = "openWalletWorksForTwice"; + + Wallet.createWallet("default", walletName, "default", null, null).get(); + + Wallet.openWallet(walletName, null, null).get(); + Wallet.openWallet(walletName, null, null).get(); + } +} diff --git a/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/RegisterWalletTypeTest.java b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/RegisterWalletTypeTest.java new file mode 100644 index 0000000000..9a130298f3 --- /dev/null +++ b/wrappers/java/src/test/java/org/hyperledger/indy/sdk/wallet/RegisterWalletTypeTest.java @@ -0,0 +1,35 @@ +package org.hyperledger.indy.sdk.wallet; + + +import org.hyperledger.indy.sdk.ErrorCode; +import org.hyperledger.indy.sdk.ErrorCodeMatcher; +import org.hyperledger.indy.sdk.IndyIntegrationTest; + +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + + +public class RegisterWalletTypeTest extends IndyIntegrationTest { + + @Test + public void testRegisterWalletTypeWorks() throws Exception { + WalletTypeInmem.getInstance().clear(); + + Wallet.registerWalletType("inmem", WalletTypeInmem.getInstance(), false).get(); + + WalletTypeInmem.getInstance().clear(); + } + + @Test + public void testRegisterWalletTypeDoesNotWorkForTwiceWithSameName() throws Exception { + + thrown.expect(ExecutionException.class); + thrown.expectCause(new ErrorCodeMatcher(ErrorCode.WalletTypeAlreadyRegisteredError)); + + String type = "inmem"; + + Wallet.registerWalletType(type, WalletTypeInmem.getInstance(), false).get(); + Wallet.registerWalletType(type, WalletTypeInmem.getInstance(), true).get(); + } +} diff --git a/wrappers/python/.gitignore b/wrappers/python/.gitignore new file mode 100644 index 0000000000..0d20b6487c --- /dev/null +++ b/wrappers/python/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/wrappers/python/Jenkinsfile b/wrappers/python/Jenkinsfile new file mode 100644 index 0000000000..09d86d6579 --- /dev/null +++ b/wrappers/python/Jenkinsfile @@ -0,0 +1,91 @@ +#!groovy​ + +@Library('SovrinHelpers') _ + +name = 'indy-sdk' +def err +def publishBranch = (env.BRANCH_NAME == 'master' || env.BRANCH_NAME == 'devel') + +try { + +// ALL BRANCHES: master, devel, PRs + + // 1. TEST + stage('Test') { + parallel 'ubuntu-python-test': { + node('ubuntu') { + stage('Ubuntu Python Test') { + pythonTestUbuntu() + } + } + } + } + +} catch (e) { + currentBuild.result = "FAILED" + node('ubuntu-master') { + sendNotification.fail([slack: publishBranch]) + } + err = e +} finally { + if (err) { + throw err + } + currentBuild.result = "SUCCESS" + if (publishBranch) { + node('ubuntu-master') { + sendNotification.success(name) + } + } +} + +def pythonTestUbuntu() { + def poolInst + def network_name = "pool_network" + try { + echo 'Ubuntu Python Test: Checkout csm' + checkout scm + + echo "Ubuntu Python Test: Create docker network (${network_name}) for nodes pool and test image" + sh "docker network create --subnet=10.0.0.0/8 ${network_name}" + + echo 'Ubuntu Python Test: Build docker image for nodes pool' + def poolEnv = dockerHelpers.build('indy_pool', 'ci/indy-pool.dockerfile ci') + echo 'Ubuntu Python Test: Run nodes pool' + poolInst = poolEnv.run("--ip=\"10.0.0.2\" --network=${network_name}") + + echo 'Ubuntu Python Test: Build docker image' + def testEnv = dockerHelpers.build(name, 'ci/python.dockerfile ci') + + testEnv.inside("--ip=\"10.0.0.3\" --network=${network_name}") { + echo 'Ubuntu Python Test: Test' + + sh ''' + cd wrappers/python + python3.6 -m pip install -e . + python3.6 -m pytest + ''' + } + } + finally { + echo "Ubuntu Python Test: Cleanup" + try { + sh "docker network inspect ${network_name}" + } catch (err) { + echo "Ubuntu Python Tests: error while inspect network ${network_name} - ${err}" + } + try { + echo "Ubuntu Python Test: stop pool" + poolInst.stop() + } catch (err) { + echo "Ubuntu Python Tests: error while stop pool ${err}" + } + try { + echo "Ubuntu Python Test: remove pool network ${network_name}" + sh "docker network rm ${network_name}" + } catch (err) { + echo "Ubuntu Python Test: error while delete ${network_name} - ${err}" + } + step([$class: 'WsCleanup']) + } +} \ No newline at end of file diff --git a/wrappers/python/indy/__init__.py b/wrappers/python/indy/__init__.py new file mode 100644 index 0000000000..d68cac3eca --- /dev/null +++ b/wrappers/python/indy/__init__.py @@ -0,0 +1 @@ +from indy.error import IndyError diff --git a/wrappers/python/indy/agent.py b/wrappers/python/indy/agent.py new file mode 100644 index 0000000000..f18e45b2a6 --- /dev/null +++ b/wrappers/python/indy/agent.py @@ -0,0 +1,429 @@ +import asyncio +import logging +from ctypes import * +from typing import List, Tuple, Any + +from .error import ErrorCode, IndyError +from .libindy import do_call, create_cb + + +class Event: + """ + Base class for agent 2 agent communication events + + :handle: (int) Event source handle + :error: (IndyError) If event is erroneous contains related IndyError exception + """ + + handle: int + error: IndyError + + def is_success(self): + """ + Checks is event erroneous or not + + :return: True if there are no errors assigned to this event and False otherwise + """ + + return self.error is None + + +class ConnectionEvent(Event): + """ + Agent 2 agent communication listener's connection event + + :connection_handle: Incoming connection handle + :sender_did: Sender DID + :receiver_did: Receiver DID + """ + connection_handle: int + sender_did: str + receiver_did: str + + def __init__(self, handle: int, err: int, connection_handle: int, sender_did: bytes, receiver_did: bytes): + logger = logging.getLogger(__name__) + logger.debug("ConnectionEvent:__init__ >>> handle: %r, err: %r, connection_handle: %r, sender_did: %r, " + "receiver_did: %r", + handle, + err, + connection_handle, + sender_did, + receiver_did) + + self.handle = handle + + if err != ErrorCode.Success: + self.error = IndyError(ErrorCode(err)) + else: + self.connection_handle = connection_handle + self.sender_did = sender_did.decode() + self.receiver_did = receiver_did.decode() + + logger.debug("ConnectionEvent:__init__ <<< self: %r", self) + + +class MessageEvent(Event): + """ + Agent 2 agent communication connection's message event + + :message: Incoming message + """ + + message: str + + def __init__(self, handle: int, err: int, message: bytes): + logger = logging.getLogger(__name__) + logger.debug("MessageEvent:__init__ >>> handle: %r, err: %r, message: %r", + handle, + err, + message) + + self.handle = handle + + if err != ErrorCode.Success: + self._error = IndyError(ErrorCode(err)) + else: + self.message = message.decode() + + logger.debug("MessageEvent:__init__ <<< self: %r", self) + + +_events: List[Event] = [] +_event_waiters: List[Tuple[List[int], Any, Any]] = [] + + +def _notify_event_waiters(): + logger = logging.getLogger(__name__) + logger.debug("_notify_event_waiters: >>> _event_waiters: %r, _events: %r", + _event_waiters, + _events) + + for i, (handles, event_loop, future) in enumerate(_event_waiters): + for j, event in enumerate(_events): + if event.handle in handles: + del _event_waiters[i] + del _events[j] + event_loop.call_soon_threadsafe(lambda f, e: f.set_result(e), + future, + event) + logger.debug("_notify_event_waiters: <<< handles: %r, event: %r", handles, event) + return + + logger.debug("_notify_event_waiters: <<< no events") + + +async def agent_wait_for_event(handles: List[int]) -> Event: + """ + Waits for events for listeners and connections defined by list of corresponded handles + + :param handles: list of listeners or connections handles + :return: first occurred listener or connection event + """ + + logger = logging.getLogger(__name__) + logger.debug("agent_wait_for_event: >>> handles: %r", handles) + + event_loop = asyncio.get_event_loop() + future = event_loop.create_future() + + _event_waiters.append((handles, event_loop, future)) + _notify_event_waiters() + + res = await future + + logger.debug("agent_wait_for_event: <<< res: %r", res) + return res + + +async def agent_connect(pool_handle: int, + wallet_handle: int, + sender_did: str, + receiver_did: str) -> int: + """ + Establishes agent to agent connection. + + Information about sender Identity must be saved in the wallet with indy_create_and_store_my_did + call before establishing of connection. + + Information about receiver Identity can be saved in the wallet with indy_store_their_did + call before establishing of connection. If there is no corresponded wallet record for receiver Identity + than this call will lookup Identity Ledger and cache this information in the wallet. + + Note that messages encryption/decryption will be performed automatically. + + After connection is established returned connection handle can be used to wait for messages with + agent_wait_for_event or sending messages with agent_send. + + :param pool_handle: pool handle (created by open_pool_ledger). + :param wallet_handle: wallet handle (created by open_wallet). + :param sender_did: id of sender Identity stored in secured Wallet. + :param receiver_did: id of receiver Identity. + :return: connection handle to use for messages sending and waiting of incoming messages with agent_wait_for_event + """ + + logger = logging.getLogger(__name__) + logger.debug("agent_connect: >>> pool_handle: %r, wallet_handle: %r, sender_did: %r, receiver_did: %r", + pool_handle, + wallet_handle, + sender_did, + receiver_did) + + if not hasattr(agent_connect, "connection_cb"): + logger.debug("agent_connect: Creating connection callback") + agent_connect.connection_cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_int32)) + + def _message_cb(connection_handle: int, err: int, message: bytes): + logger.debug("agent_connect._message_cb: connection_handle: %r, err: %r, message: %r", + connection_handle, + err, + message) + _events.append(MessageEvent(connection_handle, err, message)) + _notify_event_waiters() + + if not hasattr(agent_connect, "message_cb"): + logger.debug("agent_connect: Creating message callback") + agent_connect.message_cb = CFUNCTYPE(None, c_int32, c_int32, c_char_p)(_message_cb) + + c_pool_handle = c_int32(pool_handle) + c_wallet_handle = c_int32(wallet_handle) + c_sender_did = c_char_p(sender_did.encode('utf-8')) + c_receiver_did = c_char_p(receiver_did.encode('utf-8')) + + res = await do_call('indy_agent_connect', + c_pool_handle, + c_wallet_handle, + c_sender_did, + c_receiver_did, + agent_connect.connection_cb, + agent_connect.message_cb) + + logger.debug("agent_connect: <<< res: %r", res) + return res + + +async def agent_listen(endpoint: str) -> int: + """ + Starts listening of agent connections. + + Listener will accept only connections to registered DIDs by indy_agent_add_identity call. + + Information about sender Identity for incomming connection validation can be saved in the wallet + with indy_store_their_did call before establishing of connection. If there is no corresponded + wallet record for sender Identity than listener will lookup Identity Ledger and cache this + information in the wallet. + + Note that messages encryption/decryption will be performed automatically. + + :param endpoint: endpoint to use in starting listener. + :return: listener handle to use for waiting of incoming connections with agent_wait_for_event and management of + assigned to this endpoint identities with agent_add_identity or agent_remove_identity. + """ + + logger = logging.getLogger(__name__) + logger.debug("agent_listen: >>> endpoint: %r", endpoint) + + if not hasattr(agent_listen, "listener_cb"): + logger.debug("agent_listen: Creating listener callback") + agent_listen.listener_cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_int32)) + + def _connection_cb(listener_handle: int, err: int, connection_handle: int, sender_did: bytes, receiver_did: bytes): + logger.debug("agent_connect._connection_cb: listener_handle: %r, err: %r, connection_handle: %r, sender_did: " + "%r, receiver_did: %r", + connection_handle, + err, + connection_handle, + sender_did, + receiver_did) + _events.append(ConnectionEvent(listener_handle, err, connection_handle, sender_did, receiver_did)) + _notify_event_waiters() + + if not hasattr(agent_listen, "connection_cb"): + logger.debug("agent_listen: Creating connection callback") + agent_listen.connection_cb = CFUNCTYPE(None, c_int32, c_int32, c_int32, c_char_p, c_char_p)(_connection_cb) + + def _message_cb(connection_handle: int, err: int, message: bytes): + logger.debug("agent_connect._message_cb: connection_handle: %r, err: %r, message: %r", + connection_handle, + err, + message) + _events.append(MessageEvent(connection_handle, err, message)) + _notify_event_waiters() + + if not hasattr(agent_listen, "message_cb"): + logger.debug("agent_connect: Creating message callback") + agent_listen.message_cb = CFUNCTYPE(None, c_int32, c_int32, c_char_p)(_message_cb) + + c_endpoint = c_char_p(endpoint.encode('utf-8')) + + res = await do_call('indy_agent_listen', + c_endpoint, + agent_listen.listener_cb, + agent_listen.connection_cb, + agent_listen.message_cb) + + logger.debug("agent_listen: <<< res: %r", res) + return res + + +async def agent_add_identity(listener_handle: int, + pool_handle: int, + wallet_handle: int, + did: str) -> None: + """ + Add identity to listener. + + Performs wallet lookup to find corresponded receiver Identity information. + Information about receiver Identity must be saved in the wallet with + indy_create_and_store_my_did call before this call. + + After successfully add_identity listener will start to accept incoming connection to added DID. + + :param listener_handle: listener handle (created by indy_agent_listen). + :param pool_handle: pool handle (created by open_pool_ledger). + :param wallet_handle: wallet handle (created by open_wallet). + :param did: DID of identity. + """ + logger = logging.getLogger(__name__) + logger.debug("agent_add_identity: >>> listener_handle: %r, pool_handle: %r, wallet_handle: %r, did: %r", + listener_handle, + pool_handle, + wallet_handle, + did) + + if not hasattr(agent_add_identity, "cb"): + logger.debug("agent_add_identity: Creating callback") + agent_add_identity.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_listener_handle = c_int32(listener_handle) + c_pool_handle = c_int32(pool_handle) + c_wallet_handle = c_int32(wallet_handle) + c_did = c_char_p(did.encode('utf-8')) + + await do_call('indy_agent_add_identity', + c_listener_handle, + c_pool_handle, + c_wallet_handle, + c_did, + agent_add_identity.cb) + + logger.debug("agent_add_identity: <<<") + + +async def agent_remove_identity(listener_handle: int, + wallet_handle: int, + did: str) -> None: + """ + Remove identity from listener. + + Performs wallet lookup to find corresponded receiver Identity information. + Information about receiver Identity must be saved in the wallet with + signus.create_and_store_my_did call before this call. + + After successfully rm_identity listener will stop to accept incoming connection to removed DID. + + :param listener_handle: listener handle (created by indy_agent_listen). + :param wallet_handle: wallet handle (created by open_wallet). + :param did: DID of identity. + """ + logger = logging.getLogger(__name__) + logger.debug("agent_remove_identity: >>> listener_handle: %r, wallet_handle: %r, did: %r", + listener_handle, + wallet_handle, + did) + + if not hasattr(agent_remove_identity, "cb"): + logger.debug("agent_remove_identity: Creating callback") + agent_remove_identity.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_listener_handle = c_int32(listener_handle) + c_wallet_handle = c_int32(wallet_handle) + c_did = c_char_p(did.encode('utf-8')) + + await do_call('indy_agent_remove_identity', + c_listener_handle, + c_wallet_handle, + c_did, + agent_remove_identity.cb) + + logger.debug("agent_remove_identity: <<<") + + +async def agent_send(connection_handle: int, message: str) -> None: + """" + Sends message to connected agent. + + Note that this call works for both incoming and outgoing connections. + Note that messages encryption/decryption will be performed automatically. + + :param connection_handle: connection handle returned by indy_agent_connect or indy_agent_listen calls. + :param message: message to send. + """ + + logger = logging.getLogger(__name__) + logger.debug("agent_send: >>> connection_handle: %r, message: %r", + connection_handle, + message) + + if not hasattr(agent_send, "cb"): + logger.debug("agent_send: Creating callback") + agent_send.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_connection_handle = c_int32(connection_handle) + c_message = c_char_p(message.encode('utf-8')) + + await do_call('indy_agent_send', + c_connection_handle, + c_message, + agent_send.cb) + + logger.debug("agent_send: <<<") + + +async def agent_close_connection(connection_handle: int) -> None: + """ + Closes agent connection. + + Note that this call works for both incoming and outgoing connections. + + :param connection_handle: connection handle returned by indy_agent_connect or indy_agent_listen calls. + """ + + logger = logging.getLogger(__name__) + logger.debug("agent_close_connection: >>> connection_handle: %r", connection_handle) + + if not hasattr(agent_close_connection, "cb"): + logger.debug("agent_close_connection: Creating callback") + agent_close_connection.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_connection_handle = c_int32(connection_handle) + + await do_call('indy_agent_close_connection', + c_connection_handle, + agent_close_connection.cb) + + logger.debug("agent_close_connection: <<<") + + +async def agent_close_listener(listener_handle: int) -> None: + """ + Closes listener and stops listening for agent connections. + + Note that all opened incomming connections will be closed automatically. + + :param listener_handle: Listener handle returned by indy_agent_listen call. + """ + + logger = logging.getLogger(__name__) + logger.debug("agent_close_listener: >>> listener_handle: %r", listener_handle) + + if not hasattr(agent_close_listener, "cb"): + logger.debug("agent_close_listener: Creating callback") + agent_close_listener.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_listener_handle = c_int32(listener_handle) + + await do_call('indy_agent_close_listener', + c_listener_handle, + agent_close_listener.cb) + + logger.debug("agent_close_listener: <<<") diff --git a/wrappers/python/indy/anoncreds.py b/wrappers/python/indy/anoncreds.py new file mode 100644 index 0000000000..fd89e7cd41 --- /dev/null +++ b/wrappers/python/indy/anoncreds.py @@ -0,0 +1,738 @@ +from .libindy import do_call, create_cb + +from typing import Optional +from ctypes import * + +import logging + + +async def issuer_create_and_store_claim_def(wallet_handle: int, + issuer_did: str, + schema_json: str, + signature_type: Optional[str], + create_non_revoc: bool) -> str: + """ + Create keys (both primary and revocation) for the given schema + and signature type (currently only CL signature type is supported). + Store the keys together with signature type and schema in a secure wallet as a claim definition. + The claim definition in the wallet is identifying by a returned unique key. + + :param wallet_handle: wallet handler (created by open_wallet). + :param issuer_did: a DID of the issuer signing claim_def transaction to the Ledger + :param schema_json: schema as a json + :param signature_type: signature type (optional). Currently only 'CL' is supported. + :param create_non_revoc: whether to request non-revocation claim. + :return: claim definition json containing information about signature type, schema and issuer's public key. + Unique number identifying the public key in the wallet + """ + + logger = logging.getLogger(__name__) + logger.debug("issuer_create_and_store_claim_def: >>> wallet_handle: %r, issuer_did: %r, schema_json: %r," + " signature_type: %r, create_non_revoc: %r", + wallet_handle, + issuer_did, + schema_json, + signature_type, + create_non_revoc) + + if not hasattr(issuer_create_and_store_claim_def, "cb"): + logger.debug("issuer_create_and_store_claim_def: Creating callback") + issuer_create_and_store_claim_def.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_issuer_did = c_char_p(issuer_did.encode('utf-8')) + c_schema_json = c_char_p(schema_json.encode('utf-8')) + c_signature_type = c_char_p(signature_type.encode('utf-8')) if signature_type is not None else None + c_create_non_revoc = c_bool(create_non_revoc) + + claim_def_json = await do_call('indy_issuer_create_and_store_claim_def', + c_wallet_handle, + c_issuer_did, + c_schema_json, + c_signature_type, + c_create_non_revoc, + issuer_create_and_store_claim_def.cb) + res = claim_def_json.decode() + logger.debug("issuer_create_and_store_claim_def: <<< res: %r", res) + return res + + +async def issuer_create_and_store_revoc_reg(wallet_handle: int, + issuer_did: str, + schema_seq_no: int, + max_claim_num: int) -> (str, str): + """ + Create a new revocation registry for the given claim definition. + Stores it in a secure wallet identifying by the returned key. + + :param wallet_handle: wallet handler (created by open_wallet). + :param issuer_did: a DID of the issuer signing revoc_reg transaction to the Ledger + :param schema_seq_no: seq no of a schema transaction in Ledger + :param max_claim_num: maximum number of claims the new registry can process. + :return: Revoc registry json + Unique number identifying the revocation registry in the wallet + """ + + logger = logging.getLogger(__name__) + logger.debug("issuer_create_and_store_revoc_reg: >>> wallet_handle: %r, issuer_did: %r, schema_seq_no: %r," + " max_claim_num: %r", + wallet_handle, + issuer_did, + schema_seq_no, + max_claim_num) + + if not hasattr(issuer_create_and_store_revoc_reg, "cb"): + logger.debug("issuer_create_and_store_revoc_reg: Creating callback") + issuer_create_and_store_revoc_reg.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_issuer_did = c_char_p(issuer_did.encode('utf-8')) + c_schema_seq_no = c_int32(schema_seq_no) + c_max_claim_num = c_int32(max_claim_num) + + (revoc_reg_json, revoc_reg_uuid) = await do_call('indy_issuer_create_and_store_revoc_reg', + c_wallet_handle, + c_issuer_did, + c_schema_seq_no, + c_max_claim_num, + issuer_create_and_store_revoc_reg.cb) + res = (revoc_reg_json.decode(), revoc_reg_uuid.decode()) + logger.debug("issuer_create_and_store_revoc_reg: <<< res: %r", res) + return res + + +async def issuer_create_claim(wallet_handle: int, + claim_req_json: str, + claim_json: str, + revoc_reg_seq_no: int, + user_revoc_index: int) -> (str, str): + """ + Signs a given claim for the given user by a given key (claim ef). + The corresponding claim definition and revocation registry must be already created + an stored into the wallet. + + :param wallet_handle: wallet handler (created by open_wallet). + :param claim_req_json: a claim request with a blinded secret + from the user (returned by prover_create_and_store_claim_req). + Also contains schema_seq_no and issuer_did + Example: + { + "blinded_ms" : , + "schema_seq_no" : , + "issuer_did" : + } + :param claim_json: a claim containing attribute values for each of requested attribute names. + Example: + { + "attr1" : ["value1", "value1_as_int"], + "attr2" : ["value2", "value2_as_int"] + } + :param revoc_reg_seq_no: (Optional, pass -1 if revoc_reg_seq_no is absentee) seq no of a revocation + registry transaction in Ledger + :param user_revoc_index: index of a new user in the revocation registry + (optional, pass -1 if user_revoc_index is absentee; default one is used if not provided) + :return: Revocation registry update json with a newly issued claim + Claim json containing issued claim, issuer_did, schema_seq_no, and revoc_reg_seq_no + used for issuance + { + "claim": , + "signature": , + "revoc_reg_seq_no", string, + "issuer_did", string, + "schema_seq_no", string, + } + """ + + logger = logging.getLogger(__name__) + logger.debug("issuer_create_claim: >>> wallet_handle: %r, claim_req_json: %r, claim_json: %r," + " revoc_reg_seq_no: %r, user_revoc_index: %r", + wallet_handle, + claim_req_json, + claim_json, + revoc_reg_seq_no, + user_revoc_index) + + if not hasattr(issuer_create_claim, "cb"): + logger.debug("issuer_create_claim: Creating callback") + issuer_create_claim.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_claim_req_json = c_char_p(claim_req_json.encode('utf-8')) + c_claim_json = c_char_p(claim_json.encode('utf-8')) + c_revoc_reg_seq_no = c_int32(revoc_reg_seq_no) + c_user_revoc_index = c_int32(user_revoc_index) + + (revoc_reg_update_json, claim_json) = await do_call('indy_issuer_create_claim', + c_wallet_handle, + c_claim_req_json, + c_claim_json, + c_revoc_reg_seq_no, + c_user_revoc_index, + issuer_create_claim.cb) + res = (revoc_reg_update_json.decode(), claim_json.decode()) + logger.debug("issuer_create_claim: <<< res: %r", res) + return res + + +async def issuer_revoke_claim(wallet_handle: int, + revoc_reg_seq_no: int, + user_revoc_index: int) -> str: + """ + Revokes a user identified by a revoc_id in a given revoc-registry. + The corresponding claim definition and revocation registry must be already + created an stored into the wallet. + + :param wallet_handle: wallet handler (created by open_wallet). + :param revoc_reg_seq_no: seq no of a revocation registry transaction in Ledger + :param user_revoc_index: index of the user in the revocation registry + :return: Revocation registry update json with a revoked claim + """ + + logger = logging.getLogger(__name__) + logger.debug("issuer_revoke_claim: >>> wallet_handle: %r, revoc_reg_seq_no: %r, user_revoc_index: %r", + wallet_handle, + revoc_reg_seq_no, + user_revoc_index) + + if not hasattr(issuer_revoke_claim, "cb"): + logger.debug("issuer_revoke_claim: Creating callback") + issuer_revoke_claim.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_revoc_reg_seq_no = c_int32(revoc_reg_seq_no) + c_user_revoc_index = c_int32(user_revoc_index) + + revoc_reg_update_json = await do_call('indy_issuer_revoke_claim', + c_wallet_handle, + c_revoc_reg_seq_no, + c_user_revoc_index, + issuer_revoke_claim.cb) + res = revoc_reg_update_json.decode() + logger.debug("issuer_revoke_claim: <<< res: %r", res) + return res + + +async def prover_store_claim_offer(wallet_handle: int, + claim_offer_json: str) -> None: + """ + Stores a claim offer from the given issuer in a secure storage. + + :param wallet_handle: wallet handler (created by open_wallet). + :param claim_offer_json: claim offer as a json containing information about the issuer and a claim: + { + "issuer_did": string, + "schema_seq_no": string + } + :return: None. + """ + + logger = logging.getLogger(__name__) + logger.debug("prover_store_claim_offer: >>> wallet_handle: %r, claim_offer_json: %r", + wallet_handle, + claim_offer_json) + + if not hasattr(prover_store_claim_offer, "cb"): + logger.debug("prover_store_claim_offer: Creating callback") + prover_store_claim_offer.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_wallet_handle = c_int32(wallet_handle) + c_claim_offer_json = c_char_p(claim_offer_json.encode('utf-8')) + + res = await do_call('indy_prover_store_claim_offer', + c_wallet_handle, + c_claim_offer_json, + prover_store_claim_offer.cb) + + logger.debug("prover_store_claim_offer: <<< res: %r", res) + return res + + +async def prover_get_claim_offers(wallet_handle: int, + filter_json: str) -> str: + """ + Gets all stored claim offers (see prover_store_claim_offer). + A filter can be specified to get claim offers for specific Issuer, claim_def or schema only. + + :param wallet_handle: wallet handler (created by open_wallet). + :param filter_json: optional filter to get claim offers for specific Issuer, claim_def or schema only only + Each of the filters is optional and can be combines + { + "issuer_did": string, + "schema_seq_no": string + } + :return: A json with a list of claim offers for the filter. + { + [{"issuer_did": string, + "schema_seq_no": string}] + } + """ + + logger = logging.getLogger(__name__) + logger.debug("prover_store_claim_offer: >>> wallet_handle: %r, filter_json: %r", + wallet_handle, + filter_json) + + if not hasattr(prover_get_claim_offers, "cb"): + logger.debug("prover_get_claim_offers: Creating callback") + prover_get_claim_offers.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_filter_json = c_char_p(filter_json.encode('utf-8')) + + claim_offers_json = await do_call('indy_prover_get_claim_offers', + c_wallet_handle, + c_filter_json, + prover_get_claim_offers.cb) + + res = claim_offers_json.decode() + logger.debug("prover_get_claim_offers: <<< res: %r", res) + return res + + +async def prover_create_master_secret(wallet_handle: int, + master_secret_name: str) -> None: + """ + Creates a master secret with a given name and stores it in the wallet. + The name must be unique. + + :param wallet_handle: wallet handler (created by open_wallet). + :param master_secret_name: a new master secret name + :return: None. + """ + + logger = logging.getLogger(__name__) + logger.debug("prover_create_master_secret: >>> wallet_handle: %r, master_secret_name: %r", + wallet_handle, + master_secret_name) + + if not hasattr(prover_create_master_secret, "cb"): + logger.debug("prover_create_master_secret: Creating callback") + prover_create_master_secret.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_wallet_handle = c_int32(wallet_handle) + c_master_secret_name = c_char_p(master_secret_name.encode('utf-8')) + + res = await do_call('indy_prover_create_master_secret', + c_wallet_handle, + c_master_secret_name, + prover_create_master_secret.cb) + + logger.debug("prover_create_master_secret: <<< res: %r", res) + return res + + +async def prover_create_and_store_claim_req(wallet_handle: int, + prover_did: str, + claim_offer_json: str, + claim_def_json: str, + master_secret_name: str) -> str: + """ + Creates a clam request json for the given claim offer and stores it in a secure wallet. + The claim offer contains the information about Issuer (DID, schema_seq_no), + and the schema (schema_seq_no). + The method gets public key and schema from the ledger, stores them in a wallet, + and creates a blinded master secret for a master secret identified by a provided name. + The master secret identified by the name must be already stored in the secure wallet (see prover_create_master_secret) + The blinded master secret is a part of the claim request. + + :param wallet_handle: wallet handler (created by open_wallet). + :param prover_did: a DID of the prover + :param claim_offer_json: claim offer as a json containing information about the issuer and a claim: + { + "issuer_did": string, + "schema_seq_no": string + } + :param claim_def_json: claim definition json associated with issuer_did and schema_seq_no in the claim_offer + :param master_secret_name: the name of the master secret stored in the wallet + :return: Claim request json. + { + "blinded_ms" : , + "schema_seq_no" : , + "issuer_did" : + } + """ + + logger = logging.getLogger(__name__) + logger.debug("prover_create_and_store_claim_req: >>> wallet_handle: %r, prover_did: %r, claim_offer_json: %r," + " claim_def_json: %r, master_secret_name: %r", + wallet_handle, + prover_did, + claim_offer_json, + claim_def_json, + master_secret_name) + + if not hasattr(prover_create_and_store_claim_req, "cb"): + logger.debug("prover_create_and_store_claim_req: Creating callback") + prover_create_and_store_claim_req.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_prover_did = c_char_p(prover_did.encode('utf-8')) + c_claim_offer_json = c_char_p(claim_offer_json.encode('utf-8')) + c_claim_def_json = c_char_p(claim_def_json.encode('utf-8')) + c_master_secret_name = c_char_p(master_secret_name.encode('utf-8')) + + claim_req_json = await do_call('indy_prover_create_and_store_claim_req', + c_wallet_handle, + c_prover_did, + c_claim_offer_json, + c_claim_def_json, + c_master_secret_name, + prover_create_and_store_claim_req.cb) + + res = claim_req_json.decode() + logger.debug("prover_create_and_store_claim_req: <<< res: %r", res) + return res + + +async def prover_store_claim(wallet_handle: int, + claims_json: str) -> None: + """ + Updates the claim by a master secret and stores in a secure wallet. + The claim contains the information about + schema_seq_no, issuer_did, revoc_reg_seq_no (see issuer_create_claim). + Seq_no is a sequence number of the corresponding transaction in the ledger. + The method loads a blinded secret for this key from the wallet, + updates the claim and stores it in a wallet. + + :param wallet_handle: wallet handler (created by open_wallet). + :param claims_json: claim json: + { + "claim": {attr1:[value, value_as_int]} + "signature": , + "schema_seq_no": string, + "revoc_reg_seq_no", string + "issuer_did", string + } + :return: None. + """ + + logger = logging.getLogger(__name__) + logger.debug("prover_store_claim: >>> wallet_handle: %r, claims_json: %r", + wallet_handle, + claims_json) + + if not hasattr(prover_store_claim, "cb"): + logger.debug("prover_store_claim: Creating callback") + prover_store_claim.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_wallet_handle = c_int32(wallet_handle) + c_claims_json = c_char_p(claims_json.encode('utf-8')) + + res = await do_call('indy_prover_store_claim', + c_wallet_handle, + c_claims_json, + prover_store_claim.cb) + + logger.debug("prover_store_claim: <<< res: %r", res) + return res + + +async def prover_get_claims(wallet_handle: int, + filter_json: str) -> str: + """ + Gets human readable claims according to the filter. + If filter is NULL, then all claims are returned. + Claims can be filtered by Issuer, claim_def and/or Schema. + + :param wallet_handle: wallet handler (created by open_wallet). + :param filter_json: filter for claims + { + "issuer_did": string, + "schema_seq_no": string + } + :return: claims json + [{ + "claim_uuid": , + "attrs": [{"attr_name" : "attr_value"}], + "schema_seq_no": string, + "issuer_did": string, + "revoc_reg_seq_no": string, + }] + """ + + logger = logging.getLogger(__name__) + logger.debug("prover_get_claims: >>> wallet_handle: %r, filter_json: %r", + wallet_handle, + filter_json) + + if not hasattr(prover_get_claims, "cb"): + logger.debug("prover_get_claims: Creating callback") + prover_get_claims.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_filter_json = c_char_p(filter_json.encode('utf-8')) + + claims_json = await do_call('indy_prover_get_claims', + c_wallet_handle, + c_filter_json, + prover_get_claims.cb) + + res = claims_json.decode() + logger.debug("prover_get_claims: <<< res: %r", res) + return res + + +async def prover_get_claims_for_proof_req(wallet_handle: int, + proof_request_json: str) -> str: + """ + Gets human readable claims matching the given proof request. + + :param wallet_handle: wallet handler (created by open_wallet). + :param proof_request_json: proof request json + { + "name": string, + "version": string, + "nonce": string, + "requested_attr1_uuid": , + "requested_attr2_uuid": , + "requested_attr3_uuid": , + "requested_predicate_1_uuid": , + "requested_predicate_2_uuid": , + } + :return: json with claims for the given pool request. + Claim consists of uuid, human-readable attributes (key-value map), schema_seq_no, issuer_did and revoc_reg_seq_no. + { + "requested_attr1_uuid": [claim1, claim2], + "requested_attr2_uuid": [], + "requested_attr3_uuid": [claim3], + "requested_predicate_1_uuid": [claim1, claim3], + "requested_predicate_2_uuid": [claim2], + }, where claim is + { + "claim_uuid": , + "attrs": [{"attr_name" : "attr_value"}], + "schema_seq_no": string, + "issuer_did": string, + "revoc_reg_seq_no": string, + } + """ + + logger = logging.getLogger(__name__) + logger.debug("prover_get_claims_for_proof_req: >>> wallet_handle: %r, proof_request_json: %r", + wallet_handle, + proof_request_json) + + if not hasattr(prover_get_claims, "cb"): + logger.debug("prover_get_claims_for_proof_req: Creating callback") + prover_get_claims_for_proof_req.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_proof_request_json = c_char_p(proof_request_json.encode('utf-8')) + + claims_json = await do_call('indy_prover_get_claims_for_proof_req', + c_wallet_handle, + c_proof_request_json, + prover_get_claims_for_proof_req.cb) + + res = claims_json.decode() + logger.debug("prover_get_claims_for_proof_req: <<< res: %r", res) + return res + + +async def prover_create_proof(wallet_handle: int, + proof_req_json: str, + requested_claims_json: str, + schemas_json: str, + master_secret_name: str, + claim_defs_json: str, + revoc_regs_json: str) -> str: + """ + Creates a proof according to the given proof request + Either a corresponding claim with optionally revealed attributes or self-attested attribute must be provided + for each requested attribute (see indy_prover_get_claims_for_pool_req). + A proof request may request multiple claims from different schemas and different issuers. + All required schemas, public keys and revocation registries must be provided. + The proof request also contains nonce. + The proof contains either proof or self-attested attribute value for each requested attribute. + + :param wallet_handle: wallet handler (created by open_wallet). + :param proof_req_json: proof request json as come from the verifier + { + "nonce": string, + "requested_attr1_uuid": , + "requested_attr2_uuid": , + "requested_attr3_uuid": , + "requested_predicate_1_uuid": , + "requested_predicate_2_uuid": , + } + :param requested_claims_json: either a claim or self-attested attribute for each requested attribute + { + "requested_attr1_uuid": [claim1_uuid_in_wallet, true ], + "requested_attr2_uuid": [self_attested_attribute], + "requested_attr3_uuid": [claim2_seq_no_in_wallet, false] + "requested_attr4_uuid": [claim2_seq_no_in_wallet, true] + "requested_predicate_1_uuid": [claim2_seq_no_in_wallet], + "requested_predicate_2_uuid": [claim3_seq_no_in_wallet], + } + :param schemas_json: all schema jsons participating in the proof request + { + "claim1_uuid_in_wallet": , + "claim2_uuid_in_wallet": , + "claim3_uuid_in_wallet": , + } + :param master_secret_name: the name of the master secret stored in the wallet + + :param claim_defs_json: all claim definition jsons participating in the proof request + { + "claim1_uuid_in_wallet": , + "claim2_uuid_in_wallet": , + "claim3_uuid_in_wallet": , + } + :param revoc_regs_json: all revocation registry jsons participating in the proof request + { + "claim1_uuid_in_wallet": , + "claim2_uuid_in_wallet": , + "claim3_uuid_in_wallet": , + } + :return: Proof json + For each requested attribute either a proof (with optionally revealed attribute value) or + self-attested attribute value is provided. + Each proof is associated with a claim and corresponding schema_seq_no, issuer_did and revoc_reg_seq_no. + There ais also aggregated proof part common for all claim proofs. + { + "requested": { + "requested_attr1_id": [claim_proof1_uuid, revealed_attr1, revealed_attr1_as_int], + "requested_attr2_id": [self_attested_attribute], + "requested_attr3_id": [claim_proof2_uuid] + "requested_attr4_id": [claim_proof2_uuid, revealed_attr4, revealed_attr4_as_int], + "requested_predicate_1_uuid": [claim_proof2_uuid], + "requested_predicate_2_uuid": [claim_proof3_uuid], + } + "claim_proofs": { + "claim_proof1_uuid": [, issuer_did, schema_seq_no, revoc_reg_seq_no], + "claim_proof2_uuid": [, issuer_did, schema_seq_no, revoc_reg_seq_no], + "claim_proof3_uuid": [, issuer_did, schema_seq_no, revoc_reg_seq_no] + }, + "aggregated_proof": + } + """ + + logger = logging.getLogger(__name__) + logger.debug("prover_create_proof: >>> wallet_handle: %r, proof_req_json: %r," + " requested_claims_json: %r, schemas_json: %r, master_secret_name: %r," + " claim_defs_json: %r, revoc_regs_json: %r", + wallet_handle, + proof_req_json, + requested_claims_json, + schemas_json, + master_secret_name, + claim_defs_json, + revoc_regs_json) + + if not hasattr(prover_create_proof, "cb"): + logger.debug("prover_create_proof: Creating callback") + prover_create_proof.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_proof_req_json = c_char_p(proof_req_json.encode('utf-8')) + c_requested_claims_json = c_char_p(requested_claims_json.encode('utf-8')) + c_schemas_json = c_char_p(schemas_json.encode('utf-8')) + c_master_secret_name = c_char_p(master_secret_name.encode('utf-8')) + c_claim_defs_json = c_char_p(claim_defs_json.encode('utf-8')) + c_revoc_regs_json = c_char_p(revoc_regs_json.encode('utf-8')) + + proof_json = await do_call('indy_prover_create_proof', + c_wallet_handle, + c_proof_req_json, + c_requested_claims_json, + c_schemas_json, + c_master_secret_name, + c_claim_defs_json, + c_revoc_regs_json, + prover_create_proof.cb) + + res = proof_json.decode() + logger.debug("prover_create_proof: <<< res: %r", res) + return res + + +async def verifier_verify_proof(proof_request_json: str, + proof_json: str, + schemas_json: str, + claim_defs_jsons: str, + revoc_regs_json: str) -> bool: + """ + Verifies a proof (of multiple claim). + All required schemas, public keys and revocation registries must be provided. + + :param wallet_handle: wallet handler (created by open_wallet). + :param proof_request_json: initial proof request as sent by the verifier + { + "nonce": string, + "requested_attr1_uuid": , + "requested_attr2_uuid": , + "requested_attr3_uuid": , + "requested_predicate_1_uuid": , + "requested_predicate_2_uuid": , + } + :param proof_json: proof json + For each requested attribute either a proof (with optionally revealed attribute value) or + self-attested attribute value is provided. + Each proof is associated with a claim and corresponding schema_seq_no, issuer_did and revoc_reg_seq_no. + There ais also aggregated proof part common for all claim proofs. + { + "requested": { + "requested_attr1_id": [claim_proof1_uuid, revealed_attr1, revealed_attr1_as_int], + "requested_attr2_id": [self_attested_attribute], + "requested_attr3_id": [claim_proof2_uuid] + "requested_attr4_id": [claim_proof2_uuid, revealed_attr4, revealed_attr4_as_int], + "requested_predicate_1_uuid": [claim_proof2_uuid], + "requested_predicate_2_uuid": [claim_proof3_uuid], + } + "claim_proofs": { + "claim_proof1_uuid": [, issuer_did, schema_seq_no, revoc_reg_seq_no], + "claim_proof2_uuid": [, issuer_did, schema_seq_no, revoc_reg_seq_no], + "claim_proof3_uuid": [, issuer_did, schema_seq_no, revoc_reg_seq_no] + }, + "aggregated_proof": + } + :param schemas_json: all schema jsons participating in the proof + { + "claim_proof1_uuid": , + "claim_proof2_uuid": , + "claim_proof3_uuid": + } + :param claim_defs_jsons: all claim definition jsons participating in the proof + { + "claim_proof1_uuid": , + "claim_proof2_uuid": , + "claim_proof3_uuid": + } + :param revoc_regs_json: all revocation registry jsons participating in the proof + { + "claim_proof1_uuid": , + "claim_proof2_uuid": , + "claim_proof3_uuid": + } + :return: valid: true - if signature is valid, false - otherwise + """ + + logger = logging.getLogger(__name__) + logger.debug("verifier_verify_proof: >>> proof_request_json: %r," + " proof_json: %r, schemas_json: %r, claim_defs_jsons: %r, revoc_regs_json: %r", + proof_request_json, + proof_json, + schemas_json, + claim_defs_jsons, + revoc_regs_json) + + if not hasattr(verifier_verify_proof, "cb"): + logger.debug("verifier_verify_proof: Creating callback") + verifier_verify_proof.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_bool)) + + c_proof_request_json = c_char_p(proof_request_json.encode('utf-8')) + c_proof_json = c_char_p(proof_json.encode('utf-8')) + c_schemas_json = c_char_p(schemas_json.encode('utf-8')) + c_claim_defs_jsons = c_char_p(claim_defs_jsons.encode('utf-8')) + c_revoc_regs_json = c_char_p(revoc_regs_json.encode('utf-8')) + + res = await do_call('indy_verifier_verify_proof', + c_proof_request_json, + c_proof_json, + c_schemas_json, + c_claim_defs_jsons, + c_revoc_regs_json, + verifier_verify_proof.cb) + + logger.debug("verifier_verify_proof: <<< res: %r", res) + return res diff --git a/wrappers/python/indy/error.py b/wrappers/python/indy/error.py new file mode 100644 index 0000000000..a9c17b76ce --- /dev/null +++ b/wrappers/python/indy/error.py @@ -0,0 +1,118 @@ +from enum import IntEnum + + +class ErrorCode(IntEnum): + Success = 0, + + # Common errors + + # Caller passed invalid value as param 1 (null, invalid json and etc..) + CommonInvalidParam1 = 100, + + # Caller passed invalid value as param 2 (null, invalid json and etc..) + CommonInvalidParam2 = 101, + + # Caller passed invalid value as param 3 (null, invalid json and etc..) + CommonInvalidParam3 = 102, + + # Caller passed invalid value as param 4 (null, invalid json and etc..) + CommonInvalidParam4 = 103, + + # Caller passed invalid value as param 5 (null, invalid json and etc..) + CommonInvalidParam5 = 104, + + # Caller passed invalid value as param 6 (null, invalid json and etc..) + CommonInvalidParam6 = 105, + + # Caller passed invalid value as param 7 (null, invalid json and etc..) + CommonInvalidParam7 = 106, + + # Caller passed invalid value as param 8 (null, invalid json and etc..) + CommonInvalidParam8 = 107, + + # Caller passed invalid value as param 9 (null, invalid json and etc..) + CommonInvalidParam9 = 108, + + # Caller passed invalid value as param 10 (null, invalid json and etc..) + CommonInvalidParam10 = 109, + + # Caller passed invalid value as param 11 (null, invalid json and etc..) + CommonInvalidParam11 = 110, + + # Caller passed invalid value as param 12 (null, invalid json and etc..) + CommonInvalidParam12 = 111, + + # Invalid library state was detected in runtime. It signals library bug + CommonInvalidState = 112, + + # Object (json, config, key, claim and etc...) passed by library caller has invalid structure + CommonInvalidStructure = 113, + + # IO Error + CommonIOError = 114, + + # Wallet errors + # Caller passed invalid wallet handle + WalletInvalidHandle = 200, + + # Unknown type of wallet was passed on create_wallet + WalletUnknownTypeError = 201, + + # Attempt to register already existing wallet type + WalletTypeAlreadyRegisteredError = 202, + + # Attempt to create wallet with name used for another exists wallet + WalletAlreadyExistsError = 203, + + # Requested entity id isn't present in wallet + WalletNotFoundError = 204, + + # Trying to use wallet with pool that has different name + WalletIncompatiblePoolError = 205, + + # Trying to open wallet that was opened already + WalletAlreadyOpenedError = 206, + + # Ledger errors + # Trying to open pool ledger that wasn't created before + PoolLedgerNotCreatedError = 300, + + # Caller passed invalid pool ledger handle + PoolLedgerInvalidPoolHandle = 301, + + # Pool ledger terminated + PoolLedgerTerminated = 302, + + # No concensus during ledger operation + LedgerNoConsensusError = 303, + + # Attempt to send unknown or incomplete transaction message + LedgerInvalidTransaction = 304, + + # Attempt to send transaction without the necessary privileges + LedgerSecurityError = 305, + + # Revocation registry is full and creation of new registry is necessary + AnoncredsRevocationRegistryFullError = 400, + + AnoncredsInvalidUserRevocIndex = 401, + + AnoncredsAccumulatorIsFull = 402, + + AnoncredsNotIssuedError = 403, + + # Attempt to generate master secret with dupplicated name + AnoncredsMasterSecretDuplicateNameError = 404, + + AnoncredsProofRejected = 405, + + # Signus errors + # Unknown format of DID entity keys + SignusUnknownCryptoError = 500 + + +class IndyError(Exception): + error_code: ErrorCode + + def __init__(self, error_code: ErrorCode): + self.error_code = error_code diff --git a/wrappers/python/indy/ledger.py b/wrappers/python/indy/ledger.py new file mode 100644 index 0000000000..7989342a86 --- /dev/null +++ b/wrappers/python/indy/ledger.py @@ -0,0 +1,502 @@ +from .libindy import do_call, create_cb + +from typing import Optional +from ctypes import * + +import logging + + +async def sign_and_submit_request(pool_handle: int, + wallet_handle: int, + submitter_did: str, + request_json: str) -> str: + """ + Signs and submits request message to validator pool. + + Adds submitter information to passed request json, signs it with submitter + sign key (see wallet_sign), and sends signed request message + to validator pool (see write_request). + + :param pool_handle: pool handle (created by open_pool_ledger). + :param wallet_handle: wallet handle (created by open_wallet). + :param submitter_did: Id of Identity stored in secured Wallet. + :param request_json: Request data json. + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("sign_and_submit_request: >>> pool_handle: %s, wallet_handle: %s, submitter_did: %s, request_json: %s", + pool_handle, + wallet_handle, + submitter_did, + request_json) + + if not hasattr(sign_and_submit_request, "cb"): + logger.debug("sign_and_submit_request: Creating callback") + sign_and_submit_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_pool_handle = c_int32(pool_handle) + c_wallet_handle = c_int32(wallet_handle) + c_submitter_did = c_char_p(submitter_did.encode('utf-8')) + c_request_json = c_char_p(request_json.encode('utf-8')) + + request_result = await do_call('indy_sign_and_submit_request', + c_pool_handle, + c_wallet_handle, + c_submitter_did, + c_request_json, + sign_and_submit_request.cb) + + res = request_result.decode() + logger.debug("sign_and_submit_request: <<< res: %s", res) + return res + + +async def submit_request(pool_handle: int, + request_json: str) -> str: + """ + Publishes request message to validator pool (no signing, unlike sign_and_submit_request). + The request is sent to the validator pool as is. It's assumed that it's already prepared. + + :param pool_handle: pool handle (created by open_pool_ledger). + :param request_json: Request data json. + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("submit_request: >>> pool_handle: %s, request_json: %s", + pool_handle, + request_json) + + if not hasattr(submit_request, "cb"): + logger.debug("submit_request: Creating callback") + submit_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_pool_handle = c_int32(pool_handle) + c_request_json = c_char_p(request_json.encode('utf-8')) + + request_result = await do_call('indy_submit_request', + c_pool_handle, + c_request_json, + submit_request.cb) + + res = request_result.decode() + logger.debug("submit_request: <<< res: %s", res) + return res + + +async def build_get_ddo_request(submitter_did: str, + target_did: str) -> str: + """ + Builds a request to get a DDO. + + :param submitter_did: Id of Identity stored in secured Wallet. + :param target_did: Id of Identity stored in secured Wallet. + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("build_get_ddo_request: >>> submitter_did: %s, target_did: %s", + submitter_did, + target_did) + + if not hasattr(build_get_ddo_request, "cb"): + logger.debug("build_get_ddo_request: Creating callback") + build_get_ddo_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_submitter_did = c_char_p(submitter_did.encode('utf-8')) + c_target_did = c_char_p(target_did.encode('utf-8')) + + request_json = await do_call('indy_build_get_ddo_request', + c_submitter_did, + c_target_did, + build_get_ddo_request.cb) + + res = request_json.decode() + logger.debug("build_get_ddo_request: <<< res: %s", res) + return res + + +async def build_nym_request(submitter_did: str, + target_did: str, + ver_key: Optional[str], + alias: Optional[str], + role: Optional[str]) -> str: + """ + Builds a NYM request. + + :param submitter_did: Id of Identity stored in secured Wallet. + :param target_did: Id of Identity stored in secured Wallet. + :param ver_key: verification key + :param alias: alias + :param role: Role of a user NYM record + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("build_nym_request: >>> submitter_did: %s, target_did: %s, ver_key: %s, alias: %s, role: %s", + submitter_did, + target_did, + ver_key, + alias, + role) + + if not hasattr(build_nym_request, "cb"): + logger.debug("build_nym_request: Creating callback") + build_nym_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_submitter_did = c_char_p(submitter_did.encode('utf-8')) + c_target_did = c_char_p(target_did.encode('utf-8')) + c_ver_key = c_char_p(ver_key.encode('utf-8')) if ver_key is not None else None + c_alias = c_char_p(alias.encode('utf-8')) if alias is not None else None + c_role = c_char_p(role.encode('utf-8')) if role is not None else None + + request_json = await do_call('indy_build_nym_request', + c_submitter_did, + c_target_did, + c_ver_key, + c_alias, + c_role, + build_nym_request.cb) + + res = request_json.decode() + logger.debug("build_nym_request: <<< res: %s", res) + return res + + +async def build_attrib_request(submitter_did: str, + target_did: str, + xhash: Optional[str], + raw: Optional[str], + enc: Optional[str]) -> str: + """ + Builds an ATTRIB request. + + :param submitter_did: Id of Identity stored in secured Wallet. + :param target_did: Id of Identity stored in secured Wallet. + :param hash: Hash of attribute data + :param raw: represented as json, where key is attribute name and value is it's value + :param enc: Encrypted attribute data + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("build_attrib_request: >>> submitter_did: %s, target_did: %s, hash: %s, raw: %s, enc: %s", + submitter_did, + target_did, + xhash, + raw, + enc) + + if not hasattr(build_attrib_request, "cb"): + logger.debug("build_attrib_request: Creating callback") + build_attrib_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_submitter_did = c_char_p(submitter_did.encode('utf-8')) + c_target_did = c_char_p(target_did.encode('utf-8')) + c_hash = c_char_p(xhash.encode('utf-8')) if xhash is not None else None + c_raw = c_char_p(raw.encode('utf-8')) if raw is not None else None + c_enc = c_char_p(enc.encode('utf-8')) if enc is not None else None + + request_json = await do_call('indy_build_attrib_request', + c_submitter_did, + c_target_did, + c_hash, + c_raw, + c_enc, + build_attrib_request.cb) + + res = request_json.decode() + logger.debug("build_attrib_request: <<< res: %s", res) + return res + + +async def build_get_attrib_request(submitter_did: str, + target_did: str, + data: str) -> str: + """ + Builds a GET_ATTRIB request. + + :param submitter_did: Id of Identity stored in secured Wallet. + :param target_did: Id of Identity stored in secured Wallet. + :param data: name (attribute name) + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("build_get_attrib_request: >>> submitter_did: %s, target_did: %s, data: %s", + submitter_did, + target_did, + data) + + if not hasattr(build_get_attrib_request, "cb"): + logger.debug("build_get_attrib_request: Creating callback") + build_get_attrib_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_submitter_did = c_char_p(submitter_did.encode('utf-8')) + c_target_did = c_char_p(target_did.encode('utf-8')) + c_data = c_char_p(data.encode('utf-8')) + + request_json = await do_call('indy_build_get_attrib_request', + c_submitter_did, + c_target_did, + c_data, + build_get_attrib_request.cb) + + res = request_json.decode() + logger.debug("build_get_attrib_request: <<< res: %s", res) + return res + + +async def build_get_nym_request(submitter_did: str, + target_did: str) -> str: + """ + Builds a GET_NYM request. + + :param submitter_did: Id of Identity stored in secured Wallet. + :param target_did: Id of Identity stored in secured Wallet. + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("build_get_nym_request: >>> submitter_did: %s, target_did: %s", + submitter_did, + target_did) + + if not hasattr(build_get_nym_request, "cb"): + logger.debug("build_get_nym_request: Creating callback") + build_get_nym_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_submitter_did = c_char_p(submitter_did.encode('utf-8')) + c_target_did = c_char_p(target_did.encode('utf-8')) + + request_json = await do_call('indy_build_get_nym_request', + c_submitter_did, + c_target_did, + build_get_nym_request.cb) + + res = request_json.decode() + logger.debug("build_get_nym_request: <<< res: %s", res) + return res + + +async def build_schema_request(submitter_did: str, + data: str) -> str: + """ + Builds a SCHEMA request. + + :param submitter_did: Id of Identity stored in secured Wallet. + :param data: name, version, type, attr_names (ip, port, keys) + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("build_schema_request: >>> submitter_did: %s, data: %s", + submitter_did, + data) + + if not hasattr(build_schema_request, "cb"): + logger.debug("build_schema_request: Creating callback") + build_schema_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_submitter_did = c_char_p(submitter_did.encode('utf-8')) + c_data = c_char_p(data.encode('utf-8')) + + request_json = await do_call('indy_build_schema_request', + c_submitter_did, + c_data, + build_schema_request.cb) + + res = request_json.decode() + logger.debug("build_schema_request: <<< res: %s", res) + return res + + +async def build_get_schema_request(submitter_did: str, + dest: str, + data: str) -> str: + """ + Builds a GET_SCHEMA request. + + :param submitter_did: Id of Identity stored in secured Wallet. + :param dest: Id of Identity stored in secured Wallet. + :param data: name, version + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("build_get_schema_request: >>> submitter_did: %s, dest: %s, data: %s", + submitter_did, + dest, + data) + + if not hasattr(build_get_schema_request, "cb"): + logger.debug("build_get_schema_request: Creating callback") + build_get_schema_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_submitter_did = c_char_p(submitter_did.encode('utf-8')) + c_dest = c_char_p(dest.encode('utf-8')) + c_data = c_char_p(data.encode('utf-8')) + + request_json = await do_call('indy_build_get_schema_request', + c_submitter_did, + c_dest, + c_data, + build_get_schema_request.cb) + + res = request_json.decode() + logger.debug("build_get_schema_request: <<< res: %s", res) + return res + + +async def build_claim_def_txn(submitter_did: str, + xref: int, + signature_type: str, + data: str) -> str: + """ + Builds an CLAIM_DEF request. + + :param submitter_did: Id of Identity stored in secured Wallet. + :param xref: Seq. number of schema + :param signature_type: signature type (only CL supported now) + :param data: components of a key in json: N, R, S, Z + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("build_get_schema_request: >>> submitter_did: %s, xref: %s, signature_type: %s, data: %s", + submitter_did, + xref, + signature_type, + data) + + if not hasattr(build_claim_def_txn, "cb"): + logger.debug("build_claim_def_txn: Creating callback") + build_claim_def_txn.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_submitter_did = c_char_p(submitter_did.encode('utf-8')) + c_xref = c_int32(xref) + c_signature_type = c_char_p(signature_type.encode('utf-8')) + c_data = c_char_p(data.encode('utf-8')) + + request_result = await do_call('indy_build_claim_def_txn', + c_submitter_did, + c_xref, + c_signature_type, + c_data, + build_claim_def_txn.cb) + + res = request_result.decode() + logger.debug("build_claim_def_txn: <<< res: %s", res) + return res + + +async def build_get_claim_def_txn(submitter_did: str, + xref: int, + signature_type: str, + origin: str) -> str: + """ + Builds a GET_CLAIM_DEF request. + + :param submitter_did: Id of Identity stored in secured Wallet. + :param xref: Seq. number of schema + :param signature_type: signature type (only CL supported now) + :param origin: issuer did + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("build_get_claim_def_txn: >>> submitter_did: %s, xref: %s, signature_type: %s, origin: %s", + submitter_did, + xref, + signature_type, + origin) + + if not hasattr(build_get_claim_def_txn, "cb"): + logger.debug("build_get_claim_def_txn: Creating callback") + build_get_claim_def_txn.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_submitter_did = c_char_p(submitter_did.encode('utf-8')) + c_xref = c_int32(xref) + c_signature_type = c_char_p(signature_type.encode('utf-8')) + c_origin = c_char_p(origin.encode('utf-8')) + + request_json = await do_call('indy_build_get_claim_def_txn', + c_submitter_did, + c_xref, + c_signature_type, + c_origin, + build_get_claim_def_txn.cb) + + res = request_json.decode() + logger.debug("build_get_claim_def_txn: <<< res: %s", res) + return res + + +async def build_node_request(submitter_did: str, + target_did: str, + data: str) -> str: + """ + Builds a NODE request. + + :param submitter_did: Id of Identity stored in secured Wallet. + :param target_did: Id of Identity stored in secured Wallet. + :param data: id of a target NYM record + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("build_node_request: >>> submitter_did: %s, target_did: %s, data: %s", + submitter_did, + target_did, + data) + + if not hasattr(build_node_request, "cb"): + logger.debug("build_node_request: Creating callback") + build_node_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_submitter_did = c_char_p(submitter_did.encode('utf-8')) + c_target_did = c_char_p(target_did.encode('utf-8')) + c_data = c_char_p(data.encode('utf-8')) + + request_json = await do_call('indy_build_node_request', + c_submitter_did, + c_target_did, + c_data, + build_node_request.cb) + + res = request_json.decode() + logger.debug("build_node_request: <<< res: %s", res) + return res + + +async def build_get_txn_request(submitter_did: str, + data: int) -> str: + """ + Builds a GET_TXN request. + + :param submitter_did: Id of Identity stored in secured Wallet. + :param data: seq_no of transaction in ledger + :return: Request result as json. + """ + + logger = logging.getLogger(__name__) + logger.debug("build_get_txn_request: >>> submitter_did: %s, data: %s", + submitter_did, + data) + + if not hasattr(build_get_txn_request, "cb"): + logger.debug("build_get_txn_request: Creating callback") + build_get_txn_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_submitter_did = c_char_p(submitter_did.encode('utf-8')) + c_data = c_int32(data) + + request_json = await do_call('indy_build_get_txn_request', + c_submitter_did, + c_data, + build_get_txn_request.cb) + + res = request_json.decode() + logger.debug("build_get_txn_request: <<< res: %s", res) + return res diff --git a/wrappers/python/indy/libindy.py b/wrappers/python/indy/libindy.py new file mode 100644 index 0000000000..4313269840 --- /dev/null +++ b/wrappers/python/indy/libindy.py @@ -0,0 +1,113 @@ +from .error import ErrorCode, IndyError + +from ctypes import * + +import asyncio +import sys +import itertools +import logging + +_futures = {} +_futures_counter = itertools.count() + + +def do_call(name: str, *args): + logger = logging.getLogger(__name__) + logger.debug("do_call: >>> name: %s, args: %s", name, args) + + event_loop = asyncio.get_event_loop() + future = event_loop.create_future() + command_handle = next(_futures_counter) + + _futures[command_handle] = (event_loop, future) + + err = getattr(_cdll(), name)(command_handle, + *args) + + logger.debug("do_call: Function %s returned err: %i", name, err) + + if err != ErrorCode.Success: + logger.warning("_do_call: Function %s returned error %i", name, err) + future.set_exception(IndyError(ErrorCode(err))) + + logger.debug("do_call: <<< %s", future) + return future + + +def create_cb(cb_type: CFUNCTYPE): + logger = logging.getLogger(__name__) + logger.debug("create_cb: >>> cb_type: %s", cb_type) + + res = cb_type(_indy_callback) + + logger.debug("create_cb: <<< res: %s", res) + return res + + +def _indy_callback(command_handle: int, err: int, *args): + logger = logging.getLogger(__name__) + logger.debug("_indy_callback: >>> command_handle: %i, err %i, args: %s", command_handle, err, args) + + (event_loop, future) = _futures[command_handle] + event_loop.call_soon_threadsafe(_indy_loop_callback, command_handle, err, *args) + + logger.debug("_indy_callback: <<<") + + +def _indy_loop_callback(command_handle: int, err, *args): + logger = logging.getLogger(__name__) + logger.debug("_indy_loop_callback: >>> command_handle: %i, err %i, args: %s", command_handle, err, args) + + (event_loop, future) = _futures.pop(command_handle) + + if err != ErrorCode.Success: + logger.warning("_indy_loop_callback: Function returned error %i", err) + future.set_exception(IndyError(ErrorCode(err))) + else: + if len(args) == 0: + res = None + elif len(args) == 1: + (res,) = args + else: + res = args + + logger.warning("_indy_loop_callback: Function returned %s", res) + future.set_result(res) + + logger.debug("_indy_loop_callback <<<") + + +def _cdll() -> CDLL: + if not hasattr(_cdll, "cdll"): + _cdll.cdll = _load_cdll() + + return _cdll.cdll + + +def _load_cdll() -> CDLL: + logger = logging.getLogger(__name__) + logger.debug("_load_cdll: >>>") + + libindy_prefix_mapping = {"darwin": "lib", "linux": "lib", "linux2": "lib", "win32": ""} + libindy_suffix_mapping = {"darwin": ".dylib", "linux": ".so", "linux2": ".so", "win32": ".dll"} + + os_name = sys.platform + logger.debug("_load_cdll: Detected OS name: %s", os_name) + + try: + libindy_prefix = libindy_prefix_mapping[os_name] + libindy_suffix = libindy_suffix_mapping[os_name] + except KeyError: + logger.error("_load_cdll: OS isn't supported: %s", os_name) + raise OSError("OS isn't supported: %s", os_name) + + libindy_name = "{0}indy{1}".format(libindy_prefix, libindy_suffix) + logger.debug("_load_cdll: Resolved libindy name is: %s", libindy_name) + + try: + res = CDLL(libindy_name) + logger.debug("_load_cdll: <<< res: %s", res) + return res + except OSError as e: + logger.error("_load_cdll: Can't load libindy: %s", e) + raise e diff --git a/wrappers/python/indy/pool.py b/wrappers/python/indy/pool.py new file mode 100644 index 0000000000..c48645ec8a --- /dev/null +++ b/wrappers/python/indy/pool.py @@ -0,0 +1,163 @@ +from .libindy import do_call, create_cb + +from typing import Optional +from ctypes import * + +import logging + + +async def create_pool_ledger_config(config_name: str, + config: Optional[str]) -> None: + """ + Creates a new local pool ledger configuration that can be used later to connect pool nodes. + + :param config_name: Name of the pool ledger configuration. + :param config: (optional) Pool configuration json. if NULL, then default config will be used. Example: + { + "genesis_txn": string (optional), A path to genesis transaction file. If NULL, then a default one will be used. + If file doesn't exists default one will be created. + } + :return: Error code + """ + + logger = logging.getLogger(__name__) + logger.debug("create_pool_ledger_config: >>> config_name: %s, config: %s", + config_name, + config) + + if not hasattr(create_pool_ledger_config, "cb"): + logger.debug("create_pool_ledger_config: Creating callback") + create_pool_ledger_config.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_config_name = c_char_p(config_name.encode('utf-8')) + c_config = c_char_p(config.encode('utf-8')) if config is not None else None + + res = await do_call('indy_create_pool_ledger_config', + c_config_name, + c_config, + create_pool_ledger_config.cb) + + logger.debug("create_pool_ledger_config: <<< res: %s", res) + return res + + +async def open_pool_ledger(config_name: str, + config: Optional[str]) -> int: + """ + Opens pool ledger and performs connecting to pool nodes. + + Pool ledger configuration with corresponded name must be previously created + with indy_create_pool_ledger_config method. + It is impossible to open pool with the same name more than once. + + :param config_name: Name of the pool ledger configuration. + :param config: (optional) Runtime pool configuration json. + if NULL, then default config will be used. Example: + { + "refreshOnOpen": bool (optional), Forces pool ledger to be refreshed immediately after opening. + Defaults to true. + "autoRefreshTime": int (optional), After this time in minutes pool ledger will be automatically refreshed. + Use 0 to disable automatic refresh. Defaults to 24*60. + "networkTimeout": int (optional), Network timeout for communication with nodes in milliseconds. + Defaults to 20000. + } + :return: Handle to opened pool to use in methods that require pool connection. + """ + + logger = logging.getLogger(__name__) + logger.debug("open_pool_ledger: >>> config_name: %s, config: %s", + config_name, + config) + + if not hasattr(open_pool_ledger, "cb"): + logger.debug("open_pool_ledger: Creating callback") + open_pool_ledger.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_int32)) + + c_config_name = c_char_p(config_name.encode('utf-8')) + c_config = c_char_p(config.encode('utf-8')) if config is not None else None + + res = await do_call('indy_open_pool_ledger', + c_config_name, + c_config, + open_pool_ledger.cb) + + logger.debug("open_pool_ledger: <<< res: %s", res) + return res + + +async def refresh_pool_ledger(handle: int) -> None: + """ + Refreshes a local copy of a pool ledger and updates pool nodes connections. + + :param handle: pool handle returned by indy_open_pool_ledger + :return: Error code + """ + + logger = logging.getLogger(__name__) + logger.debug("refresh_pool_ledger: >>> config_name: %s", + handle) + + if not hasattr(refresh_pool_ledger, "cb"): + logger.debug("refresh_pool_ledger: Creating callback") + refresh_pool_ledger.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_handle = c_int32(handle) + + res = await do_call('indy_refresh_pool_ledger', + c_handle, + refresh_pool_ledger.cb) + + logger.debug("refresh_pool_ledger: <<< res: %s", res) + return res + + +async def close_pool_ledger(handle: int) -> None: + """ + Closes opened pool ledger, opened nodes connections and frees allocated resources. + + :param handle: pool handle returned by indy_open_pool_ledger. + :return: Error code + """ + + logger = logging.getLogger(__name__) + logger.debug("close_pool_ledger: >>> config_name: %s", + handle) + + if not hasattr(close_pool_ledger, "cb"): + logger.debug("close_pool_ledger: Creating callback") + close_pool_ledger.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_handle = c_int32(handle) + + res = await do_call('indy_close_pool_ledger', + c_handle, + close_pool_ledger.cb) + + logger.debug("close_pool_ledger: <<< res: %s", res) + return res + + +async def delete_pool_ledger_config(config_name: str) -> None: + """ + Deletes created pool ledger configuration. + + :param config_name: Name of the pool ledger configuration to delete. + :return: Error code + """ + + logger = logging.getLogger(__name__) + logger.debug("delete_pool_ledger_config: >>> config_name: %s", + config_name) + + if not hasattr(delete_pool_ledger_config, "cb"): + logger.debug("delete_pool_ledger_config: Creating callback") + delete_pool_ledger_config.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_config_name = c_char_p(config_name.encode('utf-8')) + + res = await do_call('indy_delete_pool_ledger_config', + c_config_name, + delete_pool_ledger_config.cb) + + logger.debug("delete_pool_ledger_config: <<< res: %s", res) + return res diff --git a/wrappers/python/indy/signus.py b/wrappers/python/indy/signus.py new file mode 100644 index 0000000000..c711531f78 --- /dev/null +++ b/wrappers/python/indy/signus.py @@ -0,0 +1,318 @@ +from .libindy import do_call, create_cb + +from ctypes import * + +import logging + + +async def create_and_store_my_did(wallet_handle: int, + did_json: str) -> (str, str, str): + """ + Creates keys (signing and encryption keys) for a new + DID (owned by the caller of the library). + Identity's DID must be either explicitly provided, or taken as the first 16 bit of verkey. + Saves the Identity DID with keys in a secured Wallet, so that it can be used to sign + and encrypt transactions. + + :param wallet_handle: wallet handler (created by open_wallet). + :param did_json: Identity information as json. Example: + { + "did": string, (optional; + if not provided and cid param is false then the first 16 bit of the verkey will be used as a new DID; + if not provided and cid is true then the full verkey will be used as a new DID; + if provided, then keys will be replaced - key rotation use case) + "seed": string, (optional; if not provide then a random one will be created) + "crypto_type": string, (optional; if not set then ed25519 curve is used; + currently only 'ed25519' value is supported for this field) + "cid": bool, (optional; if not set then false is used;) + } + :return: DID, verkey (for verification of signature) and public_key (for decryption) + """ + + logger = logging.getLogger(__name__) + logger.debug("create_and_store_my_did: >>> wallet_handle: %s, did_json: %s", + wallet_handle, + did_json) + + if not hasattr(create_and_store_my_did, "cb"): + logger.debug("create_wallet: Creating callback") + create_and_store_my_did.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p, c_char_p, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_did_json = c_char_p(did_json.encode('utf-8')) + + did, verkey, pk = await do_call('indy_create_and_store_my_did', + c_wallet_handle, + c_did_json, + create_and_store_my_did.cb) + + res = (did.decode(), verkey.decode(), pk.decode()) + + logger.debug("create_and_store_my_did: <<< res: %s", res) + return res + + +async def replace_keys(wallet_handle: int, + did: str, + identity_json: str) -> (str, str): + """ + Generated new keys (signing and encryption keys) for an existing + DID (owned by the caller of the library). + + :param wallet_handle: wallet handler (created by open_wallet). + :param did: signing DID + :param identity_json: Identity information as json. Example: + { + "seed": string, (optional; if not provide then a random one will be created) + "crypto_type": string, (optional; if not set then ed25519 curve is used; + currently only 'ed25519' value is supported for this field) + } + :return: verkey (for verification of signature) and public_key (for decryption) + """ + + logger = logging.getLogger(__name__) + logger.debug("replace_keys: >>> wallet_handle: %s, did: %s, identity_json: %s", + wallet_handle, + did, + identity_json) + + if not hasattr(replace_keys, "cb"): + logger.debug("replace_keys: Creating callback") + replace_keys.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_did = c_char_p(did.encode('utf-8')) + c_identity_json = c_char_p(identity_json.encode('utf-8')) + + verkey, pk = await do_call('indy_replace_keys', + c_wallet_handle, + c_did, + c_identity_json, + replace_keys.cb) + + res = (verkey.decode(), pk.decode()) + + logger.debug("replace_keys: <<< res: %s", res) + return res + + +async def store_their_did(wallet_handle: int, + identity_json: str) -> None: + """ + Saves their DID for a pairwise connection in a secured Wallet, + so that it can be used to verify transaction. + + :param wallet_handle: wallet handler (created by open_wallet). + :param identity_json: Identity information as json. Example: + { + "did": string, (required) + "verkey": string (optional, if only pk is provided), + "crypto_type": string, (optional; if not set then ed25519 curve is used; + currently only 'ed25519' value is supported for this field) + } + :return: None + """ + + logger = logging.getLogger(__name__) + logger.debug("store_their_did: >>> wallet_handle: %s, identity_json: %s", + wallet_handle, + identity_json) + + if not hasattr(store_their_did, "cb"): + logger.debug("store_their_did: Creating callback") + store_their_did.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_wallet_handle = c_int32(wallet_handle) + c_identity_json = c_char_p(identity_json.encode('utf-8')) + + res = await do_call('indy_store_their_did', + c_wallet_handle, + c_identity_json, + store_their_did.cb) + + logger.debug("store_their_did: <<< res: %s", res) + return res + + +async def sign(wallet_handle: int, + did: str, + msg: str) -> str: + """ + Signs a message by a signing key associated with my DID. The DID with a signing key + must be already created and stored in a secured wallet (see create_and_store_my_identity) + + :param wallet_handle: wallet handler (created by open_wallet). + :param did: signing DID + :param msg: a message to be signed + :return: a signature string + """ + + logger = logging.getLogger(__name__) + logger.debug("sign: >>> wallet_handle: %s, did: %s, msg: %s", + wallet_handle, + did, + msg) + + if not hasattr(sign, "cb"): + logger.debug("sign: Creating callback") + sign.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_did = c_char_p(did.encode('utf-8')) + c_msg = c_char_p(msg.encode('utf-8')) + + res = await do_call('indy_sign', + c_wallet_handle, + c_did, + c_msg, + sign.cb) + + res = res.decode() + + logger.debug("sign: <<< res: %s", res) + return res + + +async def verify_signature(wallet_handle: int, + pool_handle: int, + did: str, + signed_msg: str) -> bool: + """ + Verify a signature created by a key associated with a DID. + If a secure wallet doesn't contain a verkey associated with the given DID, + then verkey is read from the Ledger. + Otherwise either an existing verkey from wallet is used (see wallet_store_their_identity), + or it checks the Ledger (according to freshness settings set during initialization) + whether verkey is still the same and updates verkey for the DID if needed. + + :param wallet_handle: wallet handler (created by open_wallet). + :param pool_handle: pool handle. + :param did: DID that signed the message + :param signed_msg: message + :return: valid: true - if signature is valid, false - otherwise + """ + + logger = logging.getLogger(__name__) + logger.debug("verify_signature: >>> wallet_handle: %s, pool_handle: %s, did: %s, signed_msg: %s", + wallet_handle, + pool_handle, + did, + signed_msg) + + if not hasattr(verify_signature, "cb"): + logger.debug("verify_signature: Creating callback") + verify_signature.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_bool)) + + c_wallet_handle = c_int32(wallet_handle) + c_pool_handle = c_int32(pool_handle) + c_did = c_char_p(did.encode('utf-8')) + c_signed_msg = c_char_p(signed_msg.encode('utf-8')) + + res = await do_call('indy_verify_signature', + c_wallet_handle, + c_pool_handle, + c_did, + c_signed_msg, + verify_signature.cb) + + logger.debug("verify_signature: <<< res: %s", res) + return res + + +async def encrypt(wallet_handle: int, + pool_handle: int, + my_did: str, + did: str, + msg: str) -> (str, str): + """ + Encrypts a message by a public key associated with a DID. + If a secure wallet doesn't contain a public key associated with the given DID, + then the public key is read from the Ledger. + Otherwise either an existing public key from wallet is used (see wallet_store_their_identity), + or it checks the Ledger (according to freshness settings set during initialization) + whether public key is still the same and updates public key for the DID if needed. + + :param wallet_handle: wallet handler (created by open_wallet). + :param pool_handle: pool handle. + :param my_did: encrypting DID + :param did: encrypting DID + :param msg: a message to be signed + :return: an encrypted message and nonce + """ + + logger = logging.getLogger(__name__) + logger.debug("encrypt: >>> wallet_handle: %s, pool_handle: %s, my_did: %s, did: %s, msg: %s", + wallet_handle, + pool_handle, + my_did, + did, + msg) + + if not hasattr(encrypt, "cb"): + logger.debug("encrypt: Creating callback") + encrypt.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_pool_handle = c_int32(pool_handle) + c_my_did = c_char_p(my_did.encode('utf-8')) + c_did = c_char_p(did.encode('utf-8')) + c_msg = c_char_p(msg.encode('utf-8')) + + res = await do_call('indy_encrypt', + c_wallet_handle, + c_pool_handle, + c_my_did, + c_did, + c_msg, + encrypt.cb) + + logger.debug("encrypt: <<< res: %s", res) + return res + + +async def decrypt(wallet_handle: int, + my_did: str, + did: str, + encrypted_msg: str, + nonce: str) -> str: + """ + Decrypts a message encrypted by a public key associated with my DID. + The DID with a secret key must be already created and + stored in a secured wallet (see wallet_create_and_store_my_identity) + + :param wallet_handle: wallet handler (created by open_wallet). + :param my_did: DID + :param did: DID that signed the message + :param encrypted_msg: encrypted message + :param nonce: nonce that encrypted message + :return: decrypted message + """ + + logger = logging.getLogger(__name__) + logger.debug("decrypt: >>> wallet_handle: %s, my_did: %s, did: %s, encrypted_msg: %s, nonce: %s", + wallet_handle, + my_did, + did, + encrypted_msg, + nonce) + + if not hasattr(decrypt, "cb"): + logger.debug("decrypt: Creating callback") + decrypt.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p)) + + c_wallet_handle = c_int32(wallet_handle) + c_my_did = c_char_p(my_did.encode('utf-8')) + c_did = c_char_p(did.encode('utf-8')) + c_encrypted_msg = c_char_p(encrypted_msg.encode('utf-8')) + c_nonce = c_char_p(nonce.encode('utf-8')) + + res = await do_call('indy_decrypt', + c_wallet_handle, + c_my_did, + c_did, + c_encrypted_msg, + c_nonce, + decrypt.cb) + + logger.debug("decrypt: <<< res: %s", res) + return res diff --git a/wrappers/python/indy/wallet.py b/wrappers/python/indy/wallet.py new file mode 100644 index 0000000000..28c19b8ba2 --- /dev/null +++ b/wrappers/python/indy/wallet.py @@ -0,0 +1,157 @@ +from .libindy import do_call, create_cb + +from typing import Optional +from ctypes import * + +import logging + + +async def create_wallet(pool_name: str, + name: str, + xtype: Optional[str], + config: Optional[str], + credentials: Optional[str]) -> None: + """ + Creates a new secure wallet with the given unique name. + + :param pool_name: Name of the pool that corresponds to this wallet. + :param name: Name of the wallet. + :param xtype: (optional) Type of the wallet. Defaults to 'default'. + Custom types can be registered with indy_register_wallet_type call. + :param config: (optional) Wallet configuration json. List of supported keys are defined by wallet type. + if NULL, then default config will be used. + :param credentials: (optional) Wallet credentials json. List of supported keys are defined by wallet type. + if NULL, then default config will be used. + :return: Error code + """ + + logger = logging.getLogger(__name__) + logger.debug("create_wallet: >>> pool_name: %s, name: %s, xtype: %s, config: %s, credentials: %s", + pool_name, + name, + xtype, + config, + credentials) + + if not hasattr(create_wallet, "cb"): + logger.debug("create_wallet: Creating callback") + create_wallet.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_pool_name = c_char_p(pool_name.encode('utf-8')) + c_name = c_char_p(name.encode('utf-8')) + c_xtype = c_char_p(xtype.encode('utf-8')) if xtype is not None else None + c_config = c_char_p(config.encode('utf-8')) if config is not None else None + c_credentials = c_char_p(credentials.encode('utf-8')) if credentials is not None else None + + await do_call('indy_create_wallet', + c_pool_name, + c_name, + c_xtype, + c_config, + c_credentials, + create_wallet.cb) + + logger.debug("create_wallet: <<<") + + +async def open_wallet(name: str, + runtime_config: Optional[str], + credentials: Optional[str]) -> int: + """ + Opens the wallet with specific name. + Wallet with corresponded name must be previously created with indy_create_wallet method. + It is impossible to open wallet with the same name more than once. + + :param name: Name of the wallet. + :param runtime_config: (optional) Runtime wallet configuration json. + if NULL, then default runtime_config will be used. Example: + { + "freshnessTime": string (optional), Amount of minutes to consider wallet value as fresh. Defaults to 24*60. + ... List of additional supported keys are defined by wallet type. + } + :param credentials: (optional) Wallet credentials json. List of supported keys are defined by wallet type. + if NULL, then default credentials will be used. + :return: Handle to opened wallet to use in methods that require wallet access. + """ + + logger = logging.getLogger(__name__) + logger.debug("open_wallet: >>> name: %s, runtime_config: %s, credentials: %s", + name, + runtime_config, + credentials) + + if not hasattr(open_wallet, "cb"): + logger.debug("open_wallet: Creating callback") + open_wallet.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_int32)) + + c_name = c_char_p(name.encode('utf-8')) + c_runtime_config = c_char_p(runtime_config.encode('utf-8')) if runtime_config is not None else None + c_credentials = c_char_p(credentials.encode('utf-8')) if credentials is not None else None + + res = await do_call('indy_open_wallet', + c_name, + c_runtime_config, + c_credentials, + open_wallet.cb) + + logger.debug("open_wallet: <<< res: %s", res) + return res + + +async def close_wallet(handle: int) -> None: + """ + Closes opened wallet and frees allocated resources. + + :param handle: wallet handle returned by indy_open_wallet. + :return: Error code + """ + + logger = logging.getLogger(__name__) + logger.debug("close_wallet: >>> handle: %i", handle) + + if not hasattr(close_wallet, "cb"): + logger.debug("close_wallet: Creating callback") + close_wallet.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_handle = c_int32(handle) + + await do_call('indy_close_wallet', + c_handle, + close_wallet.cb) + + logger.debug("close_wallet: <<<") + + +# pub extern fn indy_delete_wallet(command_handle: i32, +# name: *const c_char, +# credentials: *const c_char, +# cb: Option) -> ErrorCode { +async def delete_wallet(name: str, + credentials: Optional[str]) -> None: + """ + Deletes created wallet. + + :param name: Name of the wallet to delete. + :param credentials: (optional) Wallet credentials json. List of supported keys are defined by wallet type. + if NULL, then default credentials will be used. + :return: + """ + + logger = logging.getLogger(__name__) + logger.debug("delete_wallet: >>> name: %s, credentials: %s", + name, + credentials) + + if not hasattr(delete_wallet, "cb"): + logger.debug("delete_wallet: Creating callback") + delete_wallet.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32)) + + c_name = c_char_p(name.encode('utf-8')) + c_credentials = c_char_p(credentials.encode('utf-8')) if credentials is not None else None + + await do_call('indy_delete_wallet', + c_name, + c_credentials, + delete_wallet.cb) + + logger.debug("delete_wallet: <<<") diff --git a/wrappers/python/setup.py b/wrappers/python/setup.py new file mode 100644 index 0000000000..6cb3df422f --- /dev/null +++ b/wrappers/python/setup.py @@ -0,0 +1,14 @@ +from distutils.core import setup + +setup( + name='indy-sdk', + version='0.0.1', + packages=['indy'], + url='https://github.com/hyperledger/indy-sdk', + license='MIT/Apache-2.0', + author='Vyacheslav Gudkov', + author_email='vyacheslav.gudkov@dsr-company.com', + description='This is the official SDK for Hyperledger Indy (https://www.hyperledger.org/projects), which provides a distributed-ledger-based foundation for self-sovereign identity (https://sovrin.org). The major artifact of the SDK is a c-callable library.', + install_requires=['pytest', 'pytest-asyncio', 'base58'], + tests_require=['pytest', 'pytest-asyncio', 'base58'] +) diff --git a/wrappers/python/sovrin/__init__.py b/wrappers/python/sovrin/__init__.py deleted file mode 100644 index a4c3e3c060..0000000000 --- a/wrappers/python/sovrin/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from sovrin.error import SovrinError - -from sovrin.anoncreds import Anoncreds -from sovrin.ledger import Ledger -from sovrin.pool import Pool -from sovrin.signus import Signus -from sovrin.wallet import Wallet diff --git a/wrappers/python/sovrin/anoncreds.py b/wrappers/python/sovrin/anoncreds.py deleted file mode 100644 index bbcdcb51bd..0000000000 --- a/wrappers/python/sovrin/anoncreds.py +++ /dev/null @@ -1,90 +0,0 @@ -from typing import Callable -from . import SovrinError - -class Anoncreds(object): - - """TODO: document it""" - - async def issuer_create_and_store_claim_def(wallet_handle: int, - schema_json: str, - signature_type: str, - create_non_revoc: bool, - claim_def_json: str, - claim_def_uuid: str) -> None: - pass - - async def issuer_create_and_store_revoc_reg(wallet_handle: int, - claim_def_seq_no: int, - max_claim_num: int, - revoc_reg_json: str, - revoc_reg_uuid: str) -> None: - pass - - async def issuer_create_claim(wallet_handle: int, - claim_req_json: str, - claim_json: str, - revoc_reg_seq_no: int, - user_revoc_index: int, - revoc_reg_update_json: str, - xclaim_json: str) -> None: - pass - - async def issuer_revoke_claim(wallet_handle: int, - claim_def_seq_no: int, - revoc_reg_seq_no: int, - user_revoc_index: int, - revoc_reg_update_json: str) -> None: - pass - - async def prover_store_claim_offer(wallet_handle: int, - claim_offer_json: str) -> None: - pass - - async def prover_get_claim_offers(wallet_handle: int, - filter_json: str, - claim_offers_json: str) -> None: - pass - - async def prover_create_master_secret(wallet_handle: int, - master_secret_name: str) -> None: - pass - - async def prover_create_and_store_claim_req(wallet_handle: int, - prover_did: str, - claim_offer_json: str, - claim_def_json: str, - master_secret_name: str, - claim_req_json: str) -> None: - pass - - async def prover_store_claim(wallet_handle: int, - claims_json: str) -> None: - pass - - async def prover_get_claims(wallet_handle: int, - filter_json: str, - claims_json: str) -> None: - pass - - async def prover_get_claims_for_proof_req(wallet_handle: int, - proof_request_json: str, - claims_json: str) -> None: - pass - - async def prover_create_proof(wallet_handle: int, - proof_req_json: str, - requested_claims_json: str, - schemas_json: str, - claim_defs_json: str, - revoc_regs_json: str, - proof_json: str) -> None: - pass - - async def verifier_verify_proof(wallet_handle: int, - proof_request_json: str, - proof_json: str, - schemas_json: str, - claim_defs_jsons: str, - revoc_regs_json: str, - valid: bool) -> None: - pass diff --git a/wrappers/python/sovrin/error.py b/wrappers/python/sovrin/error.py deleted file mode 100644 index 548b43bd11..0000000000 --- a/wrappers/python/sovrin/error.py +++ /dev/null @@ -1,12 +0,0 @@ -from enum import Enum - -class SovrinErrorCode(Enum): - Success = 0 - CommonInvalidParam1 = 100 - - -class SovrinError(Exception): - error_code: SovrinErrorCode - - def __init__(self, error_code: SovrinErrorCode): - self.error_code = error_code diff --git a/wrappers/python/sovrin/ledger.py b/wrappers/python/sovrin/ledger.py deleted file mode 100644 index 25692b5590..0000000000 --- a/wrappers/python/sovrin/ledger.py +++ /dev/null @@ -1,89 +0,0 @@ -from typing import Callable -from . import SovrinError - -class Ledger(object): - - """TODO: document it""" - - async def sign_and_submit_request(command_handle: int, - wallet_handle: int, - submitter_did: str, - request_json: str, - request_result_json: str) -> None: - pass - - async def submit_request(command_handle: int, - pool_handle: int, - request_json: str, - request_result_json: str) -> None: - pass - - async def build_get_ddo_request(command_handle: int, - submitter_did: str, - target_did: str, - request_json: str) -> None: - pass - - async def build_nym_request(command_handle: int, - submitter_did: str, - target_did: str, - verkey: str, - xref: str, - data: str, - role: str, - request_json: str) -> None: - pass - - async def build_attrib_request(command_handle: int, - submitter_did: str, - target_did: str, - hash: str, - raw: str, - enc: str, - request_json: str) -> None: - pass - - async def build_get_attrib_request(command_handle: int, - submitter_did: str, - target_did: str, - data: str, - request_json: str) -> None: - pass - - async def build_get_nym_request(command_handle: int, - submitter_did: str, - target_did: str, - request_json: str) -> None: - pass - - async def build_schema_request(command_handle: int, - submitter_did: str, - data: str, - request_json: str) -> None: - pass - - async def build_get_schema_request(command_handle: int, - submitter_did: str, - data: str, - request_json: str) -> None: - pass - - async def build_claim_def_txn(command_handle: int, - submitter_did: str, - xref: str, - data: str, - request_result_json: str) -> None: - pass - - async def build_get_claim_def_txn(command_handle: int, - submitter_did: str, - xref: str, - request_json: str) -> None: - pass - - async def build_node_request(command_handle: int, - submitter_did: str, - target_did: str, - data: str, - request_json: str) -> None: - pass diff --git a/wrappers/python/sovrin/pool.py b/wrappers/python/sovrin/pool.py deleted file mode 100644 index e35f41e593..0000000000 --- a/wrappers/python/sovrin/pool.py +++ /dev/null @@ -1,29 +0,0 @@ -from typing import Callable -from . import SovrinError - -class Pool(object): - - """TODO: document it""" - - async def create_pool_ledger_config(command_handle: int, - config_name: str, - config: str) -> None: - pass - - async def open_pool_ledger(command_handle: int, - config_name: str, - config: str, - pool_handle: int) -> None: - pass - - async def refresh_pool_ledger(command_handle: int, - handle: int) -> None: - pass - - async def close_pool_ledger(command_handle: int, - handle: int) -> None: - pass - - async def delete_pool_ledger_config(command_handle: int, - config_name: str) -> None: - pass diff --git a/wrappers/python/sovrin/signus.py b/wrappers/python/sovrin/signus.py deleted file mode 100644 index aa55156eb4..0000000000 --- a/wrappers/python/sovrin/signus.py +++ /dev/null @@ -1,55 +0,0 @@ -from typing import Callable -from . import SovrinError - -class Signus(object): - - """TODO: document it""" - async def create_and_store_my_did(command_handle: int, - wallet_handle: int, - did_json: str, - did: str, - verkey: str, - pk: str) -> None: - pass - - async def replace_keys(command_handle: int, - wallet_handle: int, - did: str, - identity_json: str, - verkey: str, - pk: str) -> None: - pass - - async def store_their_did(command_handle: int, - wallet_handle: int, - identity_json: str) -> None: - pass - - async def sign(command_handle: int, - wallet_handle: int, - did: str, - msg: str, - signature: str) -> None: - pass - - async def verify_signature(command_handle: int, - wallet_handle: int, - did: str, - msg: str, - signature: str, - valid: bool) -> None: - pass - - async def encrypt(command_handle: int, - wallet_handle: int, - did: str, - msg: str, - encrypted_msg: str) -> None: - pass - - async def decrypt(command_handle: int, - wallet_handle: int, - did: str, - encrypted_msg: str, - decrypted_msg: str) -> None: - pass diff --git a/wrappers/python/sovrin/wallet.py b/wrappers/python/sovrin/wallet.py deleted file mode 100644 index b7786b198b..0000000000 --- a/wrappers/python/sovrin/wallet.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Callable -from . import SovrinError - -class Wallet(object): - - """TODO: document it""" - - async def create_wallet(pool_name: str, - name: str, - xtype: str, - config: str, - credentials: str) -> None: - pass - - async def open_wallet(pool_handle: int, - name: str, - config: str) -> int: - return -1 - - async def close_wallet(wallet_handle: int) -> None: - pass - - async def delete_wallet(name:str) -> None: - pass - - async def set_seq_no_for_value(wallet_key: str, seq_num: str) -> None: - pass diff --git a/wrappers/python/tests/__init__.py b/wrappers/python/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/wrappers/python/tests/agent/__init__.py b/wrappers/python/tests/agent/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/wrappers/python/tests/agent/conftest.py b/wrappers/python/tests/agent/conftest.py new file mode 100644 index 0000000000..8c3fcb88ce --- /dev/null +++ b/wrappers/python/tests/agent/conftest.py @@ -0,0 +1,84 @@ +import json + +import pytest + +from indy import signus, agent + + +@pytest.fixture +async def endpoint(): + return "127.0.0.1:9701" + + +@pytest.fixture +async def wallet_with_identity(wallet_handle, endpoint): + did, verkey, pk = await signus.create_and_store_my_did(wallet_handle, "{}") + await signus.store_their_did(wallet_handle, + json.dumps({ + "did": did, + "verkey": verkey, + "pk": pk, + "endpoint": endpoint + })) + + return wallet_handle, did + + +@pytest.fixture +async def wallet_with_identities(wallet_with_identity, endpoint): + wallet_handle, did1 = wallet_with_identity + + did2, verkey2, pk2 = await signus.create_and_store_my_did(wallet_handle, "{}") + await signus.store_their_did(wallet_handle, + json.dumps({ + "did": did2, + "verkey": verkey2, + "pk": pk2, + "endpoint": endpoint + })) + + return wallet_handle, did1, did2 + + +@pytest.fixture +async def listener_handle(endpoint): + listener_handle = await agent.agent_listen(endpoint) + assert type(listener_handle) is int + yield listener_handle + await agent.agent_close_listener(listener_handle) + + +@pytest.fixture +async def listener_with_identity(listener_handle, wallet_with_identity): + wallet_handle, did = wallet_with_identity + await agent.agent_add_identity(listener_handle, -1, wallet_handle, did) + return listener_handle, wallet_handle, did + + +@pytest.fixture +async def listener_with_identities(listener_handle, wallet_with_identities): + wallet_handle, did1, did2 = wallet_with_identities + await agent.agent_add_identity(listener_handle, -1, wallet_handle, did1) + await agent.agent_add_identity(listener_handle, -1, wallet_handle, did2) + return listener_handle, wallet_handle, did1, did2 + + +@pytest.fixture +async def connection(listener_with_identity): + listener_handle, wallet_handle, did = listener_with_identity + + connection_handle = await agent.agent_connect(0, wallet_handle, did, did) + assert connection_handle is not None + + event = await agent.agent_wait_for_event([listener_handle]) # type: agent.ConnectionEvent + + assert type(event) is agent.ConnectionEvent + assert event.handle == listener_handle + assert event.sender_did == did + assert event.receiver_did == did + assert event.connection_handle is not None + + yield listener_handle, event.connection_handle, connection_handle, wallet_handle, did + + await agent.agent_close_connection(event.connection_handle) + await agent.agent_close_connection(connection_handle) diff --git a/wrappers/python/tests/agent/test_agent_add_idenitity.py b/wrappers/python/tests/agent/test_agent_add_idenitity.py new file mode 100644 index 0000000000..eebc3d0e5f --- /dev/null +++ b/wrappers/python/tests/agent/test_agent_add_idenitity.py @@ -0,0 +1,11 @@ +import pytest + + +@pytest.mark.asyncio +async def test_agent_add_identity_works(listener_with_identity): + assert listener_with_identity is not None + + +@pytest.mark.asyncio +async def test_agent_add_identity_works_for_multiply_keys(listener_with_identities): + assert listener_with_identities is not None diff --git a/wrappers/python/tests/agent/test_agent_close_connection.py b/wrappers/python/tests/agent/test_agent_close_connection.py new file mode 100644 index 0000000000..405e361c3e --- /dev/null +++ b/wrappers/python/tests/agent/test_agent_close_connection.py @@ -0,0 +1,45 @@ +import pytest + +from indy import agent, IndyError +from indy.error import ErrorCode + + +@pytest.mark.asyncio +async def test_agent_close_connection_works_for_outgoing(listener_with_identity): + listener_handle, wallet_handle, did = listener_with_identity + + connection_handle = await agent.agent_connect(0, wallet_handle, did, did) + assert connection_handle is not None + + await agent.agent_close_connection(connection_handle) + + try: + await agent.agent_send(connection_handle, "msg") + raise Exception("Failed") + except Exception as e: + assert type(IndyError(ErrorCode.CommonInvalidStructure)) == type(e) \ + and IndyError(ErrorCode.CommonInvalidStructure).args == e.args + + +@pytest.mark.asyncio +async def test_agent_close_connection_works_for_incoming(listener_with_identity): + listener_handle, wallet_handle, did = listener_with_identity + + connection_handle = await agent.agent_connect(0, wallet_handle, did, did) + assert connection_handle is not None + + event = await agent.agent_wait_for_event([listener_handle]) # type: agent.ConnectionEvent + + assert type(event) is agent.ConnectionEvent + assert event.connection_handle is not None + + await agent.agent_close_connection(event.connection_handle) + + try: + await agent.agent_send(event.connection_handle, "msg") + raise Exception("Failed") + except Exception as e: + assert type(IndyError(ErrorCode.CommonInvalidStructure)) == type(e) \ + and IndyError(ErrorCode.CommonInvalidStructure).args == e.args + finally: + await agent.agent_close_connection(connection_handle) diff --git a/wrappers/python/tests/agent/test_agent_close_listener.py b/wrappers/python/tests/agent/test_agent_close_listener.py new file mode 100644 index 0000000000..9e37abd957 --- /dev/null +++ b/wrappers/python/tests/agent/test_agent_close_listener.py @@ -0,0 +1,32 @@ +import pytest + +from indy import agent, IndyError +from indy.error import ErrorCode + + +@pytest.mark.asyncio +async def test_agent_close_listener_works_for_outgoing(endpoint, wallet_with_identity): + listener_handle = await agent.agent_listen(endpoint) + assert type(listener_handle) is int + + wallet_handle, did = wallet_with_identity + await agent.agent_add_identity(listener_handle, -1, wallet_handle, did) + + connection_handle = await agent.agent_connect(0, wallet_handle, did, did) + assert connection_handle is not None + + event = await agent.agent_wait_for_event([listener_handle]) # type: agent.ConnectionEvent + + assert type(event) is agent.ConnectionEvent + assert event.connection_handle is not None + + await agent.agent_close_listener(listener_handle) + + try: + await agent.agent_send(event.connection_handle, "msg") + raise Exception("Failed") + except Exception as e: + assert type(IndyError(ErrorCode.CommonInvalidStructure)) == type(e) \ + and IndyError(ErrorCode.CommonInvalidStructure).args == e.args + finally: + await agent.agent_close_connection(connection_handle) diff --git a/wrappers/python/tests/agent/test_agent_connect.py b/wrappers/python/tests/agent/test_agent_connect.py new file mode 100644 index 0000000000..8462a845a5 --- /dev/null +++ b/wrappers/python/tests/agent/test_agent_connect.py @@ -0,0 +1,69 @@ +import json + +import pytest + +from indy import signus, ledger, agent +from tests.utils import wallet + + +@pytest.mark.asyncio +async def test_agent_connect_works_for_remote_data(pool_handle, + trustee1_seed): + endpoint = "127.0.0.1:9705" + + listener_wallet_handle = await wallet.create_and_open_wallet(wallet_name="listener_wallet") + trustee_wallet_handle = await wallet.create_and_open_wallet(wallet_name="trustee_wallet") + + listener_did, listener_verkey, listener_pk = await signus.create_and_store_my_did(listener_wallet_handle, "{}") + + trustee_did, trustee_verkey, trustee_pk = await signus.create_and_store_my_did( + trustee_wallet_handle, + json.dumps({ + "seed": trustee1_seed + })) + + nym_request = await ledger.build_nym_request(trustee_did, listener_did, listener_verkey, None, None) + await ledger.sign_and_submit_request(pool_handle, listener_wallet_handle, trustee_did, nym_request) + + attrib_request = await ledger.build_attrib_request( + listener_did, + listener_did, + None, + json.dumps({ + "endpoint": { + "ha": endpoint, + "verkey": listener_pk + } + }), + None) + await ledger.sign_and_submit_request(pool_handle, listener_wallet_handle, listener_did, attrib_request) + + listener_handle = await agent.agent_listen(endpoint) + await agent.agent_add_identity(listener_handle, pool_handle, listener_wallet_handle, listener_did) + + sender_did = trustee_did + sender_wallet_handle = trustee_wallet_handle + connection_handle = await agent.agent_connect(pool_handle, + sender_wallet_handle, + sender_did, + listener_did) + assert connection_handle is not None + + connection_event = await agent.agent_wait_for_event([listener_handle]) # type: agent.ConnectionEvent + + assert type(connection_event) is agent.ConnectionEvent + assert connection_event.handle == listener_handle + assert connection_event.sender_did == sender_did + assert connection_event.receiver_did == listener_did + assert connection_event.connection_handle is not None + + await agent.agent_close_connection(connection_handle) + await agent.agent_close_connection(connection_event.handle) + await agent.agent_close_listener(listener_handle) + await wallet.close_wallet(listener_wallet_handle) + await wallet.close_wallet(trustee_wallet_handle) + + +@pytest.mark.asyncio +async def test_agent_connect_works_for_all_data_in_wallet_present(connection): + assert connection is not None diff --git a/wrappers/python/tests/agent/test_agent_listen.py b/wrappers/python/tests/agent/test_agent_listen.py new file mode 100644 index 0000000000..6412e45c8b --- /dev/null +++ b/wrappers/python/tests/agent/test_agent_listen.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.mark.asyncio +async def test_agent_listen_works(listener_handle): + assert listener_handle is not None diff --git a/wrappers/python/tests/agent/test_agent_remove_idenitity.py b/wrappers/python/tests/agent/test_agent_remove_idenitity.py new file mode 100644 index 0000000000..68d2228711 --- /dev/null +++ b/wrappers/python/tests/agent/test_agent_remove_idenitity.py @@ -0,0 +1,9 @@ +import pytest + +from indy import agent + + +@pytest.mark.asyncio +async def test_agent_remove_identity_works(listener_with_identity): + listener_handle, wallet_handle, did = listener_with_identity + await agent.agent_remove_identity(listener_handle, wallet_handle, did) diff --git a/wrappers/python/tests/agent/test_agent_send.py b/wrappers/python/tests/agent/test_agent_send.py new file mode 100644 index 0000000000..284b377891 --- /dev/null +++ b/wrappers/python/tests/agent/test_agent_send.py @@ -0,0 +1,25 @@ +import json + +import pytest + +from indy import signus, ledger, agent +from tests.utils import wallet + + +@pytest.mark.asyncio +async def test_agent_send_works_for_all_data_in_wallet_present(connection): + listener_handle, inc_con_handle, out_con_handle, wallet_handle, did = connection + + await agent.agent_send(out_con_handle, "msg_from_client") + message_event = await agent.agent_wait_for_event([listener_handle, inc_con_handle]) # type: agent.MessageEvent + + assert type(message_event) is agent.MessageEvent + assert message_event.handle == inc_con_handle + assert message_event.message == "msg_from_client" + + await agent.agent_send(inc_con_handle, "msg_from_server") + message_event = await agent.agent_wait_for_event([out_con_handle]) # type: agent.MessageEvent + + assert type(message_event) is agent.MessageEvent + assert message_event.handle == out_con_handle + assert message_event.message == "msg_from_server" diff --git a/wrappers/python/tests/anoncreds/test_issuer_create_and_store_claim_def.py b/wrappers/python/tests/anoncreds/test_issuer_create_and_store_claim_def.py new file mode 100644 index 0000000000..736e8d981e --- /dev/null +++ b/wrappers/python/tests/anoncreds/test_issuer_create_and_store_claim_def.py @@ -0,0 +1,53 @@ +from indy import wallet +from indy.anoncreds import issuer_create_and_store_claim_def +from indy.error import ErrorCode, IndyError + +from tests.utils import storage, anoncreds +from tests.utils.wallet import create_and_open_wallet + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.fixture +async def wallet_handle(): + handle = await create_and_open_wallet() + yield handle + await wallet.close_wallet(handle) + + +@pytest.mark.asyncio +async def test_issuer_create_and_store_claim_def_works(wallet_handle): + schema = anoncreds.get_gvt_schema_json(1) + claim_def_json = json.loads(await issuer_create_and_store_claim_def(wallet_handle, anoncreds.ISSUER_DID, + json.dumps(schema), "CL", False)) + assert len(claim_def_json['data']['primary']['r']) == 4 + assert len(claim_def_json['data']['primary']['n']) > 0 + assert len(claim_def_json['data']['primary']['s']) > 0 + assert len(claim_def_json['data']['primary']['rms']) > 0 + assert len(claim_def_json['data']['primary']['z']) > 0 + assert len(claim_def_json['data']['primary']['rctxt']) > 0 + + +@pytest.mark.asyncio +async def test_issuer_create_and_store_claim_def_works_for_invalid_wallet(wallet_handle): + schema = anoncreds.get_gvt_schema_json(1) + invalid_wallet_handle = wallet_handle + 100 + + try: + await issuer_create_and_store_claim_def( + invalid_wallet_handle, anoncreds.ISSUER_DID, json.dumps(schema), None, False) + raise Exception("Failed") + except Exception as e: + assert type(IndyError(ErrorCode.WalletInvalidHandle)) == type(e) and \ + IndyError(ErrorCode.WalletInvalidHandle).args == e.args \ No newline at end of file diff --git a/wrappers/python/tests/anoncreds/test_issuer_create_claim.py b/wrappers/python/tests/anoncreds/test_issuer_create_claim.py new file mode 100644 index 0000000000..6c0d395c31 --- /dev/null +++ b/wrappers/python/tests/anoncreds/test_issuer_create_claim.py @@ -0,0 +1,53 @@ +from indy import wallet +from indy.anoncreds import issuer_create_claim +from indy.error import ErrorCode, IndyError + +from tests.utils import storage, anoncreds +from tests.utils.wallet import create_and_open_wallet + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.fixture +async def wallet_handle(): + handle = await create_and_open_wallet() + await anoncreds.prepare_common_wallet(handle) + yield handle + await wallet.close_wallet(handle) + + +@pytest.mark.asyncio +async def test_issuer_create_claim_works(wallet_handle): + claim_req = anoncreds.get_claim_req() + claim_json = anoncreds.get_gvt_claim_json() + (_, claim_json) = await issuer_create_claim(wallet_handle, json.dumps(claim_req), json.dumps(claim_json), -1, -1) + + +@pytest.mark.asyncio +async def test_issuer_create_claim_works_for_claim_does_not_correspond_to_claim_req(wallet_handle): + claim_req = anoncreds.get_claim_req() + claim_json = anoncreds.get_xyz_claim_json() + with pytest.raises(IndyError) as e: + await issuer_create_claim(wallet_handle, json.dumps(claim_req), json.dumps(claim_json), -1, -1) + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_issuer_create_claim_works_for_for_invalid_wallet_handle(wallet_handle): + claim_req = anoncreds.get_claim_req() + claim_json = anoncreds.get_gvt_claim_json() + invalid_wallet_handle = wallet_handle + 100 + with pytest.raises(IndyError) as e: + await issuer_create_claim(invalid_wallet_handle, json.dumps(claim_req), json.dumps(claim_json), -1, -1) + assert ErrorCode.WalletInvalidHandle == e.value.error_code diff --git a/wrappers/python/tests/anoncreds/test_prover_create_and_store_claim_req.py b/wrappers/python/tests/anoncreds/test_prover_create_and_store_claim_req.py new file mode 100644 index 0000000000..d615aedece --- /dev/null +++ b/wrappers/python/tests/anoncreds/test_prover_create_and_store_claim_req.py @@ -0,0 +1,87 @@ +from indy import wallet +from indy.anoncreds import prover_create_and_store_claim_req +from indy.error import ErrorCode, IndyError + +from tests.utils import storage, anoncreds +from tests.utils.wallet import create_and_open_wallet + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.fixture +async def wallet_handle_and_claim_def(): + handle = await create_and_open_wallet() + claim_def = await anoncreds.prepare_common_wallet(handle) + yield (handle, claim_def) + await wallet.close_wallet(handle) + + +@pytest.mark.asyncio +async def test_prover_create_and_store_claim_req_works(wallet_handle_and_claim_def): + schema_seq_no = 1 + prover_did = "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW" + claim_offer_json = anoncreds.get_claim_offer(anoncreds.ISSUER_DID, schema_seq_no) + claim_req_json = json.loads(await prover_create_and_store_claim_req(wallet_handle_and_claim_def[0], prover_did, + json.dumps(claim_offer_json), + wallet_handle_and_claim_def[1], + anoncreds.COMMON_MASTER_SECRET_NAME)) + assert claim_req_json['schema_seq_no'] == schema_seq_no + assert claim_req_json['issuer_did'] == anoncreds.ISSUER_DID + assert len(claim_req_json['blinded_ms']['u']) > 0 + + +@pytest.mark.asyncio +async def test_prover_create_and_store_claim_req_works_for_invalid_wallet(wallet_handle_and_claim_def): + schema_seq_no = 1 + prover_did = "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW" + invalid_wallet_handle = wallet_handle_and_claim_def[0] + 100 + claim_offer_json = anoncreds.get_claim_offer(anoncreds.ISSUER_DID, schema_seq_no) + + with pytest.raises(IndyError) as e: + await prover_create_and_store_claim_req(invalid_wallet_handle, prover_did, + json.dumps(claim_offer_json), + wallet_handle_and_claim_def[1], + anoncreds.COMMON_MASTER_SECRET_NAME) + + assert ErrorCode.WalletInvalidHandle == e.value.error_code + + +@pytest.mark.asyncio +async def test_prover_create_and_store_claim_req_works_for_claim_def_does_not_correspond_offer_different_issuer_did(wallet_handle_and_claim_def): + schema_seq_no = 1 + prover_did = "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW" + claim_offer_json = anoncreds.get_claim_offer("NcYxiDXkpYi6ov5FcYDi1e3", schema_seq_no) + + with pytest.raises(IndyError) as e: + await prover_create_and_store_claim_req(wallet_handle_and_claim_def[0], prover_did, + json.dumps(claim_offer_json), + wallet_handle_and_claim_def[1], + anoncreds.COMMON_MASTER_SECRET_NAME) + + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_prover_create_and_store_claim_req_works_for_claim_def_does_not_correspond_offer_different_schema_seq_no(wallet_handle_and_claim_def): + schema_seq_no = 2 + prover_did = "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW" + claim_offer_json = anoncreds.get_claim_offer(anoncreds.ISSUER_DID, schema_seq_no) + + with pytest.raises(IndyError) as e: + await prover_create_and_store_claim_req(wallet_handle_and_claim_def[0], prover_did, + json.dumps(claim_offer_json), + wallet_handle_and_claim_def[1], + anoncreds.COMMON_MASTER_SECRET_NAME) + + assert ErrorCode.CommonInvalidStructure == e.value.error_code diff --git a/wrappers/python/tests/anoncreds/test_prover_create_master_secret.py b/wrappers/python/tests/anoncreds/test_prover_create_master_secret.py new file mode 100644 index 0000000000..9a047fe22e --- /dev/null +++ b/wrappers/python/tests/anoncreds/test_prover_create_master_secret.py @@ -0,0 +1,44 @@ +from indy import wallet +from indy.anoncreds import prover_create_master_secret +from indy.error import ErrorCode, IndyError + +from tests.utils import storage, anoncreds +from tests.utils.wallet import create_and_open_wallet + +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.fixture +async def wallet_handle(): + handle = await create_and_open_wallet() + await anoncreds.prepare_common_wallet(handle) + yield handle + await wallet.close_wallet(handle) + + +@pytest.mark.asyncio +async def test_prover_create_master_secret_works(wallet_handle): + await prover_create_master_secret(wallet_handle, "master_secret_name") + + +@pytest.mark.asyncio +async def test_prover_create_master_secret_works_invalid_wallet_handle(wallet_handle): + invalid_wallet_handle = wallet_handle + 100 + + try: + await prover_create_master_secret(invalid_wallet_handle, "master_secret_name") + raise Exception("Failed") + except Exception as e: + assert type(IndyError(ErrorCode.WalletInvalidHandle)) == type(e) and \ + IndyError(ErrorCode.WalletInvalidHandle).args == e.args + diff --git a/wrappers/python/tests/anoncreds/test_prover_create_proof.py b/wrappers/python/tests/anoncreds/test_prover_create_proof.py new file mode 100644 index 0000000000..a3f7682e72 --- /dev/null +++ b/wrappers/python/tests/anoncreds/test_prover_create_proof.py @@ -0,0 +1,167 @@ +from indy import wallet +from indy.anoncreds import prover_get_claims_for_proof_req, prover_create_proof, prover_get_claims +from indy.error import ErrorCode, IndyError + +from tests.utils import storage, anoncreds +from tests.utils.wallet import create_and_open_wallet + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.fixture +async def wallet_handle_and_claim_def(): + handle = await create_and_open_wallet() + claim_def = await anoncreds.prepare_common_wallet(handle) + yield (handle, claim_def) + await wallet.close_wallet(handle) + + +@pytest.mark.asyncio +async def test_prover_create_proof_works(wallet_handle_and_claim_def): + proof_req = { + "nonce": "123432421212", + "name": "proof_req_1", + "version": "0.1", + "requested_attrs": { + "attr1_uuid": { + "schema_seq_no": 1, + "name": "name" + } + }, + "requested_predicates": { + "predicate1_uuid": { + "attr_name": "age", + "p_type": "GE", + "value": 18 + } + } + } + + claims = json.loads(await prover_get_claims_for_proof_req(wallet_handle_and_claim_def[0], json.dumps(proof_req))) + claim_for_attr = claims['attrs']['attr1_uuid'][0]['claim_uuid'] + claim_for_predicate = claims['predicates']['predicate1_uuid'][0]['claim_uuid'] + requested_claims = { + "self_attested_attributes": {}, + "requested_attrs": { + "attr1_uuid": [claim_for_attr, True] + }, + "requested_predicates": { + "predicate1_uuid": claim_for_predicate + } + } + + schemas = { + claim_for_attr: anoncreds.get_gvt_schema_json(1) + } + + claim_defs = { + claim_for_attr: json.loads(wallet_handle_and_claim_def[1]) + } + + await prover_create_proof(wallet_handle_and_claim_def[0], json.dumps(proof_req), json.dumps(requested_claims), + json.dumps(schemas), anoncreds.COMMON_MASTER_SECRET_NAME, + json.dumps(claim_defs), "{}") + + +@pytest.mark.asyncio +async def test_prover_create_proof_works_for_using_not_satisfy_claim(wallet_handle_and_claim_def): + claims = json.loads(await prover_get_claims(wallet_handle_and_claim_def[0], "{}")) + claim_uuid = claims[0]['claim_uuid'] + proof_req = { + "nonce": "123432421212", + "name": "proof_req_1", + "version": "0.1", + "requested_attrs": { + "attr1_uuid": { + "schema_seq_no": 1, + "name": "some_attr" + } + }, + "requested_predicates": {} + } + + requested_claims = { + "self_attested_attributes": {}, + "requested_attrs": { + "attr1_uuid": [claim_uuid, True] + }, + "requested_predicates": { + "predicate1_uuid": {} + } + } + + schemas = { + claim_uuid: anoncreds.get_gvt_schema_json(1) + } + + claim_defs = { + claim_uuid: json.loads(wallet_handle_and_claim_def[1]) + } + + with pytest.raises(IndyError) as e: + await prover_create_proof(wallet_handle_and_claim_def[0], json.dumps(proof_req), json.dumps(requested_claims), + json.dumps(schemas), anoncreds.COMMON_MASTER_SECRET_NAME, + json.dumps(claim_defs), "{}") + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_prover_create_proof_works_for_invalid_wallet_handle(wallet_handle_and_claim_def): + proof_req = { + "nonce": "123432421212", + "name": "proof_req_1", + "version": "0.1", + "requested_attrs": { + "attr1_uuid": { + "schema_seq_no": 1, + "name": "name" + } + }, + "requested_predicates": { + "predicate1_uuid": { + "attr_name": "age", + "p_type": "GE", + "value": 18 + } + } + } + + claims = json.loads(await prover_get_claims_for_proof_req(wallet_handle_and_claim_def[0], json.dumps(proof_req))) + claim_for_attr = claims['attrs']['attr1_uuid'][0]['claim_uuid'] + claim_for_predicate = claims['predicates']['predicate1_uuid'][0]['claim_uuid'] + requested_claims = { + "self_attested_attributes": {}, + "requested_attrs": { + "attr1_uuid": [claim_for_attr, True] + }, + "requested_predicates": { + "predicate1_uuid": claim_for_predicate + } + } + + schemas = { + claim_for_attr: anoncreds.get_gvt_schema_json(1) + } + + claim_defs = { + claim_for_attr: json.loads(wallet_handle_and_claim_def[1]) + } + + invalid_wallet_handle = wallet_handle_and_claim_def[0] + 100 + + with pytest.raises(IndyError) as e: + await prover_create_proof(invalid_wallet_handle, json.dumps(proof_req), json.dumps(requested_claims), + json.dumps(schemas), anoncreds.COMMON_MASTER_SECRET_NAME, + json.dumps(claim_defs), "{}") + assert ErrorCode.WalletInvalidHandle == e.value.error_code diff --git a/wrappers/python/tests/anoncreds/test_prover_get_claim_offers.py b/wrappers/python/tests/anoncreds/test_prover_get_claim_offers.py new file mode 100644 index 0000000000..4abae590f2 --- /dev/null +++ b/wrappers/python/tests/anoncreds/test_prover_get_claim_offers.py @@ -0,0 +1,79 @@ +from indy import wallet +from indy.anoncreds import prover_get_claim_offers +from indy.error import ErrorCode, IndyError + +from tests.utils import storage, anoncreds +from tests.utils.wallet import create_and_open_wallet + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.fixture +async def wallet_handle(): + handle = await create_and_open_wallet() + await anoncreds.prepare_common_wallet(handle) + yield handle + await wallet.close_wallet(handle) + + +@pytest.mark.asyncio +async def test_prover_get_claim_offers_works_for_empty_filter(wallet_handle): + claim_offers = json.loads(await prover_get_claim_offers(wallet_handle, "{}")) + assert len(claim_offers) == 3 + + +@pytest.mark.asyncio +async def test_prover_get_claim_offers_works_for_filter_by_issuer(wallet_handle): + claim_offers = json.loads(await prover_get_claim_offers( + wallet_handle, '{{"issuer_did":"{}"}}'.format(anoncreds.ISSUER_DID))) + assert len(claim_offers) == 2 + assert {'issuer_did': anoncreds.ISSUER_DID, 'schema_seq_no': 1} in claim_offers + assert {'issuer_did': anoncreds.ISSUER_DID, 'schema_seq_no': 2} in claim_offers + + +@pytest.mark.asyncio +async def test_prover_get_claim_offers_works_for_filter_by_schema(wallet_handle): + claim_offers = json.loads(await prover_get_claim_offers( + wallet_handle, '{"schema_seq_no":2}')) + assert len(claim_offers) == 2 + assert {'issuer_did': anoncreds.ISSUER_DID, 'schema_seq_no': 2} in claim_offers + assert {'issuer_did': 'CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW', 'schema_seq_no': 2} in claim_offers + + +@pytest.mark.asyncio +async def test_prover_get_claim_offers_works_for_filter_by_issuer_and_schema(wallet_handle): + claim_offers = json.loads(await prover_get_claim_offers( + wallet_handle, json.dumps(anoncreds.get_claim_offer(anoncreds.ISSUER_DID, 1)))) + assert len(claim_offers) == 1 + assert {'issuer_did': anoncreds.ISSUER_DID, 'schema_seq_no': 1} in claim_offers + + +@pytest.mark.asyncio +async def test_prover_get_claim_offers_works_for_no_results(wallet_handle): + claim_offers = json.loads(await prover_get_claim_offers( + wallet_handle, '{"schema_seq_no":4}')) + assert len(claim_offers) == 0 + + +@pytest.mark.asyncio +async def test_prover_get_claim_offers_works_for_invalid_wallet_handle(wallet_handle): + invalid_wallet_handle = wallet_handle + 100 + + try: + await prover_get_claim_offers(invalid_wallet_handle, '{"schema_seq_no":1}') + raise Exception("Failed") + except Exception as e: + assert type(IndyError(ErrorCode.WalletInvalidHandle)) == type(e) and \ + IndyError(ErrorCode.WalletInvalidHandle).args == e.args + diff --git a/wrappers/python/tests/anoncreds/test_prover_get_claims.py b/wrappers/python/tests/anoncreds/test_prover_get_claims.py new file mode 100644 index 0000000000..d340a4f6b5 --- /dev/null +++ b/wrappers/python/tests/anoncreds/test_prover_get_claims.py @@ -0,0 +1,60 @@ +from indy import wallet +from indy.anoncreds import prover_get_claims +from indy.error import ErrorCode, IndyError + +from tests.utils import storage, anoncreds +from tests.utils.wallet import create_and_open_wallet + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.fixture +async def wallet_handle(): + handle = await create_and_open_wallet() + await anoncreds.prepare_common_wallet(handle) + yield handle + await wallet.close_wallet(handle) + + +@pytest.mark.asyncio +async def test_prover_get_claims_works_for_empty_filter(wallet_handle): + claims = json.loads(await prover_get_claims(wallet_handle, "{}")) + assert len(claims) == 1 + + +@pytest.mark.asyncio +async def test_prover_get_claims_works_for_filter_by_issuer_did(wallet_handle): + claims = json.loads(await prover_get_claims(wallet_handle, '{{"issuer_did":"{}"}}'.format(anoncreds.ISSUER_DID))) + assert len(claims) == 1 + + +@pytest.mark.asyncio +async def test_prover_get_claims_works_for_filter_by_issuer_did_and_schema_seq_no(wallet_handle): + claims = json.loads(await prover_get_claims(wallet_handle, json.dumps(anoncreds.get_claim_offer(anoncreds.ISSUER_DID, 1)))) + assert len(claims) == 1 + + +@pytest.mark.asyncio +async def test_prover_get_claims_works_for_empty_result(wallet_handle): + claims = json.loads(await prover_get_claims(wallet_handle, '{"schema_seq_no":10}')) + assert len(claims) == 0 + + +@pytest.mark.asyncio +async def test_prover_get_claims_works_for_invalid_wallet_handle(wallet_handle): + invalid_wallet_handle = wallet_handle + 100 + + with pytest.raises(IndyError) as e: + await prover_get_claims(invalid_wallet_handle, '{}') + assert ErrorCode.WalletInvalidHandle == e.value.error_code diff --git a/wrappers/python/tests/anoncreds/test_prover_get_claims_for_proof_req.py b/wrappers/python/tests/anoncreds/test_prover_get_claims_for_proof_req.py new file mode 100644 index 0000000000..f989ac4597 --- /dev/null +++ b/wrappers/python/tests/anoncreds/test_prover_get_claims_for_proof_req.py @@ -0,0 +1,166 @@ +from indy import wallet +from indy.anoncreds import prover_get_claims_for_proof_req +from indy.error import ErrorCode, IndyError + +from tests.utils import storage, anoncreds +from tests.utils.wallet import create_and_open_wallet + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.fixture +async def wallet_handle(): + handle = await create_and_open_wallet() + await anoncreds.prepare_common_wallet(handle) + yield handle + await wallet.close_wallet(handle) + + +@pytest.mark.asyncio +async def test_prover_get_claims_for_proof_req_works_for_revealed_attr(wallet_handle): + proof_req = { + "nonce": "123432421212", + "name": "proof_req_1", + "version": "0.1", + "requested_attrs": { + "attr1_uuid": { + "schema_seq_no": 1, + "name": "name" + } + }, + "requested_predicates": {} + } + + claims = json.loads(await prover_get_claims_for_proof_req(wallet_handle, json.dumps(proof_req))) + assert len(claims['attrs']) == 1 + assert len(claims['predicates']) == 0 + assert len(claims['attrs']['attr1_uuid']) == 1 + + +@pytest.mark.asyncio +async def test_prover_get_claims_for_proof_req_works_for_not_found_attribute(wallet_handle): + proof_req = { + "nonce": "123432421212", + "name": "proof_req_1", + "version": "0.1", + "requested_attrs": { + "attr1_uuid": { + "schema_seq_no": 1, + "name": "some_attr" + } + }, + "requested_predicates": {} + } + + claims = json.loads(await prover_get_claims_for_proof_req(wallet_handle, json.dumps(proof_req))) + assert len(claims['attrs']) == 1 + assert len(claims['predicates']) == 0 + assert len(claims['attrs']['attr1_uuid']) == 0 + + +@pytest.mark.asyncio +async def test_prover_get_claims_for_proof_req_works_for_satisfy_predicate(wallet_handle): + proof_req = { + "nonce": "123432421212", + "name": "proof_req_1", + "version": "0.1", + "requested_attrs": {}, + "requested_predicates": { + "predicate1_uuid": + { + "attr_name": "age", + "p_type": "GE", + "value": 18 + } + } + } + + claims = json.loads(await prover_get_claims_for_proof_req(wallet_handle, json.dumps(proof_req))) + assert len(claims['attrs']) == 0 + assert len(claims['predicates']) == 1 + assert len(claims['predicates']['predicate1_uuid']) == 1 + + +@pytest.mark.asyncio +async def test_prover_get_claims_for_proof_req_works_for_not_satisfy_predicate(wallet_handle): + proof_req = { + "nonce": "123432421212", + "name": "proof_req_1", + "version": "0.1", + "requested_attrs": {}, + "requested_predicates": { + "predicate1_uuid": + { + "attr_name": "age", + "p_type": "GE", + "value": 58 + } + } + } + + claims = json.loads(await prover_get_claims_for_proof_req(wallet_handle, json.dumps(proof_req))) + assert len(claims['attrs']) == 0 + assert len(claims['predicates']) == 1 + assert len(claims['predicates']['predicate1_uuid']) == 0 + + +@pytest.mark.asyncio +async def test_prover_get_claims_for_proof_req_works_for_multiply_attribute_and_predicates(wallet_handle): + proof_req = { + "nonce": "123432421212", + "name": "proof_req_1", + "version": "0.1", + "requested_attrs": { + "attr1_uuid": {"schema_seq_no": 1, "name": "name"}, + "attr2_uuid": {"schema_seq_no": 1, "name": "sex"} + }, + "requested_predicates": { + "predicate1_uuid": {"attr_name": "age", "p_type": "GE", "value": 18}, + "predicate2_uuid": {"attr_name": "height", "p_type": "GE", "value": 160} + } + } + + claims = json.loads(await prover_get_claims_for_proof_req(wallet_handle, json.dumps(proof_req))) + assert len(claims['attrs']) == 2 + assert len(claims['predicates']) == 2 + assert len(claims['attrs']['attr1_uuid']) == 1 + assert len(claims['attrs']['attr2_uuid']) == 1 + assert len(claims['predicates']['predicate1_uuid']) == 1 + assert len(claims['predicates']['predicate2_uuid']) == 1 + + +@pytest.mark.asyncio +async def test_prover_get_claims_for_proof_req_works_for_invalid_wallet_handle(wallet_handle): + proof_req = { + "nonce": "123432421212", + "name": "proof_req_1", + "version": "0.1", + "requested_attrs": {}, + "requested_predicates": { + "predicate1_uuid": + { + "attr_name": "age", + "p_type": "GE", + "value": 58 + } + } + } + + invalid_wallet_handle = wallet_handle + 100 + + with pytest.raises(IndyError) as e: + await prover_get_claims_for_proof_req(invalid_wallet_handle, json.dumps(proof_req)) + assert ErrorCode.WalletInvalidHandle == e.value.error_code + + diff --git a/wrappers/python/tests/anoncreds/test_prover_store_claim.py b/wrappers/python/tests/anoncreds/test_prover_store_claim.py new file mode 100644 index 0000000000..5bb6cacc5a --- /dev/null +++ b/wrappers/python/tests/anoncreds/test_prover_store_claim.py @@ -0,0 +1,60 @@ +from indy import wallet +from indy.anoncreds import prover_create_and_store_claim_req, prover_store_claim,\ + prover_create_master_secret, issuer_create_claim +from indy.error import ErrorCode, IndyError + +from tests.utils import storage, anoncreds +from tests.utils.wallet import create_and_open_wallet + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.fixture +async def wallet_handle_and_claim_def(): + handle = await create_and_open_wallet() + claim_def = await anoncreds.prepare_common_wallet(handle) + yield (handle, claim_def) + await wallet.close_wallet(handle) + + +@pytest.mark.asyncio +async def test_prover_store_claim_works(wallet_handle_and_claim_def): + prover_did = "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW" + claim_offer_json = anoncreds.get_claim_offer(anoncreds.ISSUER_DID, 1) + await prover_create_master_secret(wallet_handle_and_claim_def[0], anoncreds.COMMON_MASTER_SECRET_NAME_1) + claim_req = await prover_create_and_store_claim_req(wallet_handle_and_claim_def[0], prover_did, + json.dumps(claim_offer_json), wallet_handle_and_claim_def[1], + anoncreds.COMMON_MASTER_SECRET_NAME_1) + + (_, claim_json) = await issuer_create_claim(wallet_handle_and_claim_def[0], claim_req, + json.dumps(anoncreds.get_gvt_claim_json()), -1, -1) + await prover_store_claim(wallet_handle_and_claim_def[0], claim_json) + + +@pytest.mark.asyncio +async def test_prover_store_claim_works_for_invalid_wallet_handle(wallet_handle_and_claim_def): + prover_did = "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW" + claim_offer_json = anoncreds.get_claim_offer(anoncreds.ISSUER_DID, 1) + invalid_wallet_handle = wallet_handle_and_claim_def[0] + 100 + await prover_create_master_secret(wallet_handle_and_claim_def[0], anoncreds.COMMON_MASTER_SECRET_NAME_1) + claim_req = await prover_create_and_store_claim_req(wallet_handle_and_claim_def[0], prover_did, + json.dumps(claim_offer_json), wallet_handle_and_claim_def[1], + anoncreds.COMMON_MASTER_SECRET_NAME_1) + + (_, claim_json) = await issuer_create_claim(wallet_handle_and_claim_def[0], claim_req, + json.dumps(anoncreds.get_gvt_claim_json()), -1, -1) + + with pytest.raises(IndyError) as e: + await prover_store_claim(invalid_wallet_handle, claim_json) + assert ErrorCode.WalletInvalidHandle == e.value.error_code diff --git a/wrappers/python/tests/anoncreds/test_prover_store_claim_offer.py b/wrappers/python/tests/anoncreds/test_prover_store_claim_offer.py new file mode 100644 index 0000000000..d167f7788b --- /dev/null +++ b/wrappers/python/tests/anoncreds/test_prover_store_claim_offer.py @@ -0,0 +1,58 @@ +from indy import wallet +from indy.anoncreds import prover_store_claim_offer +from indy.error import ErrorCode, IndyError + +from tests.utils import storage, anoncreds +from tests.utils.wallet import create_and_open_wallet + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.fixture +async def wallet_handle(): + handle = await create_and_open_wallet() + await anoncreds.prepare_common_wallet(handle) + yield handle + await wallet.close_wallet(handle) + + +@pytest.mark.asyncio +async def test_prover_store_claim_offer_works(wallet_handle): + claim_offer = anoncreds.get_claim_offer(anoncreds.ISSUER_DID, 1) + await prover_store_claim_offer(wallet_handle, json.dumps(claim_offer)) + + +@pytest.mark.asyncio +async def test_prover_store_claim_offer_works_for_invalid_json(wallet_handle): + claim_offer = {"issuer_did": anoncreds.ISSUER_DID} + + try: + await prover_store_claim_offer(wallet_handle, json.dumps(claim_offer)) + raise Exception("Failed") + except Exception as e: + assert type(IndyError(ErrorCode.CommonInvalidStructure)) == type(e) and \ + IndyError(ErrorCode.CommonInvalidStructure).args == e.args + + +@pytest.mark.asyncio +async def test_prover_store_claim_offer_works_for_invalid_wallet(wallet_handle): + claim_offer = anoncreds.get_claim_offer(anoncreds.ISSUER_DID, 1) + invalid_wallet_handle = wallet_handle + 100 + + try: + await prover_store_claim_offer(invalid_wallet_handle, json.dumps(claim_offer)) + raise Exception("Failed") + except Exception as e: + assert type(IndyError(ErrorCode.WalletInvalidHandle)) == type(e) and \ + IndyError(ErrorCode.WalletInvalidHandle).args == e.args diff --git a/wrappers/python/tests/anoncreds/test_verify_proof.py b/wrappers/python/tests/anoncreds/test_verify_proof.py new file mode 100644 index 0000000000..7d2aaba94a --- /dev/null +++ b/wrappers/python/tests/anoncreds/test_verify_proof.py @@ -0,0 +1,466 @@ +from indy.anoncreds import verifier_verify_proof +from indy.error import ErrorCode, IndyError + +from tests.utils import storage, anoncreds + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_verifier_verify_proof_works_for_correct_proof(): + proof_req = anoncreds.get_proof_req() + claim_def = anoncreds.get_claim_def() + + schemas = { + "claim::277478db-bf57-42c3-8530-b1b13cfe0bfd": anoncreds.get_gvt_schema_json(1) + } + claim_defs = { + "claim::277478db-bf57-42c3-8530-b1b13cfe0bfd": claim_def + } + proof = { + "proofs": { + "claim::277478db-bf57-42c3-8530-b1b13cfe0bfd": { + "proof": { + "primary_proof": { + "eq_proof": { + "revealed_attrs": { + "name": "1139481716457488690172217916278103335" + }, + "a_prime": "47629821806628155353444789773246165920681315271529392722265555946090524267165563309836167110610840740533588118152308411732923636370660640410661034994521654033599863817144282118006097899736622728860229305231675970853294584911572355833537271010861501353858292189045263114095480601737776505186511389129055847562085611741257601964074827979121349153316235245772819207422031038042586202074331681302501661153569340935741290924699468188826629478130140797677338573924284871118002193526319478550852287453975107498037063076866410320160118555629090040954555043934303307652160345244864713226315470541231435958298648179413077988340", + "e": "13427639393364185909415877973872458621259927563729922146828001652769380799419438410309469022979920689628523901764614163117469683925816443", + "v": "852136445143816932026946294488424887907102968158908948827421962603492187508454543239422067899916472317305416590471170842186669606584356963437132366711335927890209765986844538775191207999204354235774464468525274918097404114453069375363594310105209141774763909570100638835926337238009617444858777301355087706167735590386774813901740600054753028260344014744801229032610106838480523182317262113911183640784111960909501662169298536941919854667754097841344375972975021196106884215734228415868248724905018661498061287694439466570946597514142085096419985189064172035527690786158872698717583830848410994616274586162550376126607414773916066374234063208380831144157533076866210628625236440222547584539349936639548061601416341705483504386186280800509889531835172071717956251546280392606775903107774727736794828168898273891724336881907672405328368540895104468091907771325910937575557566831844131159128453840354307814975621978196047820", + "m": { + "age": "1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662", + "height": "7064132689652704067914104576495132313294680087958177180391515757079548676035445873279966783996928425154050462229933823707574545166617858646442019030600136959459527533262821184869", + "sex": "16084497853957041205729191269508720470626311156190485518484640641677445098603656354458362520541393995692536218820724164533958162674375198846036330444513484319280148335515891811530"}, + "m1": "154906224259819061652290487122980839849626068919893070220438585977323162319993111920906032317552959103520053742608858935542877608981244065301675821390065831113115709272412144796159984624494428122971995557415296140268002332169405587907128359886810433617416529821500995701094400375272097687818064435577784795275", + "m2": "13805395408072590464827983892588030341708765524663545700917462089376137940485022437657208204460048097312372685954050370540389593952001973312378647790917367330461398089529292217752"}, + "ge_proofs": [{"u": { + "1": "7698818972783845439601187851976452936638792889455287252542709653271706844173743185409084669157965935169942655008606334521674712818637940377261656468700786810566551698412412949418", + "0": "11703047052430512223413711314521545616119146623040600935686474696241801697819280425232876917607198335376453682738553665221410353412906194951254558355994401995990233992518110582450", + "3": "13210777821918317858818819091924507295018522783042111457450035423463340571245465760486275059291363621513532153389441883097799049597687545496359999443320001567152794884095192951040", + "2": "15219471780524079156861690098171693383497641272226737821992208834301871102152362116211452788300889697214391366996966539871625433480959011635688106136537800706217506402845296449689"}, + "r": { + "1": "46043242109380749151527145850513330956077996622769158245225343392397735706292106535150958053995712629189143692293204979798837951212291825184346767969751978730000071952944305252032332015837054475531407691352179423131405515518588355918925056889302269768343499864256747177988825578647189563088068257214198650437730618330249172716051559993880468542083352885474175039320848153156858562341041960950299312991459780503345784440261679263045723337629951517601461685539857683027034345542399365706329805317943096391758978877658949910614447086409173234155028671453929715706057153381022697673192590033507204548864311227048268516889390503318015295207078022755834130221198717787608473222789491216667698651180077661375273569115943192", + "0": "135472587547410377947826119498467634347118057359097899596599164976338466445104141784869016998150489852448547539824768048351359572626675997498079394825940306636285481821620973655797996638210760710325933304918452142858879806106214845499670718704532018129553348815327362843246706518826311676917538452317818631484884032929252959289913274829848084561421467966320595980172006456003183536232790787521924655750157145207798486087511869939940023266736153366338179116840490184005332351004990854691988404031259910319601383696749511809898297656135548118786342107367065232798999979296280467063561892962526945512167505847049907450058650930480352253243357594344686769208712964458923557777584158831146374282687397585726706489164423632", + "DELTA": "93540839493959971552865423901789226093328763011922445919928571946113703515842729132879472109395228387208764738970926484618949870591214627692618668077375153559192701474693025462226656116549337248146652482501255820930607033869432220667968682424554711616471973627651716863421554516577716366331699848682958681216261888139409101603059124344125075525791543312721162515584942523419876134808829569829529457617639955678189490257208141837196965948342373022812790844435050648360150869293836349223060722858500537182872294143846213258360218898475766641125493477502149553491502593654061863323857297998048614447925371606038801933864960337435890254277043261512846682042139570000962051463878026338583242360548041329046695667868842400", + "3": "1227675452527605924725300993571504188580051470857656204064614533296779844072852823820754766175236321050062349182891221840452517985644028521499240739391613871973822807731772613052644168369405390658793869751915172749739844553410726807277698347769400977274750672880389943392076308065414059539317340070691852044062594715307024113666759844200606183662256825096857658837519571386467051003466014468855293015652584667669998830524947537781865745830650392641812221679438090257444660715937570193098993118585554478799821072396238689063767016402460690760792908977364175126682041704095200572282644311025594681667826054722587271200221036938804846621444065128275082392082327596239358623150786484106872933657139420542280145197712634108", + "2": "596248147592834822582469335300585333722415132713749620075902332764163096347819006925876158892694742461036531935093982309708492066217459300117157420442081698140277277546563570823996272914068575482008392971932777453900260626542725308060927710122631763045025742980634216666560934260634907599194353151523256914796667535940073668465664206971169038864484235442207811974981191879443614478897291543702607764944403808380921189291059195014621592027660463072969363556421687131446107696579365265893962197300447027501604372738056016734644378437907931412654753728514905671605635291285742886484416973884856055084605172305967034292646171874483670469193852404511746786039743401185954843446037600121496137915619789351744485264614840070"}, + "mj": "1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662", + "alpha": "76727612740067576380015106087224381023260815407331375101920043509817863645705120013304683427627332447210083684516403565749916480947649443674885388155460323163682547865307733144184097845709556309570345707127872162476432029772452433292049079349274445907295491125915363620615679995457134810061392296263970553630102299601689685622244925494554558218277670233361938142224820526392365740420502452466959099546877778248089664282581792213376636587293479012783947088070052463503335266180110771978445892744225891676396288437005847308189508347446490710626231658457908472341606549292437553353163031111068977301305043175839949352742711874426231072729977019365761072816602400121302646283352164756787266537474728685656685493249314400351742964904006326192403855909148605656818024621453179832395687665671245528217931951331393482249182516107670379946496778373", + "t": { + "1": "37203689290881948278188715497642400459048942241931994079434400288578680362970117779048886269388440270597283202033458042171954610700745461571112086648991639439510380585728148682202768590972068041537531136529323260832899360551065706810590032715173070285762675403853992183366951113799098912676809373169763887110420539387555392787590966452796271491986622992160642135480293110112269570862265489120557014181468118619500321000966443141863893743211690388599242584469856365803370202569641902205925191670838354052104480074127555862332399641076324738839120815544432811566503174551735326387678621283249883091766325861497740614317", + "3": "58486787977689017034592833190899828017343431922483563651969628402499947729293364026001243898136737211851089198526360764391403150763769829047179796728616126204105160762333590343947446892105646111520243793053992399512412375936746396187319527051818920531870855183738837254656664620975569939859368862778444291640228229744805843388153451336792379036403300211151424879060241580540910888241769468335914016289938374111481091198264912969768783884602931940994543804730631920434719776196148182987249363641941951160704928605829395517074202388967815738516252602903999010405305463910751219873354588685197134114358234107748126140977", + "0": "60771874648036182010335841594233428920565254732600738082343398028553347795361460295011584446745121430144172025428394361648540904134739046923992231536160801306934272250969829886396340824213814702904457884984387666505055153957942221822193548673145705543973635530652570436109428474727638128773540793530691399549837156239786231362112148914687724325416768262058486101761972044802628459748878200584371058300150212485731451700436345975266860685549673168984700174294811561393162860595319582236734968601457003780816977537443267217411297266600994916897237305128142313335280264655603445636393371224354539882875937093696844430903", + "DELTA": "32816484171372208266594641116109072545171919234551585018140151846920408763078147655907777031259225522515086979967895258126318315788662577171150780535509410112003001556402222994276811926864642497249250763185467678044678144507739529818566125668667424447792097244624010084189629269472698722402896445274092470014229247479740671263651727480322483037149584904549203417226525624083290572692241241259382947122018271686649224741832992966652878170311798126004447080305528487720923103595513611363001766063956060990267107048028416069435287244770875463867263571308182619338433913487209319707428378896314619624990311543563016697299", + "2": "36428320569485697540634597755814766104888687488985202673924762266313135133244610404742081973550848160712054769198012193456278135847215508952327879544434490828380496286187725750283788811367824465072001959950807751252194618152990469069074061195618692339915840384087350671392595652921761835083158086795163935060896053332506433434451836095710383871272788002621913967538399141417857031787255744141437237474972197102809365346359345477248611632307159641948507043668113827177494748159094045928919209335044052792843664865311991178972383241855607627188111601119780878072683890170539599447876998109080150992209773901144245398001"}, + "predicate": {"attr_name": "age", "p_type": "GE", "value": 18}}]}, + "non_revoc_proof": None}, "schema_seq_no": 1, "revoc_reg_seq_no": None, "issuer_did": "did"}}, + "aggregated_proof": {"c_hash": "33103550379681684069592829341967479618752165928802550870585275205292715916069", + "c_list": [ + [1, 121, 77, 5, 144, 154, 14, 192, 190, 190, 145, 180, 128, 71, 22, 60, 168, 20, 46, + 163, 139, 194, 71, 165, 220, 188, 121, 76, 25, 146, 231, 114, 65, 54, 69, 68, 19, 200, + 250, 192, 47, 123, 157, 132, 74, 50, 28, 69, 226, 195, 243, 118, 45, 63, 237, 197, + 216, 202, 206, 101, 33, 56, 225, 200, 128, 3, 89, 12, 182, 38, 113, 221, 165, 119, + 228, 201, 156, 201, 172, 136, 59, 64, 51, 72, 164, 198, 49, 228, 223, 117, 80, 64, + 166, 226, 37, 8, 29, 146, 186, 80, 210, 119, 76, 252, 4, 255, 62, 218, 112, 163, 164, + 147, 247, 190, 108, 76, 140, 191, 76, 217, 214, 184, 152, 179, 193, 149, 15, 70, 197, + 46, 90, 60, 255, 247, 197, 219, 252, 73, 76, 0, 125, 104, 114, 22, 182, 161, 110, 36, + 162, 103, 27, 42, 88, 18, 161, 237, 198, 43, 177, 189, 181, 86, 135, 207, 71, 114, 0, + 26, 175, 12, 199, 125, 25, 124, 178, 87, 36, 208, 251, 15, 191, 127, 202, 148, 152, + 43, 142, 92, 191, 7, 89, 153, 130, 195, 223, 248, 176, 109, 97, 164, 126, 162, 181, + 124, 237, 130, 155, 197, 66, 59, 40, 197, 72, 84, 32, 100, 64, 55, 227, 60, 214, 143, + 200, 200, 89, 115, 236, 172, 145, 56, 100, 73, 20, 242, 233, 95, 130, 58, 112, 153, + 120, 115, 119, 42, 199, 30, 205, 88, 223, 42, 196, 184, 41, 19, 100, 19, 244], + [1, 225, 103, 238, 42, 147, 91, 191, 110, 69, 154, 53, 57, 156, 124, 43, 174, 155, 76, + 202, 193, 98, 128, 38, 207, 126, 66, 70, 161, 96, 109, 127, 174, 44, 203, 198, 177, + 238, 118, 117, 89, 227, 170, 155, 44, 251, 35, 119, 219, 29, 100, 173, 26, 144, 95, + 50, 177, 4, 40, 234, 117, 174, 210, 192, 172, 57, 160, 198, 42, 199, 212, 243, 240, + 114, 59, 91, 207, 68, 57, 38, 198, 2, 73, 18, 16, 209, 182, 145, 206, 71, 17, 69, 222, + 49, 36, 120, 72, 117, 169, 107, 238, 208, 235, 216, 24, 183, 201, 81, 15, 83, 242, 45, + 136, 184, 166, 26, 142, 136, 228, 58, 229, 235, 88, 169, 238, 134, 205, 96, 85, 9, + 122, 53, 147, 100, 183, 114, 92, 54, 125, 178, 125, 75, 127, 116, 50, 88, 109, 152, + 22, 4, 121, 252, 190, 18, 190, 130, 143, 138, 59, 231, 38, 131, 176, 54, 19, 194, 218, + 67, 144, 122, 91, 43, 86, 73, 233, 48, 193, 30, 183, 183, 191, 238, 216, 167, 101, 28, + 185, 43, 118, 64, 242, 16, 62, 239, 177, 27, 109, 144, 67, 221, 175, 202, 4, 92, 130, + 74, 24, 20, 151, 15, 227, 225, 142, 71, 145, 46, 192, 248, 87, 57, 183, 142, 253, 52, + 20, 56, 153, 220, 234, 25, 67, 116, 225, 179, 211, 116, 161, 37, 64, 34, 48, 155, 1, + 1, 159, 157, 37, 31, 202, 19, 229, 152, 23, 138, 183, 126, 55], + [1, 38, 181, 193, 191, 72, 2, 239, 34, 83, 49, 36, 179, 160, 82, 112, 172, 98, 255, 63, + 60, 22, 177, 249, 67, 215, 220, 198, 181, 7, 49, 254, 133, 243, 221, 214, 47, 64, 229, + 82, 11, 94, 175, 57, 86, 152, 229, 192, 184, 96, 136, 116, 226, 123, 128, 217, 23, + 244, 19, 204, 36, 44, 123, 208, 88, 24, 217, 120, 145, 139, 25, 233, 227, 5, 119, 90, + 47, 147, 1, 115, 92, 39, 119, 194, 167, 17, 229, 39, 163, 167, 237, 14, 116, 234, 106, + 252, 216, 54, 33, 233, 21, 54, 183, 130, 144, 161, 177, 142, 177, 240, 51, 73, 21, + 202, 188, 103, 244, 153, 204, 219, 123, 231, 139, 135, 189, 155, 143, 28, 4, 180, 44, + 148, 0, 27, 103, 26, 13, 203, 31, 32, 166, 67, 84, 87, 23, 72, 234, 236, 20, 1, 84, + 70, 86, 76, 192, 164, 235, 124, 86, 128, 78, 230, 119, 155, 95, 121, 125, 20, 244, + 181, 121, 250, 169, 9, 67, 85, 213, 177, 139, 111, 187, 183, 114, 165, 249, 177, 161, + 181, 175, 46, 226, 66, 86, 84, 124, 86, 69, 143, 217, 158, 161, 30, 107, 133, 44, 239, + 89, 209, 24, 150, 1, 238, 122, 144, 138, 179, 121, 114, 90, 13, 212, 209, 60, 126, 37, + 62, 177, 180, 131, 222, 168, 2, 201, 156, 169, 220, 224, 53, 8, 203, 220, 215, 163, + 104, 195, 184, 73, 35, 241, 182, 177, 80, 41, 253, 230, 90, 173], + [1, 32, 145, 96, 219, 241, 190, 19, 195, 129, 219, 50, 148, 152, 107, 12, 189, 225, + 103, 171, 149, 252, 193, 243, 136, 132, 195, 44, 19, 20, 247, 140, 160, 91, 230, 78, + 31, 242, 85, 213, 65, 185, 1, 91, 12, 69, 118, 80, 26, 135, 102, 131, 4, 108, 130, + 230, 83, 91, 176, 249, 196, 56, 128, 127, 82, 72, 106, 49, 211, 94, 133, 40, 86, 72, + 42, 187, 199, 216, 191, 223, 208, 206, 121, 118, 15, 167, 255, 228, 57, 206, 158, 217, + 64, 205, 212, 178, 8, 248, 129, 183, 221, 98, 70, 54, 37, 55, 47, 81, 120, 59, 186, + 238, 165, 0, 70, 173, 137, 193, 232, 180, 125, 211, 237, 182, 249, 191, 173, 107, 129, + 164, 148, 231, 116, 225, 66, 66, 71, 156, 39, 248, 164, 253, 234, 140, 205, 177, 140, + 117, 47, 21, 15, 242, 31, 113, 118, 91, 143, 89, 213, 86, 143, 135, 21, 46, 35, 199, + 214, 107, 111, 65, 65, 19, 26, 171, 130, 16, 19, 102, 145, 210, 210, 61, 51, 169, 148, + 169, 118, 182, 106, 107, 253, 100, 214, 232, 52, 103, 180, 96, 249, 254, 71, 6, 11, + 119, 48, 129, 213, 223, 205, 93, 20, 117, 26, 187, 32, 151, 212, 137, 203, 17, 237, + 208, 150, 72, 23, 225, 235, 122, 188, 34, 105, 115, 0, 160, 168, 251, 191, 22, 242, + 238, 207, 74, 142, 154, 66, 94, 149, 191, 215, 194, 134, 6, 165, 244, 167, 233, 241], + [1, 207, 77, 250, 146, 127, 242, 229, 44, 172, 182, 201, 183, 242, 32, 242, 182, 129, + 233, 10, 8, 180, 23, 191, 163, 21, 238, 158, 5, 27, 216, 146, 253, 173, 127, 99, 95, + 168, 209, 132, 242, 196, 242, 34, 25, 25, 249, 211, 51, 236, 164, 153, 175, 61, 65, + 150, 82, 251, 174, 102, 186, 47, 195, 82, 44, 90, 252, 184, 74, 89, 251, 177, 254, + 108, 151, 136, 230, 220, 93, 224, 173, 247, 244, 116, 132, 59, 170, 215, 194, 30, 87, + 84, 166, 147, 57, 156, 201, 207, 132, 203, 222, 191, 253, 15, 19, 228, 173, 81, 156, + 4, 51, 121, 227, 159, 50, 18, 148, 129, 205, 42, 42, 227, 252, 138, 62, 176, 115, 227, + 253, 52, 125, 110, 178, 167, 132, 244, 14, 116, 195, 194, 172, 44, 45, 63, 38, 121, + 215, 136, 68, 230, 21, 108, 133, 159, 197, 179, 94, 78, 233, 107, 236, 114, 92, 165, + 248, 22, 124, 161, 23, 142, 236, 224, 175, 233, 134, 25, 97, 150, 131, 61, 220, 203, + 104, 154, 199, 247, 146, 47, 205, 56, 209, 0, 133, 132, 18, 103, 136, 8, 202, 37, 29, + 100, 105, 12, 232, 74, 33, 6, 255, 202, 96, 170, 52, 229, 244, 4, 235, 2, 201, 125, + 86, 168, 179, 224, 130, 81, 54, 221, 185, 184, 187, 141, 0, 114, 98, 38, 70, 225, 228, + 60, 157, 53, 210, 238, 60, 216, 215, 154, 48, 73, 3, 157, 192, 245, 81, 170, 49], + [1, 3, 244, 229, 158, 71, 18, 146, 198, 202, 27, 2, 231, 37, 13, 145, 243, 84, 112, + 220, 61, 174, 4, 175, 104, 200, 64, 146, 193, 20, 174, 126, 42, 157, 168, 76, 165, 21, + 50, 216, 82, 211, 180, 73, 244, 54, 227, 200, 19, 157, 25, 228, 81, 37, 64, 201, 19, + 138, 175, 50, 246, 169, 11, 45, 74, 194, 131, 236, 127, 177, 41, 242, 130, 55, 112, + 182, 98, 22, 99, 48, 153, 83, 161, 250, 65, 89, 3, 97, 6, 5, 171, 54, 223, 87, 98, + 103, 23, 200, 212, 177, 140, 155, 151, 252, 125, 45, 176, 55, 92, 41, 56, 2, 252, 32, + 149, 60, 3, 168, 209, 193, 23, 168, 230, 182, 72, 193, 230, 224, 5, 15, 58, 63, 93, + 196, 33, 93, 76, 188, 30, 70, 31, 136, 64, 204, 223, 2, 230, 210, 243, 255, 135, 193, + 52, 132, 248, 160, 22, 18, 164, 71, 77, 80, 112, 229, 120, 116, 210, 225, 2, 19, 139, + 35, 0, 214, 5, 246, 9, 106, 136, 204, 0, 148, 97, 21, 222, 153, 57, 177, 162, 11, 243, + 252, 7, 242, 34, 239, 245, 50, 104, 74, 221, 92, 73, 13, 142, 10, 184, 250, 246, 167, + 240, 46, 230, 86, 207, 181, 12, 133, 81, 119, 143, 164, 88, 114, 223, 243, 179, 208, + 175, 84, 161, 27, 11, 225, 36, 37, 177, 112, 85, 81, 184, 163, 223, 159, 36, 9, 247, + 20, 13, 230, 215, 108, 117, 35, 99, 117, 211]]}, "requested_proof": { + "revealed_attrs": { + "attr1_uuid": ["claim::277478db-bf57-42c3-8530-b1b13cfe0bfd", "Alex", + "1139481716457488690172217916278103335"] + }, "unrevealed_attrs": {}, + "self_attested_attrs": {}, + "predicates": { + "predicate1_uuid": "claim::277478db-bf57-42c3-8530-b1b13cfe0bfd" + } + } + } + + valid = await verifier_verify_proof(json.dumps(proof_req), json.dumps(proof), + json.dumps(schemas), json.dumps(claim_defs), "{}") + + assert valid + + +@pytest.mark.asyncio +async def test_verifier_verify_proof_works_for_proof_does_not_correspond_to_request(): + proof_req = anoncreds.get_proof_req(180) + claim_def = anoncreds.get_claim_def() + + schemas = { + "claim::277478db-bf57-42c3-8530-b1b13cfe0bfd": anoncreds.get_gvt_schema_json(1) + } + claim_defs = { + "claim::277478db-bf57-42c3-8530-b1b13cfe0bfd": claim_def + } + proof = { + "proofs": + { + "claim::277478db-bf57-42c3-8530-b1b13cfe0bfd": + { + "proof": + { + "primary_proof": { + "eq_proof": {"revealed_attrs": {"name": "1139481716457488690172217916278103335"}, + "a_prime": "47629821806628155353444789773246165920681315271529392722265555946090524267165563309836167110610840740533588118152308411732923636370660640410661034994521654033599863817144282118006097899736622728860229305231675970853294584911572355833537271010861501353858292189045263114095480601737776505186511389129055847562085611741257601964074827979121349153316235245772819207422031038042586202074331681302501661153569340935741290924699468188826629478130140797677338573924284871118002193526319478550852287453975107498037063076866410320160118555629090040954555043934303307652160345244864713226315470541231435958298648179413077988340", + "e": "13427639393364185909415877973872458621259927563729922146828001652769380799419438410309469022979920689628523901764614163117469683925816443", + "v": "852136445143816932026946294488424887907102968158908948827421962603492187508454543239422067899916472317305416590471170842186669606584356963437132366711335927890209765986844538775191207999204354235774464468525274918097404114453069375363594310105209141774763909570100638835926337238009617444858777301355087706167735590386774813901740600054753028260344014744801229032610106838480523182317262113911183640784111960909501662169298536941919854667754097841344375972975021196106884215734228415868248724905018661498061287694439466570946597514142085096419985189064172035527690786158872698717583830848410994616274586162550376126607414773916066374234063208380831144157533076866210628625236440222547584539349936639548061601416341705483504386186280800509889531835172071717956251546280392606775903107774727736794828168898273891724336881907672405328368540895104468091907771325910937575557566831844131159128453840354307814975621978196047820", + "m": { + "age": "1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662", + "height": "7064132689652704067914104576495132313294680087958177180391515757079548676035445873279966783996928425154050462229933823707574545166617858646442019030600136959459527533262821184869", + "sex": "16084497853957041205729191269508720470626311156190485518484640641677445098603656354458362520541393995692536218820724164533958162674375198846036330444513484319280148335515891811530"}, + "m1": "154906224259819061652290487122980839849626068919893070220438585977323162319993111920906032317552959103520053742608858935542877608981244065301675821390065831113115709272412144796159984624494428122971995557415296140268002332169405587907128359886810433617416529821500995701094400375272097687818064435577784795275", + "m2": "13805395408072590464827983892588030341708765524663545700917462089376137940485022437657208204460048097312372685954050370540389593952001973312378647790917367330461398089529292217752"}, + "ge_proofs": [{"u": { + "1": "7698818972783845439601187851976452936638792889455287252542709653271706844173743185409084669157965935169942655008606334521674712818637940377261656468700786810566551698412412949418", + "0": "11703047052430512223413711314521545616119146623040600935686474696241801697819280425232876917607198335376453682738553665221410353412906194951254558355994401995990233992518110582450", + "3": "13210777821918317858818819091924507295018522783042111457450035423463340571245465760486275059291363621513532153389441883097799049597687545496359999443320001567152794884095192951040", + "2": "15219471780524079156861690098171693383497641272226737821992208834301871102152362116211452788300889697214391366996966539871625433480959011635688106136537800706217506402845296449689"}, + "r": { + "1": "46043242109380749151527145850513330956077996622769158245225343392397735706292106535150958053995712629189143692293204979798837951212291825184346767969751978730000071952944305252032332015837054475531407691352179423131405515518588355918925056889302269768343499864256747177988825578647189563088068257214198650437730618330249172716051559993880468542083352885474175039320848153156858562341041960950299312991459780503345784440261679263045723337629951517601461685539857683027034345542399365706329805317943096391758978877658949910614447086409173234155028671453929715706057153381022697673192590033507204548864311227048268516889390503318015295207078022755834130221198717787608473222789491216667698651180077661375273569115943192", + "0": "135472587547410377947826119498467634347118057359097899596599164976338466445104141784869016998150489852448547539824768048351359572626675997498079394825940306636285481821620973655797996638210760710325933304918452142858879806106214845499670718704532018129553348815327362843246706518826311676917538452317818631484884032929252959289913274829848084561421467966320595980172006456003183536232790787521924655750157145207798486087511869939940023266736153366338179116840490184005332351004990854691988404031259910319601383696749511809898297656135548118786342107367065232798999979296280467063561892962526945512167505847049907450058650930480352253243357594344686769208712964458923557777584158831146374282687397585726706489164423632", + "DELTA": "93540839493959971552865423901789226093328763011922445919928571946113703515842729132879472109395228387208764738970926484618949870591214627692618668077375153559192701474693025462226656116549337248146652482501255820930607033869432220667968682424554711616471973627651716863421554516577716366331699848682958681216261888139409101603059124344125075525791543312721162515584942523419876134808829569829529457617639955678189490257208141837196965948342373022812790844435050648360150869293836349223060722858500537182872294143846213258360218898475766641125493477502149553491502593654061863323857297998048614447925371606038801933864960337435890254277043261512846682042139570000962051463878026338583242360548041329046695667868842400", + "3": "1227675452527605924725300993571504188580051470857656204064614533296779844072852823820754766175236321050062349182891221840452517985644028521499240739391613871973822807731772613052644168369405390658793869751915172749739844553410726807277698347769400977274750672880389943392076308065414059539317340070691852044062594715307024113666759844200606183662256825096857658837519571386467051003466014468855293015652584667669998830524947537781865745830650392641812221679438090257444660715937570193098993118585554478799821072396238689063767016402460690760792908977364175126682041704095200572282644311025594681667826054722587271200221036938804846621444065128275082392082327596239358623150786484106872933657139420542280145197712634108", + "2": "596248147592834822582469335300585333722415132713749620075902332764163096347819006925876158892694742461036531935093982309708492066217459300117157420442081698140277277546563570823996272914068575482008392971932777453900260626542725308060927710122631763045025742980634216666560934260634907599194353151523256914796667535940073668465664206971169038864484235442207811974981191879443614478897291543702607764944403808380921189291059195014621592027660463072969363556421687131446107696579365265893962197300447027501604372738056016734644378437907931412654753728514905671605635291285742886484416973884856055084605172305967034292646171874483670469193852404511746786039743401185954843446037600121496137915619789351744485264614840070"}, + "mj": "1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662", + "alpha": "76727612740067576380015106087224381023260815407331375101920043509817863645705120013304683427627332447210083684516403565749916480947649443674885388155460323163682547865307733144184097845709556309570345707127872162476432029772452433292049079349274445907295491125915363620615679995457134810061392296263970553630102299601689685622244925494554558218277670233361938142224820526392365740420502452466959099546877778248089664282581792213376636587293479012783947088070052463503335266180110771978445892744225891676396288437005847308189508347446490710626231658457908472341606549292437553353163031111068977301305043175839949352742711874426231072729977019365761072816602400121302646283352164756787266537474728685656685493249314400351742964904006326192403855909148605656818024621453179832395687665671245528217931951331393482249182516107670379946496778373", + "t": { + "1": "37203689290881948278188715497642400459048942241931994079434400288578680362970117779048886269388440270597283202033458042171954610700745461571112086648991639439510380585728148682202768590972068041537531136529323260832899360551065706810590032715173070285762675403853992183366951113799098912676809373169763887110420539387555392787590966452796271491986622992160642135480293110112269570862265489120557014181468118619500321000966443141863893743211690388599242584469856365803370202569641902205925191670838354052104480074127555862332399641076324738839120815544432811566503174551735326387678621283249883091766325861497740614317", + "3": "58486787977689017034592833190899828017343431922483563651969628402499947729293364026001243898136737211851089198526360764391403150763769829047179796728616126204105160762333590343947446892105646111520243793053992399512412375936746396187319527051818920531870855183738837254656664620975569939859368862778444291640228229744805843388153451336792379036403300211151424879060241580540910888241769468335914016289938374111481091198264912969768783884602931940994543804730631920434719776196148182987249363641941951160704928605829395517074202388967815738516252602903999010405305463910751219873354588685197134114358234107748126140977", + "0": "60771874648036182010335841594233428920565254732600738082343398028553347795361460295011584446745121430144172025428394361648540904134739046923992231536160801306934272250969829886396340824213814702904457884984387666505055153957942221822193548673145705543973635530652570436109428474727638128773540793530691399549837156239786231362112148914687724325416768262058486101761972044802628459748878200584371058300150212485731451700436345975266860685549673168984700174294811561393162860595319582236734968601457003780816977537443267217411297266600994916897237305128142313335280264655603445636393371224354539882875937093696844430903", + "DELTA": "32816484171372208266594641116109072545171919234551585018140151846920408763078147655907777031259225522515086979967895258126318315788662577171150780535509410112003001556402222994276811926864642497249250763185467678044678144507739529818566125668667424447792097244624010084189629269472698722402896445274092470014229247479740671263651727480322483037149584904549203417226525624083290572692241241259382947122018271686649224741832992966652878170311798126004447080305528487720923103595513611363001766063956060990267107048028416069435287244770875463867263571308182619338433913487209319707428378896314619624990311543563016697299", + "2": "36428320569485697540634597755814766104888687488985202673924762266313135133244610404742081973550848160712054769198012193456278135847215508952327879544434490828380496286187725750283788811367824465072001959950807751252194618152990469069074061195618692339915840384087350671392595652921761835083158086795163935060896053332506433434451836095710383871272788002621913967538399141417857031787255744141437237474972197102809365346359345477248611632307159641948507043668113827177494748159094045928919209335044052792843664865311991178972383241855607627188111601119780878072683890170539599447876998109080150992209773901144245398001"}, + "predicate": {"attr_name": "age", "p_type": "GE", "value": 18}}]}, + "non_revoc_proof": None}, "schema_seq_no": 1, "revoc_reg_seq_no": None, + "issuer_did": "did"}}, + "aggregated_proof": {"c_hash": "33103550379681684069592829341967479618752165928802550870585275205292715916069", + "c_list": [ + [1, 121, 77, 5, 144, 154, 14, 192, 190, 190, 145, 180, 128, 71, 22, 60, 168, 20, 46, + 163, 139, 194, 71, 165, 220, 188, 121, 76, 25, 146, 231, 114, 65, 54, 69, 68, 19, 200, + 250, 192, 47, 123, 157, 132, 74, 50, 28, 69, 226, 195, 243, 118, 45, 63, 237, 197, + 216, 202, 206, 101, 33, 56, 225, 200, 128, 3, 89, 12, 182, 38, 113, 221, 165, 119, + 228, 201, 156, 201, 172, 136, 59, 64, 51, 72, 164, 198, 49, 228, 223, 117, 80, 64, + 166, 226, 37, 8, 29, 146, 186, 80, 210, 119, 76, 252, 4, 255, 62, 218, 112, 163, 164, + 147, 247, 190, 108, 76, 140, 191, 76, 217, 214, 184, 152, 179, 193, 149, 15, 70, 197, + 46, 90, 60, 255, 247, 197, 219, 252, 73, 76, 0, 125, 104, 114, 22, 182, 161, 110, 36, + 162, 103, 27, 42, 88, 18, 161, 237, 198, 43, 177, 189, 181, 86, 135, 207, 71, 114, 0, + 26, 175, 12, 199, 125, 25, 124, 178, 87, 36, 208, 251, 15, 191, 127, 202, 148, 152, + 43, 142, 92, 191, 7, 89, 153, 130, 195, 223, 248, 176, 109, 97, 164, 126, 162, 181, + 124, 237, 130, 155, 197, 66, 59, 40, 197, 72, 84, 32, 100, 64, 55, 227, 60, 214, 143, + 200, 200, 89, 115, 236, 172, 145, 56, 100, 73, 20, 242, 233, 95, 130, 58, 112, 153, + 120, 115, 119, 42, 199, 30, 205, 88, 223, 42, 196, 184, 41, 19, 100, 19, 244], + [1, 225, 103, 238, 42, 147, 91, 191, 110, 69, 154, 53, 57, 156, 124, 43, 174, 155, 76, + 202, 193, 98, 128, 38, 207, 126, 66, 70, 161, 96, 109, 127, 174, 44, 203, 198, 177, + 238, 118, 117, 89, 227, 170, 155, 44, 251, 35, 119, 219, 29, 100, 173, 26, 144, 95, + 50, 177, 4, 40, 234, 117, 174, 210, 192, 172, 57, 160, 198, 42, 199, 212, 243, 240, + 114, 59, 91, 207, 68, 57, 38, 198, 2, 73, 18, 16, 209, 182, 145, 206, 71, 17, 69, 222, + 49, 36, 120, 72, 117, 169, 107, 238, 208, 235, 216, 24, 183, 201, 81, 15, 83, 242, 45, + 136, 184, 166, 26, 142, 136, 228, 58, 229, 235, 88, 169, 238, 134, 205, 96, 85, 9, + 122, 53, 147, 100, 183, 114, 92, 54, 125, 178, 125, 75, 127, 116, 50, 88, 109, 152, + 22, 4, 121, 252, 190, 18, 190, 130, 143, 138, 59, 231, 38, 131, 176, 54, 19, 194, 218, + 67, 144, 122, 91, 43, 86, 73, 233, 48, 193, 30, 183, 183, 191, 238, 216, 167, 101, 28, + 185, 43, 118, 64, 242, 16, 62, 239, 177, 27, 109, 144, 67, 221, 175, 202, 4, 92, 130, + 74, 24, 20, 151, 15, 227, 225, 142, 71, 145, 46, 192, 248, 87, 57, 183, 142, 253, 52, + 20, 56, 153, 220, 234, 25, 67, 116, 225, 179, 211, 116, 161, 37, 64, 34, 48, 155, 1, + 1, 159, 157, 37, 31, 202, 19, 229, 152, 23, 138, 183, 126, 55], + [1, 38, 181, 193, 191, 72, 2, 239, 34, 83, 49, 36, 179, 160, 82, 112, 172, 98, 255, 63, + 60, 22, 177, 249, 67, 215, 220, 198, 181, 7, 49, 254, 133, 243, 221, 214, 47, 64, 229, + 82, 11, 94, 175, 57, 86, 152, 229, 192, 184, 96, 136, 116, 226, 123, 128, 217, 23, + 244, 19, 204, 36, 44, 123, 208, 88, 24, 217, 120, 145, 139, 25, 233, 227, 5, 119, 90, + 47, 147, 1, 115, 92, 39, 119, 194, 167, 17, 229, 39, 163, 167, 237, 14, 116, 234, 106, + 252, 216, 54, 33, 233, 21, 54, 183, 130, 144, 161, 177, 142, 177, 240, 51, 73, 21, + 202, 188, 103, 244, 153, 204, 219, 123, 231, 139, 135, 189, 155, 143, 28, 4, 180, 44, + 148, 0, 27, 103, 26, 13, 203, 31, 32, 166, 67, 84, 87, 23, 72, 234, 236, 20, 1, 84, + 70, 86, 76, 192, 164, 235, 124, 86, 128, 78, 230, 119, 155, 95, 121, 125, 20, 244, + 181, 121, 250, 169, 9, 67, 85, 213, 177, 139, 111, 187, 183, 114, 165, 249, 177, 161, + 181, 175, 46, 226, 66, 86, 84, 124, 86, 69, 143, 217, 158, 161, 30, 107, 133, 44, 239, + 89, 209, 24, 150, 1, 238, 122, 144, 138, 179, 121, 114, 90, 13, 212, 209, 60, 126, 37, + 62, 177, 180, 131, 222, 168, 2, 201, 156, 169, 220, 224, 53, 8, 203, 220, 215, 163, + 104, 195, 184, 73, 35, 241, 182, 177, 80, 41, 253, 230, 90, 173], + [1, 32, 145, 96, 219, 241, 190, 19, 195, 129, 219, 50, 148, 152, 107, 12, 189, 225, + 103, 171, 149, 252, 193, 243, 136, 132, 195, 44, 19, 20, 247, 140, 160, 91, 230, 78, + 31, 242, 85, 213, 65, 185, 1, 91, 12, 69, 118, 80, 26, 135, 102, 131, 4, 108, 130, + 230, 83, 91, 176, 249, 196, 56, 128, 127, 82, 72, 106, 49, 211, 94, 133, 40, 86, 72, + 42, 187, 199, 216, 191, 223, 208, 206, 121, 118, 15, 167, 255, 228, 57, 206, 158, 217, + 64, 205, 212, 178, 8, 248, 129, 183, 221, 98, 70, 54, 37, 55, 47, 81, 120, 59, 186, + 238, 165, 0, 70, 173, 137, 193, 232, 180, 125, 211, 237, 182, 249, 191, 173, 107, 129, + 164, 148, 231, 116, 225, 66, 66, 71, 156, 39, 248, 164, 253, 234, 140, 205, 177, 140, + 117, 47, 21, 15, 242, 31, 113, 118, 91, 143, 89, 213, 86, 143, 135, 21, 46, 35, 199, + 214, 107, 111, 65, 65, 19, 26, 171, 130, 16, 19, 102, 145, 210, 210, 61, 51, 169, 148, + 169, 118, 182, 106, 107, 253, 100, 214, 232, 52, 103, 180, 96, 249, 254, 71, 6, 11, + 119, 48, 129, 213, 223, 205, 93, 20, 117, 26, 187, 32, 151, 212, 137, 203, 17, 237, + 208, 150, 72, 23, 225, 235, 122, 188, 34, 105, 115, 0, 160, 168, 251, 191, 22, 242, + 238, 207, 74, 142, 154, 66, 94, 149, 191, 215, 194, 134, 6, 165, 244, 167, 233, 241], + [1, 207, 77, 250, 146, 127, 242, 229, 44, 172, 182, 201, 183, 242, 32, 242, 182, 129, + 233, 10, 8, 180, 23, 191, 163, 21, 238, 158, 5, 27, 216, 146, 253, 173, 127, 99, 95, + 168, 209, 132, 242, 196, 242, 34, 25, 25, 249, 211, 51, 236, 164, 153, 175, 61, 65, + 150, 82, 251, 174, 102, 186, 47, 195, 82, 44, 90, 252, 184, 74, 89, 251, 177, 254, + 108, 151, 136, 230, 220, 93, 224, 173, 247, 244, 116, 132, 59, 170, 215, 194, 30, 87, + 84, 166, 147, 57, 156, 201, 207, 132, 203, 222, 191, 253, 15, 19, 228, 173, 81, 156, + 4, 51, 121, 227, 159, 50, 18, 148, 129, 205, 42, 42, 227, 252, 138, 62, 176, 115, 227, + 253, 52, 125, 110, 178, 167, 132, 244, 14, 116, 195, 194, 172, 44, 45, 63, 38, 121, + 215, 136, 68, 230, 21, 108, 133, 159, 197, 179, 94, 78, 233, 107, 236, 114, 92, 165, + 248, 22, 124, 161, 23, 142, 236, 224, 175, 233, 134, 25, 97, 150, 131, 61, 220, 203, + 104, 154, 199, 247, 146, 47, 205, 56, 209, 0, 133, 132, 18, 103, 136, 8, 202, 37, 29, + 100, 105, 12, 232, 74, 33, 6, 255, 202, 96, 170, 52, 229, 244, 4, 235, 2, 201, 125, + 86, 168, 179, 224, 130, 81, 54, 221, 185, 184, 187, 141, 0, 114, 98, 38, 70, 225, 228, + 60, 157, 53, 210, 238, 60, 216, 215, 154, 48, 73, 3, 157, 192, 245, 81, 170, 49], + [1, 3, 244, 229, 158, 71, 18, 146, 198, 202, 27, 2, 231, 37, 13, 145, 243, 84, 112, + 220, 61, 174, 4, 175, 104, 200, 64, 146, 193, 20, 174, 126, 42, 157, 168, 76, 165, 21, + 50, 216, 82, 211, 180, 73, 244, 54, 227, 200, 19, 157, 25, 228, 81, 37, 64, 201, 19, + 138, 175, 50, 246, 169, 11, 45, 74, 194, 131, 236, 127, 177, 41, 242, 130, 55, 112, + 182, 98, 22, 99, 48, 153, 83, 161, 250, 65, 89, 3, 97, 6, 5, 171, 54, 223, 87, 98, + 103, 23, 200, 212, 177, 140, 155, 151, 252, 125, 45, 176, 55, 92, 41, 56, 2, 252, 32, + 149, 60, 3, 168, 209, 193, 23, 168, 230, 182, 72, 193, 230, 224, 5, 15, 58, 63, 93, + 196, 33, 93, 76, 188, 30, 70, 31, 136, 64, 204, 223, 2, 230, 210, 243, 255, 135, 193, + 52, 132, 248, 160, 22, 18, 164, 71, 77, 80, 112, 229, 120, 116, 210, 225, 2, 19, 139, + 35, 0, 214, 5, 246, 9, 106, 136, 204, 0, 148, 97, 21, 222, 153, 57, 177, 162, 11, 243, + 252, 7, 242, 34, 239, 245, 50, 104, 74, 221, 92, 73, 13, 142, 10, 184, 250, 246, 167, + 240, 46, 230, 86, 207, 181, 12, 133, 81, 119, 143, 164, 88, 114, 223, 243, 179, 208, + 175, 84, 161, 27, 11, 225, 36, 37, 177, 112, 85, 81, 184, 163, 223, 159, 36, 9, 247, + 20, 13, 230, 215, 108, 117, 35, 99, 117, 211]]}, "requested_proof": { + "revealed_attrs": {"attr1_uuid": ["claim::277478db-bf57-42c3-8530-b1b13cfe0bfd", "Alex", + "1139481716457488690172217916278103335"]}, "unrevealed_attrs": {}, + "self_attested_attrs": {}, + "predicates": {"predicate1_uuid": "claim::277478db-bf57-42c3-8530-b1b13cfe0bfd"}}} + + with pytest.raises(IndyError) as e: + await verifier_verify_proof(json.dumps(proof_req), json.dumps(proof), + json.dumps(schemas), json.dumps(claim_defs), "{}") + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_verifier_verify_proof_works_for_wrong_proof(): + proof_req = anoncreds.get_proof_req() + claim_def = anoncreds.get_claim_def() + + schemas = { + "claim::277478db-bf57-42c3-8530-b1b13cfe0bfd": anoncreds.get_gvt_schema_json(1) + } + claim_defs = { + "claim::277478db-bf57-42c3-8530-b1b13cfe0bfd": claim_def + } + proof = { + "proofs": + { + "claim::277478db-bf57-42c3-8530-b1b13cfe0bfd": + { + "proof": + { + "primary_proof": { + "eq_proof": {"revealed_attrs": {"name": "1139481716457488690172217916278103337"}, + "a_prime": "47629821806628155353444789773246165920681315271529392722265555946090524267165563309836167110610840740533588118152308411732923636370660640410661034994521654033599863817144282118006097899736622728860229305231675970853294584911572355833537271010861501353858292189045263114095480601737776505186511389129055847562085611741257601964074827979121349153316235245772819207422031038042586202074331681302501661153569340935741290924699468188826629478130140797677338573924284871118002193526319478550852287453975107498037063076866410320160118555629090040954555043934303307652160345244864713226315470541231435958298648179413077988340", + "e": "13427639393364185909415877973872458621259927563729922146828001652769380799419438410309469022979920689628523901764614163117469683925816443", + "v": "852136445143816932026946294488424887907102968158908948827421962603492187508454543239422067899916472317305416590471170842186669606584356963437132366711335927890209765986844538775191207999204354235774464468525274918097404114453069375363594310105209141774763909570100638835926337238009617444858777301355087706167735590386774813901740600054753028260344014744801229032610106838480523182317262113911183640784111960909501662169298536941919854667754097841344375972975021196106884215734228415868248724905018661498061287694439466570946597514142085096419985189064172035527690786158872698717583830848410994616274586162550376126607414773916066374234063208380831144157533076866210628625236440222547584539349936639548061601416341705483504386186280800509889531835172071717956251546280392606775903107774727736794828168898273891724336881907672405328368540895104468091907771325910937575557566831844131159128453840354307814975621978196047820", + "m": { + "age": "1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662", + "height": "7064132689652704067914104576495132313294680087958177180391515757079548676035445873279966783996928425154050462229933823707574545166617858646442019030600136959459527533262821184869", + "sex": "16084497853957041205729191269508720470626311156190485518484640641677445098603656354458362520541393995692536218820724164533958162674375198846036330444513484319280148335515891811530"}, + "m1": "154906224259819061652290487122980839849626068919893070220438585977323162319993111920906032317552959103520053742608858935542877608981244065301675821390065831113115709272412144796159984624494428122971995557415296140268002332169405587907128359886810433617416529821500995701094400375272097687818064435577784795275", + "m2": "13805395408072590464827983892588030341708765524663545700917462089376137940485022437657208204460048097312372685954050370540389593952001973312378647790917367330461398089529292217752"}, + "ge_proofs": [{"u": { + "1": "7698818972783845439601187851976452936638792889455287252542709653271706844173743185409084669157965935169942655008606334521674712818637940377261656468700786810566551698412412949418", + "0": "11703047052430512223413711314521545616119146623040600935686474696241801697819280425232876917607198335376453682738553665221410353412906194951254558355994401995990233992518110582450", + "3": "13210777821918317858818819091924507295018522783042111457450035423463340571245465760486275059291363621513532153389441883097799049597687545496359999443320001567152794884095192951040", + "2": "15219471780524079156861690098171693383497641272226737821992208834301871102152362116211452788300889697214391366996966539871625433480959011635688106136537800706217506402845296449689"}, + "r": { + "1": "46043242109380749151527145850513330956077996622769158245225343392397735706292106535150958053995712629189143692293204979798837951212291825184346767969751978730000071952944305252032332015837054475531407691352179423131405515518588355918925056889302269768343499864256747177988825578647189563088068257214198650437730618330249172716051559993880468542083352885474175039320848153156858562341041960950299312991459780503345784440261679263045723337629951517601461685539857683027034345542399365706329805317943096391758978877658949910614447086409173234155028671453929715706057153381022697673192590033507204548864311227048268516889390503318015295207078022755834130221198717787608473222789491216667698651180077661375273569115943192", + "0": "135472587547410377947826119498467634347118057359097899596599164976338466445104141784869016998150489852448547539824768048351359572626675997498079394825940306636285481821620973655797996638210760710325933304918452142858879806106214845499670718704532018129553348815327362843246706518826311676917538452317818631484884032929252959289913274829848084561421467966320595980172006456003183536232790787521924655750157145207798486087511869939940023266736153366338179116840490184005332351004990854691988404031259910319601383696749511809898297656135548118786342107367065232798999979296280467063561892962526945512167505847049907450058650930480352253243357594344686769208712964458923557777584158831146374282687397585726706489164423632", + "DELTA": "93540839493959971552865423901789226093328763011922445919928571946113703515842729132879472109395228387208764738970926484618949870591214627692618668077375153559192701474693025462226656116549337248146652482501255820930607033869432220667968682424554711616471973627651716863421554516577716366331699848682958681216261888139409101603059124344125075525791543312721162515584942523419876134808829569829529457617639955678189490257208141837196965948342373022812790844435050648360150869293836349223060722858500537182872294143846213258360218898475766641125493477502149553491502593654061863323857297998048614447925371606038801933864960337435890254277043261512846682042139570000962051463878026338583242360548041329046695667868842400", + "3": "1227675452527605924725300993571504188580051470857656204064614533296779844072852823820754766175236321050062349182891221840452517985644028521499240739391613871973822807731772613052644168369405390658793869751915172749739844553410726807277698347769400977274750672880389943392076308065414059539317340070691852044062594715307024113666759844200606183662256825096857658837519571386467051003466014468855293015652584667669998830524947537781865745830650392641812221679438090257444660715937570193098993118585554478799821072396238689063767016402460690760792908977364175126682041704095200572282644311025594681667826054722587271200221036938804846621444065128275082392082327596239358623150786484106872933657139420542280145197712634108", + "2": "596248147592834822582469335300585333722415132713749620075902332764163096347819006925876158892694742461036531935093982309708492066217459300117157420442081698140277277546563570823996272914068575482008392971932777453900260626542725308060927710122631763045025742980634216666560934260634907599194353151523256914796667535940073668465664206971169038864484235442207811974981191879443614478897291543702607764944403808380921189291059195014621592027660463072969363556421687131446107696579365265893962197300447027501604372738056016734644378437907931412654753728514905671605635291285742886484416973884856055084605172305967034292646171874483670469193852404511746786039743401185954843446037600121496137915619789351744485264614840070"}, + "mj": "1117601261519431120446925325460734824239475567013636538481947258329666056692767097795046086413732472111811628751812987521644198549167671875326968410921589186689138994171774838662", + "alpha": "76727612740067576380015106087224381023260815407331375101920043509817863645705120013304683427627332447210083684516403565749916480947649443674885388155460323163682547865307733144184097845709556309570345707127872162476432029772452433292049079349274445907295491125915363620615679995457134810061392296263970553630102299601689685622244925494554558218277670233361938142224820526392365740420502452466959099546877778248089664282581792213376636587293479012783947088070052463503335266180110771978445892744225891676396288437005847308189508347446490710626231658457908472341606549292437553353163031111068977301305043175839949352742711874426231072729977019365761072816602400121302646283352164756787266537474728685656685493249314400351742964904006326192403855909148605656818024621453179832395687665671245528217931951331393482249182516107670379946496778373", + "t": { + "1": "37203689290881948278188715497642400459048942241931994079434400288578680362970117779048886269388440270597283202033458042171954610700745461571112086648991639439510380585728148682202768590972068041537531136529323260832899360551065706810590032715173070285762675403853992183366951113799098912676809373169763887110420539387555392787590966452796271491986622992160642135480293110112269570862265489120557014181468118619500321000966443141863893743211690388599242584469856365803370202569641902205925191670838354052104480074127555862332399641076324738839120815544432811566503174551735326387678621283249883091766325861497740614317", + "3": "58486787977689017034592833190899828017343431922483563651969628402499947729293364026001243898136737211851089198526360764391403150763769829047179796728616126204105160762333590343947446892105646111520243793053992399512412375936746396187319527051818920531870855183738837254656664620975569939859368862778444291640228229744805843388153451336792379036403300211151424879060241580540910888241769468335914016289938374111481091198264912969768783884602931940994543804730631920434719776196148182987249363641941951160704928605829395517074202388967815738516252602903999010405305463910751219873354588685197134114358234107748126140977", + "0": "60771874648036182010335841594233428920565254732600738082343398028553347795361460295011584446745121430144172025428394361648540904134739046923992231536160801306934272250969829886396340824213814702904457884984387666505055153957942221822193548673145705543973635530652570436109428474727638128773540793530691399549837156239786231362112148914687724325416768262058486101761972044802628459748878200584371058300150212485731451700436345975266860685549673168984700174294811561393162860595319582236734968601457003780816977537443267217411297266600994916897237305128142313335280264655603445636393371224354539882875937093696844430903", + "DELTA": "32816484171372208266594641116109072545171919234551585018140151846920408763078147655907777031259225522515086979967895258126318315788662577171150780535509410112003001556402222994276811926864642497249250763185467678044678144507739529818566125668667424447792097244624010084189629269472698722402896445274092470014229247479740671263651727480322483037149584904549203417226525624083290572692241241259382947122018271686649224741832992966652878170311798126004447080305528487720923103595513611363001766063956060990267107048028416069435287244770875463867263571308182619338433913487209319707428378896314619624990311543563016697299", + "2": "36428320569485697540634597755814766104888687488985202673924762266313135133244610404742081973550848160712054769198012193456278135847215508952327879544434490828380496286187725750283788811367824465072001959950807751252194618152990469069074061195618692339915840384087350671392595652921761835083158086795163935060896053332506433434451836095710383871272788002621913967538399141417857031787255744141437237474972197102809365346359345477248611632307159641948507043668113827177494748159094045928919209335044052792843664865311991178972383241855607627188111601119780878072683890170539599447876998109080150992209773901144245398001"}, + "predicate": {"attr_name": "age", "p_type": "GE", "value": 18}}]}, + "non_revoc_proof": None}, "schema_seq_no": 1, "revoc_reg_seq_no": None, + "issuer_did": "did"}}, + "aggregated_proof": {"c_hash": "33103550379681684069592829341967479618752165928802550870585275205292715916069", + "c_list": [ + [1, 121, 77, 5, 144, 154, 14, 192, 190, 190, 145, 180, 128, 71, 22, 60, 168, 20, 46, + 163, 139, 194, 71, 165, 220, 188, 121, 76, 25, 146, 231, 114, 65, 54, 69, 68, 19, 200, + 250, 192, 47, 123, 157, 132, 74, 50, 28, 69, 226, 195, 243, 118, 45, 63, 237, 197, + 216, 202, 206, 101, 33, 56, 225, 200, 128, 3, 89, 12, 182, 38, 113, 221, 165, 119, + 228, 201, 156, 201, 172, 136, 59, 64, 51, 72, 164, 198, 49, 228, 223, 117, 80, 64, + 166, 226, 37, 8, 29, 146, 186, 80, 210, 119, 76, 252, 4, 255, 62, 218, 112, 163, 164, + 147, 247, 190, 108, 76, 140, 191, 76, 217, 214, 184, 152, 179, 193, 149, 15, 70, 197, + 46, 90, 60, 255, 247, 197, 219, 252, 73, 76, 0, 125, 104, 114, 22, 182, 161, 110, 36, + 162, 103, 27, 42, 88, 18, 161, 237, 198, 43, 177, 189, 181, 86, 135, 207, 71, 114, 0, + 26, 175, 12, 199, 125, 25, 124, 178, 87, 36, 208, 251, 15, 191, 127, 202, 148, 152, + 43, 142, 92, 191, 7, 89, 153, 130, 195, 223, 248, 176, 109, 97, 164, 126, 162, 181, + 124, 237, 130, 155, 197, 66, 59, 40, 197, 72, 84, 32, 100, 64, 55, 227, 60, 214, 143, + 200, 200, 89, 115, 236, 172, 145, 56, 100, 73, 20, 242, 233, 95, 130, 58, 112, 153, + 120, 115, 119, 42, 199, 30, 205, 88, 223, 42, 196, 184, 41, 19, 100, 19, 244], + [1, 225, 103, 238, 42, 147, 91, 191, 110, 69, 154, 53, 57, 156, 124, 43, 174, 155, 76, + 202, 193, 98, 128, 38, 207, 126, 66, 70, 161, 96, 109, 127, 174, 44, 203, 198, 177, + 238, 118, 117, 89, 227, 170, 155, 44, 251, 35, 119, 219, 29, 100, 173, 26, 144, 95, + 50, 177, 4, 40, 234, 117, 174, 210, 192, 172, 57, 160, 198, 42, 199, 212, 243, 240, + 114, 59, 91, 207, 68, 57, 38, 198, 2, 73, 18, 16, 209, 182, 145, 206, 71, 17, 69, 222, + 49, 36, 120, 72, 117, 169, 107, 238, 208, 235, 216, 24, 183, 201, 81, 15, 83, 242, 45, + 136, 184, 166, 26, 142, 136, 228, 58, 229, 235, 88, 169, 238, 134, 205, 96, 85, 9, + 122, 53, 147, 100, 183, 114, 92, 54, 125, 178, 125, 75, 127, 116, 50, 88, 109, 152, + 22, 4, 121, 252, 190, 18, 190, 130, 143, 138, 59, 231, 38, 131, 176, 54, 19, 194, 218, + 67, 144, 122, 91, 43, 86, 73, 233, 48, 193, 30, 183, 183, 191, 238, 216, 167, 101, 28, + 185, 43, 118, 64, 242, 16, 62, 239, 177, 27, 109, 144, 67, 221, 175, 202, 4, 92, 130, + 74, 24, 20, 151, 15, 227, 225, 142, 71, 145, 46, 192, 248, 87, 57, 183, 142, 253, 52, + 20, 56, 153, 220, 234, 25, 67, 116, 225, 179, 211, 116, 161, 37, 64, 34, 48, 155, 1, + 1, 159, 157, 37, 31, 202, 19, 229, 152, 23, 138, 183, 126, 55], + [1, 38, 181, 193, 191, 72, 2, 239, 34, 83, 49, 36, 179, 160, 82, 112, 172, 98, 255, 63, + 60, 22, 177, 249, 67, 215, 220, 198, 181, 7, 49, 254, 133, 243, 221, 214, 47, 64, 229, + 82, 11, 94, 175, 57, 86, 152, 229, 192, 184, 96, 136, 116, 226, 123, 128, 217, 23, + 244, 19, 204, 36, 44, 123, 208, 88, 24, 217, 120, 145, 139, 25, 233, 227, 5, 119, 90, + 47, 147, 1, 115, 92, 39, 119, 194, 167, 17, 229, 39, 163, 167, 237, 14, 116, 234, 106, + 252, 216, 54, 33, 233, 21, 54, 183, 130, 144, 161, 177, 142, 177, 240, 51, 73, 21, + 202, 188, 103, 244, 153, 204, 219, 123, 231, 139, 135, 189, 155, 143, 28, 4, 180, 44, + 148, 0, 27, 103, 26, 13, 203, 31, 32, 166, 67, 84, 87, 23, 72, 234, 236, 20, 1, 84, + 70, 86, 76, 192, 164, 235, 124, 86, 128, 78, 230, 119, 155, 95, 121, 125, 20, 244, + 181, 121, 250, 169, 9, 67, 85, 213, 177, 139, 111, 187, 183, 114, 165, 249, 177, 161, + 181, 175, 46, 226, 66, 86, 84, 124, 86, 69, 143, 217, 158, 161, 30, 107, 133, 44, 239, + 89, 209, 24, 150, 1, 238, 122, 144, 138, 179, 121, 114, 90, 13, 212, 209, 60, 126, 37, + 62, 177, 180, 131, 222, 168, 2, 201, 156, 169, 220, 224, 53, 8, 203, 220, 215, 163, + 104, 195, 184, 73, 35, 241, 182, 177, 80, 41, 253, 230, 90, 173], + [1, 32, 145, 96, 219, 241, 190, 19, 195, 129, 219, 50, 148, 152, 107, 12, 189, 225, + 103, 171, 149, 252, 193, 243, 136, 132, 195, 44, 19, 20, 247, 140, 160, 91, 230, 78, + 31, 242, 85, 213, 65, 185, 1, 91, 12, 69, 118, 80, 26, 135, 102, 131, 4, 108, 130, + 230, 83, 91, 176, 249, 196, 56, 128, 127, 82, 72, 106, 49, 211, 94, 133, 40, 86, 72, + 42, 187, 199, 216, 191, 223, 208, 206, 121, 118, 15, 167, 255, 228, 57, 206, 158, 217, + 64, 205, 212, 178, 8, 248, 129, 183, 221, 98, 70, 54, 37, 55, 47, 81, 120, 59, 186, + 238, 165, 0, 70, 173, 137, 193, 232, 180, 125, 211, 237, 182, 249, 191, 173, 107, 129, + 164, 148, 231, 116, 225, 66, 66, 71, 156, 39, 248, 164, 253, 234, 140, 205, 177, 140, + 117, 47, 21, 15, 242, 31, 113, 118, 91, 143, 89, 213, 86, 143, 135, 21, 46, 35, 199, + 214, 107, 111, 65, 65, 19, 26, 171, 130, 16, 19, 102, 145, 210, 210, 61, 51, 169, 148, + 169, 118, 182, 106, 107, 253, 100, 214, 232, 52, 103, 180, 96, 249, 254, 71, 6, 11, + 119, 48, 129, 213, 223, 205, 93, 20, 117, 26, 187, 32, 151, 212, 137, 203, 17, 237, + 208, 150, 72, 23, 225, 235, 122, 188, 34, 105, 115, 0, 160, 168, 251, 191, 22, 242, + 238, 207, 74, 142, 154, 66, 94, 149, 191, 215, 194, 134, 6, 165, 244, 167, 233, 241], + [1, 207, 77, 250, 146, 127, 242, 229, 44, 172, 182, 201, 183, 242, 32, 242, 182, 129, + 233, 10, 8, 180, 23, 191, 163, 21, 238, 158, 5, 27, 216, 146, 253, 173, 127, 99, 95, + 168, 209, 132, 242, 196, 242, 34, 25, 25, 249, 211, 51, 236, 164, 153, 175, 61, 65, + 150, 82, 251, 174, 102, 186, 47, 195, 82, 44, 90, 252, 184, 74, 89, 251, 177, 254, + 108, 151, 136, 230, 220, 93, 224, 173, 247, 244, 116, 132, 59, 170, 215, 194, 30, 87, + 84, 166, 147, 57, 156, 201, 207, 132, 203, 222, 191, 253, 15, 19, 228, 173, 81, 156, + 4, 51, 121, 227, 159, 50, 18, 148, 129, 205, 42, 42, 227, 252, 138, 62, 176, 115, 227, + 253, 52, 125, 110, 178, 167, 132, 244, 14, 116, 195, 194, 172, 44, 45, 63, 38, 121, + 215, 136, 68, 230, 21, 108, 133, 159, 197, 179, 94, 78, 233, 107, 236, 114, 92, 165, + 248, 22, 124, 161, 23, 142, 236, 224, 175, 233, 134, 25, 97, 150, 131, 61, 220, 203, + 104, 154, 199, 247, 146, 47, 205, 56, 209, 0, 133, 132, 18, 103, 136, 8, 202, 37, 29, + 100, 105, 12, 232, 74, 33, 6, 255, 202, 96, 170, 52, 229, 244, 4, 235, 2, 201, 125, + 86, 168, 179, 224, 130, 81, 54, 221, 185, 184, 187, 141, 0, 114, 98, 38, 70, 225, 228, + 60, 157, 53, 210, 238, 60, 216, 215, 154, 48, 73, 3, 157, 192, 245, 81, 170, 49], + [1, 3, 244, 229, 158, 71, 18, 146, 198, 202, 27, 2, 231, 37, 13, 145, 243, 84, 112, + 220, 61, 174, 4, 175, 104, 200, 64, 146, 193, 20, 174, 126, 42, 157, 168, 76, 165, 21, + 50, 216, 82, 211, 180, 73, 244, 54, 227, 200, 19, 157, 25, 228, 81, 37, 64, 201, 19, + 138, 175, 50, 246, 169, 11, 45, 74, 194, 131, 236, 127, 177, 41, 242, 130, 55, 112, + 182, 98, 22, 99, 48, 153, 83, 161, 250, 65, 89, 3, 97, 6, 5, 171, 54, 223, 87, 98, + 103, 23, 200, 212, 177, 140, 155, 151, 252, 125, 45, 176, 55, 92, 41, 56, 2, 252, 32, + 149, 60, 3, 168, 209, 193, 23, 168, 230, 182, 72, 193, 230, 224, 5, 15, 58, 63, 93, + 196, 33, 93, 76, 188, 30, 70, 31, 136, 64, 204, 223, 2, 230, 210, 243, 255, 135, 193, + 52, 132, 248, 160, 22, 18, 164, 71, 77, 80, 112, 229, 120, 116, 210, 225, 2, 19, 139, + 35, 0, 214, 5, 246, 9, 106, 136, 204, 0, 148, 97, 21, 222, 153, 57, 177, 162, 11, 243, + 252, 7, 242, 34, 239, 245, 50, 104, 74, 221, 92, 73, 13, 142, 10, 184, 250, 246, 167, + 240, 46, 230, 86, 207, 181, 12, 133, 81, 119, 143, 164, 88, 114, 223, 243, 179, 208, + 175, 84, 161, 27, 11, 225, 36, 37, 177, 112, 85, 81, 184, 163, 223, 159, 36, 9, 247, + 20, 13, 230, 215, 108, 117, 35, 99, 117, 211]]}, "requested_proof": { + "revealed_attrs": {"attr1_uuid": ["claim::277478db-bf57-42c3-8530-b1b13cfe0bfd", "Alex", + "1139481716457488690172217916278103335"]}, "unrevealed_attrs": {}, + "self_attested_attrs": {}, + "predicates": {"predicate1_uuid": "claim::277478db-bf57-42c3-8530-b1b13cfe0bfd"}}} + + valid = await verifier_verify_proof(json.dumps(proof_req), json.dumps(proof), + json.dumps(schemas), json.dumps(claim_defs), "{}") + + assert not valid diff --git a/wrappers/python/tests/conftest.py b/wrappers/python/tests/conftest.py new file mode 100644 index 0000000000..3bcb4cc4dd --- /dev/null +++ b/wrappers/python/tests/conftest.py @@ -0,0 +1,37 @@ +import logging + +import pytest + +from .utils import pool, storage, wallet + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture +def trustee1_seed(): + return "000000000000000000000000Trustee1" + + +@pytest.fixture +def cleanup_storage(): + storage.cleanup() + yield + storage.cleanup() + + +# noinspection PyUnusedLocal +@pytest.fixture +async def wallet_handle(cleanup_storage): + wallet_handle = await wallet.create_and_open_wallet() + assert type(wallet_handle) is int + yield wallet_handle + await wallet.close_wallet(wallet_handle) + + +# noinspection PyUnusedLocal +@pytest.fixture +async def pool_handle(cleanup_storage): + pool_handle = await pool.create_and_open_pool_ledger() + assert type(pool_handle) is int + yield pool_handle + await pool.close_pool_ledger(pool_handle) diff --git a/wrappers/python/tests/demo/agent.py b/wrappers/python/tests/demo/agent.py new file mode 100644 index 0000000000..363d12d4a8 --- /dev/null +++ b/wrappers/python/tests/demo/agent.py @@ -0,0 +1,75 @@ +from indy import agent +from indy import ledger, signus, wallet, pool +from indy.pool import open_pool_ledger + +import pytest +import json + +from tests.utils.pool import create_genesis_txn_file + + +@pytest.mark.asyncio +async def test_agent_demo_works(cleanup_storage): + # 1. Create ledger config from genesis txn file + path = create_genesis_txn_file('pool_1.txn', None) + pool_config = json.dumps({"genesis_txn": str(path)}) + await pool.create_pool_ledger_config('pool_1', pool_config) + + # 2. Open pool ledger + pool_handle = await open_pool_ledger('pool_1', None) + + # 3. Create and Open Listener Wallet. Gets wallet handle + await wallet.create_wallet('pool_1', 'listener_wallet', None, None, None) + listener_wallet_handle = await wallet.open_wallet('listener_wallet', None, None) + + # 4. Create and Open Sender Wallet. Gets wallet handle + await wallet.create_wallet('pool_1', 'sender_wallet', None, None, None) + sender_wallet_handle = await wallet.open_wallet('sender_wallet', None, None) + + # 5. Create Listener DID + (listener_did, listener_verkey, listener_pk) = await signus.create_and_store_my_did(listener_wallet_handle, "{}") + + # 6. Create Sender DID from Trustee1 seed + (sender_did, sender_verkey, sender_pk) = \ + await signus.create_and_store_my_did(sender_wallet_handle, '{"seed":"000000000000000000000000Trustee1"}') + + # 7. Prepare and send NYM transaction + nym_txn_req = await ledger.build_nym_request(sender_did, listener_did, listener_verkey, None, None) + await ledger.sign_and_submit_request(pool_handle, sender_wallet_handle, sender_did, nym_txn_req) + + # 8. Prepare and send Attrib request + raw = json.dumps({ + "endpoint": { + "ha": "127.0.0.1:5555", + "verkey": listener_pk + } + }) + + attrib_txn_req = await ledger.build_attrib_request(listener_did, listener_did, None, raw, None) + await ledger.sign_and_submit_request(pool_handle, listener_wallet_handle, listener_did, attrib_txn_req) + + # 9. Start listener on endpoint + listener_handle = await agent.agent_listen("127.0.0.1:5555") + + # 10. Allow listener accept incoming connection for specific DID (listener_did) + await agent.agent_add_identity(listener_handle, pool_handle, listener_wallet_handle, listener_did) + + # 11. Initiate connection from sender to listener + connection_handle = await agent.agent_connect(pool_handle, sender_wallet_handle, sender_did, listener_did) + event = await agent.agent_wait_for_event([listener_handle]) + inc_con_handle = event.connection_handle + + # 12. Send test message from sender to listener + message = 'msg_from_sender_to_listener' + await agent.agent_send(connection_handle, message) + + message_event = await agent.agent_wait_for_event([listener_handle, inc_con_handle]) # type: agent.MessageEvent + assert message_event.message == message + + # 13. Close connection, listener, wallets, pool + await agent.agent_close_listener(listener_handle) + await agent.agent_close_connection(connection_handle) + + await wallet.close_wallet(listener_wallet_handle) + await wallet.close_wallet(sender_wallet_handle) + await pool.close_pool_ledger(pool_handle) diff --git a/wrappers/python/tests/demo/anoncreds.py b/wrappers/python/tests/demo/anoncreds.py new file mode 100644 index 0000000000..8630ca9881 --- /dev/null +++ b/wrappers/python/tests/demo/anoncreds.py @@ -0,0 +1,94 @@ +from indy import anoncreds, wallet + +import pytest +import json + + +@pytest.mark.asyncio +async def test_anoncreds_demo_works(cleanup_storage): + # 1. Create My Wallet and Get Wallet Handle + await wallet.create_wallet('pool_1', 'wallet_1', None, None, None) + wallet_handle = await wallet.open_wallet('wallet_1', None, None) + + # 2. Issuer create Claim Definition for Schema + schema = { + 'seqNo': 1, + 'data': { + 'name': 'gvt', + 'version': '1.0', + 'keys': ['age', 'sex', 'height', 'name'] + } + } + schema_json = json.dumps(schema) + + claim_def_json = \ + await anoncreds.issuer_create_and_store_claim_def(wallet_handle, + 'NcYxiDXkpYi6ov5FcYDi1e', schema_json, 'CL', False) + + # 3. Prover create Master Secret + await anoncreds.prover_create_master_secret(wallet_handle, 'master_secret') + + # 4. Prover create Claim Request + claim_offer_json = json.dumps({ + 'issuer_did': 'NcYxiDXkpYi6ov5FcYDi1e', + 'schema_seq_no': 1 + }) + + claim_req_json = await anoncreds.prover_create_and_store_claim_req(wallet_handle, 'BzfFCYk', claim_offer_json, + claim_def_json, 'master_secret') + + # 5. Issuer create Claim for Claim Request + claim_json = json.dumps({ + 'sex': ['male', '5944657099558967239210949258394887428692050081607692519917050011144233115103'], + 'name': ['Alex', '1139481716457488690172217916278103335'], + 'height': ['175', '175'], + 'age': ['28', '28'] + }) + + (_, claim_json) = await anoncreds.issuer_create_claim(wallet_handle, claim_req_json, claim_json, -1, -1) + + # 6. Prover process and store Claim + await anoncreds.prover_store_claim(wallet_handle, claim_json) + + # 7. Prover gets Claims for Proof Request + proof_req_json = json.dumps({ + 'nonce': '123432421212', + 'name': 'proof_req_1', + 'version': '0.1', + 'requested_attrs': { + 'attr1_uuid': {'schema_seq_no': 1, 'name': 'name'} + }, + 'requested_predicates': { + 'predicate1_uuid': {'attr_name': 'age', 'p_type': 'GE', 'value': 18} + } + }) + + claim_for_proof_json = await anoncreds.prover_get_claims_for_proof_req(wallet_handle, proof_req_json) + claims_for_proof = json.loads(claim_for_proof_json) + + claim_for_attr1 = claims_for_proof['attrs']['attr1_uuid'] + claim_uuid = claim_for_attr1[0]['claim_uuid'] + + # 8. Prover create Proof for Proof Request + requested_claims_json = json.dumps({ + 'self_attested_attributes': {}, + 'requested_attrs': {'attr1_uuid': [claim_uuid, True]}, + 'requested_predicates': {'predicate1_uuid': claim_uuid} + }) + + schemas_json = json.dumps({claim_uuid: schema}) + claim_defs_json = json.dumps({claim_uuid: json.loads(claim_def_json)}) + revoc_regs_json = json.dumps({}) + + proof_json = await anoncreds.prover_create_proof(wallet_handle, proof_req_json, requested_claims_json, schemas_json, + 'master_secret', claim_defs_json, revoc_regs_json) + proof = json.loads(proof_json) + + assert 'Alex' == proof['requested_proof']['revealed_attrs']['attr1_uuid'][1] + + # 9. Verifier verify proof + assert await anoncreds.verifier_verify_proof(proof_req_json, proof_json, schemas_json, claim_defs_json, + revoc_regs_json) + + # 10. Close wallet + await wallet.close_wallet(wallet_handle) diff --git a/wrappers/python/tests/demo/ledger.py b/wrappers/python/tests/demo/ledger.py new file mode 100644 index 0000000000..0bde12efb3 --- /dev/null +++ b/wrappers/python/tests/demo/ledger.py @@ -0,0 +1,59 @@ +from indy import ledger, signus, wallet, pool +from indy.pool import open_pool_ledger + +import pytest +import json + +from tests.utils.pool import create_genesis_txn_file + + +@pytest.mark.asyncio +async def test_ledger_demo_works(cleanup_storage): + # 1. Create ledger config from genesis txn file + path = create_genesis_txn_file('pool_1.txn', None) + pool_config = json.dumps({"genesis_txn": str(path)}) + await pool.create_pool_ledger_config('pool_1', pool_config) + + # 2. Open pool ledger + pool_handle = await open_pool_ledger('pool_1', None) + + # 3. Create My Wallet and Get Wallet Handle + await wallet.create_wallet('pool_1', 'my_wallet', None, None, None) + my_wallet_handle = await wallet.open_wallet('my_wallet', None, None) + + # 4. Create Their Wallet and Get Wallet Handle + await wallet.create_wallet('pool_1', 'their_wallet', None, None, None) + their_wallet_handle = await wallet.open_wallet('their_wallet', None, None) + + # 5. Create My DID + (my_did, my_verkey, my_pk) = await signus.create_and_store_my_did(my_wallet_handle, "{}") + + # 6. Create Their DID from Trustee1 seed + (their_did, their_verkey, their_pk) = \ + await signus.create_and_store_my_did(their_wallet_handle, '{"seed":"000000000000000000000000Trustee1"}') + + # 7. Store Their DID + their_identity_json = json.dumps({ + 'did': their_did, + 'pk': their_pk, + 'verkey': their_verkey + }) + + await signus.store_their_did(my_wallet_handle, their_identity_json) + + # 8. Prepare and send NYM transaction + nym_txn_req = await ledger.build_nym_request(their_did, my_did, None, None, None) + await ledger.sign_and_submit_request(pool_handle, their_wallet_handle, their_did, nym_txn_req) + + # 9. Prepare and send GET_NYM request + get_nym_txn_req = await ledger.build_get_nym_request(their_did, my_did) + get_nym_txn_resp = await ledger.submit_request(pool_handle, get_nym_txn_req) + + get_nym_txn_resp = json.loads(get_nym_txn_resp) + + assert get_nym_txn_resp['result']['dest'] == my_did + + # 10. Close wallets and pool + await wallet.close_wallet(their_wallet_handle) + await wallet.close_wallet(my_wallet_handle) + await pool.close_pool_ledger(pool_handle) diff --git a/wrappers/python/tests/demo/signus.py b/wrappers/python/tests/demo/signus.py new file mode 100644 index 0000000000..0a34aedffd --- /dev/null +++ b/wrappers/python/tests/demo/signus.py @@ -0,0 +1,50 @@ +from indy import signus, wallet + +import pytest +import json + + +@pytest.mark.asyncio +async def test_signus_demo_works(cleanup_storage): + # 1. Create My Wallet and Get Wallet Handle + await wallet.create_wallet('pool_1', 'my_wallet', None, None, None) + my_wallet_handle = await wallet.open_wallet('my_wallet', None, None) + + # 2. Create Their Wallet and Get Wallet Handle + await wallet.create_wallet('pool_1', 'their_wallet', None, None, None) + their_wallet_handle = await wallet.open_wallet('their_wallet', None, None) + + # 3. Create My DID + await signus.create_and_store_my_did(my_wallet_handle, "{}") + + # 4. Create Their DID from Trustee1 seed + (their_did, their_verkey, their_pk) = \ + await signus.create_and_store_my_did(their_wallet_handle, '{"seed":"000000000000000000000000Trustee1"}') + + # 5. Store Their DID + their_identity_json = json.dumps({ + 'did': their_did, + 'pk': their_pk, + 'verkey': their_verkey + }) + + await signus.store_their_did(my_wallet_handle, their_identity_json) + + # 6. Their sign message + message = json.dumps({ + "reqId": 1495034346617224651, + "identifier": "GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL", + "operation": { + "type": "1", + "dest": "4efZu2SXufS556yss7W5k6Po37jt4371RM4whbPKBKdB" + } + }) + + signed_msg = await signus.sign(their_wallet_handle, their_did, message) + + # 7. Their sign message + assert await signus.verify_signature(my_wallet_handle, 1, their_did, signed_msg) + + # 8. Close wallets + await wallet.close_wallet(their_wallet_handle) + await wallet.close_wallet(my_wallet_handle) \ No newline at end of file diff --git a/wrappers/python/tests/ledger/test_build_attrib_request.py b/wrappers/python/tests/ledger/test_build_attrib_request.py new file mode 100644 index 0000000000..4d76086543 --- /dev/null +++ b/wrappers/python/tests/ledger/test_build_attrib_request.py @@ -0,0 +1,47 @@ +from tests.utils import storage +from indy import ledger +from indy.error import * + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_build_attrib_request_works_for_raw_data(): + identifier = "Th7MpTaRZVRYnPiabds81Y" + destination = "Th7MpTaRZVRYnPiabds81Y" + raw = '{"endpoint":{"ha":"127.0.0.1:5555"}}' + + expected_response = { + "identifier": identifier, + "operation": { + "type": "100", + "dest": destination, + "raw": raw + } + } + + response = json.loads(await ledger.build_attrib_request(identifier, destination, None, raw, None)) + assert expected_response.items() <= response.items() + + +@pytest.mark.asyncio +async def test_build_attrib_request_works_for_missed_attribute(): + identifier = "Th7MpTaRZVRYnPiabds81Y" + destination = "Th7MpTaRZVRYnPiabds81Y" + + with pytest.raises(IndyError) as e: + await ledger.build_attrib_request(identifier, destination, None, None, None) + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + diff --git a/wrappers/python/tests/ledger/test_build_claim_def_txn.py b/wrappers/python/tests/ledger/test_build_claim_def_txn.py new file mode 100644 index 0000000000..81d3642267 --- /dev/null +++ b/wrappers/python/tests/ledger/test_build_claim_def_txn.py @@ -0,0 +1,47 @@ +from tests.utils import storage +from indy import ledger + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_build_claim_def_request_works_for_correct_data_json(): + identifier = "identifier" + signature_type = "CL" + schema_seq_no = 1 + data = { + "primary": { + "n": "1", + "s": "2", + "rms": "3", + "r": { + "name": "1" + }, + "rctxt": "1", + "z": "1" + } + } + + expected_response = { + "identifier": "identifier", + "operation": {"ref": 1, + "data": '{"primary": {"n": "1", "s": "2", "rms": "3",' + ' "r": {"name": "1"}, "rctxt": "1", "z": "1"}}', + "type": "102", + "signature_type": "CL"}} + + response = json.loads( + await ledger.build_claim_def_txn( + identifier, schema_seq_no, signature_type, json.dumps(data))) + assert expected_response.items() <= response.items() diff --git a/wrappers/python/tests/ledger/test_build_get_attrib_request.py b/wrappers/python/tests/ledger/test_build_get_attrib_request.py new file mode 100644 index 0000000000..450a5d6105 --- /dev/null +++ b/wrappers/python/tests/ledger/test_build_get_attrib_request.py @@ -0,0 +1,34 @@ +from tests.utils import storage +from indy import ledger + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_build_get_attrib_request_works(): + identifier = "Th7MpTaRZVRYnPiabds81Y" + destination = "Th7MpTaRZVRYnPiabds81Y" + raw = "endpoint" + + expected_response = { + "identifier": identifier, + "operation": { + "type": "104", + "dest": destination, + "raw": raw + } + } + + response = json.loads(await ledger.build_get_attrib_request(identifier, destination, raw)) + assert expected_response.items() <= response.items() diff --git a/wrappers/python/tests/ledger/test_build_get_claim_def_txn.py b/wrappers/python/tests/ledger/test_build_get_claim_def_txn.py new file mode 100644 index 0000000000..8205a6bd15 --- /dev/null +++ b/wrappers/python/tests/ledger/test_build_get_claim_def_txn.py @@ -0,0 +1,72 @@ +from tests.utils import storage +from indy import ledger + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_build_get_claim_def_request_works(): + identifier = "identifier" + _ref = 1 + signature_type = "signature_type" + origin = "origin" + + expected_response = { + "identifier": "identifier", + "operation": { + "type": "108", + "ref": 1, + "signature_type": "signature_type", + "origin": "origin" + } + } + + response = json.loads((await ledger.build_get_claim_def_txn( + identifier, _ref, signature_type, origin + ))) + assert expected_response.items() <= response.items() + + +@pytest.mark.asyncio +async def test_build_claim_def_request_works_for_correct_data_json(): + identifier = "identifier" + signature_type = "CL" + schema_seq_no = 1 + data = { + "primary": { + "n": "1", + "s": "2", + "rms": "3", + "r": { + "name": "1" + }, + "rctxt": "1", + "z": "1" + } + } + + expected_response = { + "identifier": "identifier", + "operation": { + "ref": schema_seq_no, + "data": json.dumps(data), + "type": "102", + "signature_type": signature_type + } + } + + response = json.loads( + await ledger.build_claim_def_txn( + identifier, schema_seq_no, signature_type, json.dumps(data))) + assert expected_response.items() <= response.items() diff --git a/wrappers/python/tests/ledger/test_build_get_nym_request.py b/wrappers/python/tests/ledger/test_build_get_nym_request.py new file mode 100644 index 0000000000..bb102bedec --- /dev/null +++ b/wrappers/python/tests/ledger/test_build_get_nym_request.py @@ -0,0 +1,32 @@ +from tests.utils import storage +from indy import ledger + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_build_get_nym_request_works(): + identifier = "Th7MpTaRZVRYnPiabds81Y" + destination = "FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4" + + expected_response = { + "identifier": identifier, + "operation": { + "type": "105", + "dest": destination + } + } + + response = json.loads(await ledger.build_get_nym_request(identifier, destination)) + assert expected_response.items() <= response.items() diff --git a/wrappers/python/tests/ledger/test_build_get_schema_request.py b/wrappers/python/tests/ledger/test_build_get_schema_request.py new file mode 100644 index 0000000000..167985a6c6 --- /dev/null +++ b/wrappers/python/tests/ledger/test_build_get_schema_request.py @@ -0,0 +1,36 @@ +from tests.utils import storage +from indy import ledger + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_build_get_schema_requests_works_for_correct_data_json(): + identifier = "identifier" + data = '{"name":"name","version":"1.0"}' + + expected_response = { + "identifier": "identifier", + "operation": { + "type": "107", + "dest": "identifier", + "data": { + "name": "name", + "version": "1.0" + } + } + } + + response = json.loads(await ledger.build_get_schema_request(identifier, identifier, data)) + assert expected_response.items() <= response.items() diff --git a/wrappers/python/tests/ledger/test_build_get_txn_request.py b/wrappers/python/tests/ledger/test_build_get_txn_request.py new file mode 100644 index 0000000000..0ff71080b2 --- /dev/null +++ b/wrappers/python/tests/ledger/test_build_get_txn_request.py @@ -0,0 +1,30 @@ +from tests.utils import storage +from indy import ledger + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_build_get_txn_request_works(): + identifier = "identifier" + data = 1 + expected_response = { + "identifier": "identifier", + "operation": { + "type": "3", "data": 1 + } + } + + response = json.loads(await ledger.build_get_txn_request(identifier, data)) + assert expected_response.items() <= response.items() diff --git a/wrappers/python/tests/ledger/test_build_node_request.py b/wrappers/python/tests/ledger/test_build_node_request.py new file mode 100644 index 0000000000..192c286337 --- /dev/null +++ b/wrappers/python/tests/ledger/test_build_node_request.py @@ -0,0 +1,58 @@ +from tests.utils import storage +from indy import ledger +from indy.error import ErrorCode, IndyError + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_build_node_request_works_for_missed_field_in_data_json(): + identifier = "identifier" + destination = "destination" + data = { + "node_ip": "ip", + "node_port": 1, + "client_ip": "ip", + "client_port": 1 + } + + with pytest.raises(IndyError) as e: + await ledger.build_node_request(identifier, destination, json.dumps(data)) + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_build_node_request_works_for_correct_data_json(): + identifier = "identifier" + destination = "destination" + data = { + "node_ip": "ip", + "node_port": 1, + "client_ip": "ip", + "client_port": 1, + "alias": "some", + "services": ["VALIDATOR"] + } + + expected_response = { + "identifier": identifier, + "operation": { + "type": "0", + "dest": destination, + "data": data + } + } + + response = json.loads(await ledger.build_node_request(identifier, destination, json.dumps(data))) + assert expected_response.items() <= response.items() diff --git a/wrappers/python/tests/ledger/test_build_nym_request.py b/wrappers/python/tests/ledger/test_build_nym_request.py new file mode 100644 index 0000000000..161d54c447 --- /dev/null +++ b/wrappers/python/tests/ledger/test_build_nym_request.py @@ -0,0 +1,66 @@ +from tests.utils import storage +from indy import ledger +from indy.error import ErrorCode, IndyError + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_build_nym_request_works_for_invalid_identifier(): + identifier = "invalid_base58_identifier" + dest = "FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4" + + with pytest.raises(IndyError) as e: + await ledger.build_nym_request(identifier, dest, None, None, None) + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_build_nym_request_works_for_only_required_fields(): + identifier = "Th7MpTaRZVRYnPiabds81Y" + destination = "FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4" + + expected_response = { + "identifier": identifier, + "operation": { + "type": "1", + "dest": destination + } + } + + response = json.loads((await ledger.build_nym_request(identifier, destination, None, None, None))) + assert expected_response.items() <= response.items() + + +@pytest.mark.asyncio +async def test_build_nym_request_works_with_option_fields(): + identifier = "Th7MpTaRZVRYnPiabds81Y" + destination = "FYmoFw55GeQH7SRFa37dkx1d2dZ3zUF8ckg7wmL7ofN4" + ver_key = "Anfh2rjAcxkE249DcdsaQl" + role = "STEWARD" + alias = "some_alias" + + expected_response = { + "identifier": identifier, + "operation": { + "type": "1", + "dest": destination, + "verkey": ver_key, + "alias": alias, + "role": "2" + } + } + + response = json.loads(await ledger.build_nym_request(identifier, destination, ver_key, alias, role)) + assert expected_response.items() <= response.items() diff --git a/wrappers/python/tests/ledger/test_build_schema_request.py b/wrappers/python/tests/ledger/test_build_schema_request.py new file mode 100644 index 0000000000..f23f8886a2 --- /dev/null +++ b/wrappers/python/tests/ledger/test_build_schema_request.py @@ -0,0 +1,31 @@ +from tests.utils import storage +from indy import ledger + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_build_schema_requests_works_for_correct_data_json(): + identifier = "identifier" + data = '{"name":"name", "version":"1.0", "keys":["name","male"]}' + + expected_response = { + "operation": { + "type": "101", + "data": '{"name":"name", "version":"1.0", "keys":["name","male"]}' + } + } + + response = json.loads(await ledger.build_schema_request(identifier, data)) + assert expected_response.items() <= response.items() diff --git a/wrappers/python/tests/ledger/test_sign_and_submit_request.py b/wrappers/python/tests/ledger/test_sign_and_submit_request.py new file mode 100644 index 0000000000..0d2a59eb89 --- /dev/null +++ b/wrappers/python/tests/ledger/test_sign_and_submit_request.py @@ -0,0 +1,83 @@ +from tests.utils import pool, storage +from tests.utils.wallet import create_and_open_wallet +from indy import wallet, signus, ledger +from indy.pool import close_pool_ledger +from indy.error import ErrorCode, IndyError +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.fixture +async def pool_handle(): + handle = await pool.create_and_open_pool_ledger("pool_1") + yield handle + await close_pool_ledger(handle) + + +@pytest.fixture +async def wallet_handle(): + handle = await create_and_open_wallet() + yield handle + await wallet.close_wallet(handle) + + +@pytest.mark.asyncio +async def test_sign_and_submit_request_works(wallet_handle, pool_handle): + (my_did, _, _) = await signus.create_and_store_my_did(wallet_handle, '{"seed":"00000000000000000000000000000My1"}') + (trustee_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + nym_request = await ledger.build_nym_request(trustee_did, my_did, None, None, None) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, trustee_did, nym_request) + + +@pytest.mark.asyncio +async def test_sign_and_submit_request_works_for_invalid_pool_handle(wallet_handle, pool_handle): + (my_did, _, _) = await signus.create_and_store_my_did(wallet_handle, '{"seed":"00000000000000000000000000000My1"}') + (trustee_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + nym_request = await ledger.build_nym_request(trustee_did, my_did, None, None, None) + invalid_pool_handle = pool_handle + 1 + + with pytest.raises(IndyError) as e: + await ledger.sign_and_submit_request(invalid_pool_handle, wallet_handle, trustee_did, + nym_request) + assert ErrorCode.PoolLedgerInvalidPoolHandle == e.value.error_code + + +@pytest.mark.asyncio +async def test_sign_and_submit_request_works_for_invalid_wallet_handle(wallet_handle, pool_handle): + (my_did, _, _) = await signus.create_and_store_my_did(wallet_handle, '{"seed":"00000000000000000000000000000My1"}') + (trustee_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + nym_request = await ledger.build_nym_request(trustee_did, my_did, None, None, None) + invalid_wallet_handle = wallet_handle + 1 + + with pytest.raises(IndyError) as e: + await ledger.sign_and_submit_request(pool_handle, invalid_wallet_handle, trustee_did, + nym_request) + assert ErrorCode.WalletInvalidHandle == e.value.error_code + + +@pytest.mark.asyncio +async def test_sign_and_submit_request_works_for_incompatible_wallet_and_pool(pool_handle): + wallet_handle = await create_and_open_wallet(pool_name="pool_2") + (my_did, _, _) = await signus.create_and_store_my_did(wallet_handle, '{"seed":"00000000000000000000000000000My1"}') + (trustee_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + nym_request = await ledger.build_nym_request(trustee_did, my_did, None, None, None) + + with pytest.raises(IndyError) as e: + await ledger.sign_and_submit_request(pool_handle, wallet_handle, trustee_did, + nym_request) + assert ErrorCode.WalletIncompatiblePoolError == e.value.error_code + + await wallet.close_wallet(wallet_handle) diff --git a/wrappers/python/tests/ledger/test_submit_request.py b/wrappers/python/tests/ledger/test_submit_request.py new file mode 100644 index 0000000000..605fa6e8ea --- /dev/null +++ b/wrappers/python/tests/ledger/test_submit_request.py @@ -0,0 +1,307 @@ +from tests.utils import pool, storage +from tests.utils.wallet import create_and_open_wallet +from indy import ledger, wallet, signus +from indy.pool import close_pool_ledger +from indy.error import ErrorCode, IndyError + +import json +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.fixture +async def wallet_handle(): + handle = await create_and_open_wallet() + yield handle + await wallet.close_wallet(handle) + + +@pytest.fixture +async def pool_handle(): + handle = await pool.create_and_open_pool_ledger("pool_1") + yield handle + await close_pool_ledger(handle) + + +@pytest.mark.asyncio +async def test_submit_request_works(pool_handle): + request = { + "reqId": 1491566332010860, + "identifier": "Th7MpTaRZVRYnPiabds81Y", + "operation": { + "type": "105", + "dest": "Th7MpTaRZVRYnPiabds81Y" + }, + "signature": "4o86XfkiJ4e2r3J6Ufoi17UU3W5Zi9sshV6FjBjkVw4sgEQFQov9dxqDEtLbAJAWffCWd5KfAk164QVo7mYwKkiV" + } + + expected_response = { + "result": { + "reqId": 1491566332010860, + "identifier": "Th7MpTaRZVRYnPiabds81Y", + "dest": "Th7MpTaRZVRYnPiabds81Y", + "data": "{\"dest\":\"Th7MpTaRZVRYnPiabds81Y\",\"identifier\":\"V4SGRU86Z58d6TV7PBUe6f\",\"role\":\"2\"" + ",\"verkey\":\"~7TYfekw4GUagBnBVCqPjiC\"}", + "type": "105", + }, + "op": "REPLY" + } + response = json.loads(await ledger.submit_request(pool_handle, json.dumps(request))) + assert response == expected_response + + +@pytest.mark.asyncio +async def test_submit_request_works_for_invalid_pool_handle(pool_handle, wallet_handle): + (my_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + + get_nym_request = await ledger.build_get_nym_request(my_did, my_did) + invalid_pool_handle = pool_handle + 1 + + with pytest.raises(IndyError) as e: + await ledger.submit_request(invalid_pool_handle, get_nym_request) + assert ErrorCode.PoolLedgerInvalidPoolHandle == e.value.error_code + + +@pytest.mark.asyncio +async def test_send_nym_request_works_without_signature(pool_handle, wallet_handle): + (my_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"00000000000000000000000000000My1"}') + + nym_request = await ledger.build_nym_request(my_did, my_did, None, None, None) + + with pytest.raises(IndyError) as e: + await ledger.submit_request(pool_handle, nym_request) + assert ErrorCode.LedgerInvalidTransaction == e.value.error_code + + +@pytest.mark.asyncio +async def test_send_get_nym_request_works(pool_handle, wallet_handle): + (my_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + + get_nym_request = await ledger.build_get_nym_request(my_did, my_did) + + response = json.loads(await ledger.submit_request(pool_handle, get_nym_request)) + assert response['result']['data'] is not None + + +@pytest.mark.asyncio +async def test_nym_requests_works(pool_handle, wallet_handle): + (trustee_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + (my_did, my_ver_key, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"00000000000000000000000000000My1"}') + + nym_request = await ledger.build_nym_request(trustee_did, my_did, my_ver_key, None, None) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, trustee_did, nym_request) + get_nym_request = await ledger.build_get_nym_request(my_did, my_did) + response = json.loads(await ledger.submit_request(pool_handle, get_nym_request)) + assert response['result']['data'] is not None + + +@pytest.mark.asyncio +async def test_send_attrib_request_works_without_signature(pool_handle, wallet_handle): + (my_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"00000000000000000000000000000My1"}') + + attrib_request = await ledger.build_attrib_request(my_did, my_did, None, + "{\"endpoint\":{\"ha\":\"127.0.0.1:5555\"}}", None) + with pytest.raises(IndyError) as e: + await ledger.submit_request(pool_handle, attrib_request) + assert ErrorCode.LedgerInvalidTransaction == e.value.error_code + + +@pytest.mark.asyncio +async def test_attrib_requests_works(pool_handle, wallet_handle): + (trustee_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + (my_did, my_ver_key, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"00000000000000000000000000000My1"}') + nym_request = await ledger.build_nym_request(trustee_did, my_did, my_ver_key, None, None) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, trustee_did, nym_request) + attrib_request = await ledger.build_attrib_request(my_did, my_did, None, + "{\"endpoint\":{\"ha\":\"127.0.0.1:5555\"}}", None) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, my_did, attrib_request) + get_attrib_request = await ledger.build_get_attrib_request(my_did, my_did, "endpoint") + response = json.loads(await ledger.submit_request(pool_handle, get_attrib_request)) + assert response['result']['data'] is not None + + +@pytest.mark.asyncio +async def test_send_schema_request_works_without_signature(pool_handle, wallet_handle): + (my_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"00000000000000000000000000000My1"}') + + schema_data = { + "name": "gvt2", + "version": "2.0", + "keys": ["name", "male"] + } + + schema_request = await ledger.build_schema_request(my_did, json.dumps(schema_data)) + + with pytest.raises(IndyError) as e: + await ledger.submit_request(pool_handle, schema_request) + assert ErrorCode.LedgerInvalidTransaction == e.value.error_code + + +@pytest.mark.asyncio +async def test_schema_requests_works(pool_handle, wallet_handle): + (trustee_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + (my_did, my_ver_key, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"00000000000000000000000000000My1"}') + + schema_data = { + "name": "gvt2", + "version": "2.0", + "keys": ["name", "male"] + } + + nym_request = await ledger.build_nym_request(trustee_did, my_did, my_ver_key, None, None) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, trustee_did, nym_request) + schema_request = await ledger.build_schema_request(my_did, json.dumps(schema_data)) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, my_did, schema_request) + get_schema_data = { + "name": "gvt2", + "version": "2.0" + } + get_schema_request = await ledger.build_get_schema_request(my_did, my_did, json.dumps(get_schema_data)) + response = json.loads(await ledger.submit_request(pool_handle, get_schema_request)) + assert response['result']['data'] is not None + + +@pytest.mark.asyncio +async def test_send_node_request_works_without_signature(pool_handle, wallet_handle): + (my_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"00000000000000000000000000000My1"}') + + node_data = { + "node_ip": "10.0.0.100", + "node_port": 9710, + "client_ip": "10.0.0.100", + "client_port": 9709, + "alias": "Node5", + "services": ["VALIDATOR"] + } + + node_request = await ledger.build_node_request(my_did, my_did, json.dumps(node_data)) + + with pytest.raises(IndyError) as e: + await ledger.submit_request(pool_handle, node_request) + assert ErrorCode.LedgerInvalidTransaction == e.value.error_code + + +@pytest.mark.asyncio +async def test_claim_def_requests_works(pool_handle, wallet_handle): + (trustee_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + (my_did, my_ver_key, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"00000000000000000000000000000My1"}') + + schema_data = { + "name": "gvt2", + "version": "2.0", + "keys": ["name", "male"] + } + + nym_request = await ledger.build_nym_request(trustee_did, my_did, my_ver_key, None, None) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, trustee_did, nym_request) + + schema_request = await ledger.build_schema_request(my_did, json.dumps(schema_data)) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, my_did, schema_request) + + get_schema_data = { + "name": "gvt2", + "version": "2.0" + } + + get_schema_request = await ledger.build_get_schema_request(my_did, my_did, json.dumps(get_schema_data)) + get_schema_response = json.loads(await ledger.submit_request(pool_handle, get_schema_request)) + + claim_def = { + "primary": { + "n": "83469852984476956871633111285697420678256060723156580163068122759469567425381600849138438902552107548539766861666590365174848381535291010418041757276710240953030842046122202402016906205924972182252295487319094577329593677544393592632224714613427822130473474379696616183721440743475053734247824037725487533789856061706740833324717788602268746116297029721621398888459529131593826880823126900285858832457134377949183677639585442886904844793608783831753240185678448312284269486845497720949217396146132958861735347072722092449280372574205841746312833280031873247525372459800132930201998084029506922484661426185450002143461", + "s": "36598527821865478336201608644402887021319976830281254144922838415193047189326184120876650311572665920640111967758238425066565864958446810892401358531545590342401290056836149703549220109981509774843525259400920352082531560361277411808530872594109525982462491998670199872903823657869742599086495624835178373073050767142081484206776345277546531080450529061958937980460303537107061046725579009809137197541389237618812289642185603461102513124991949835948586623327143696280240600789928383168220919049794681181861776889681393339729944540218566460627715413465709316412838042632482652979005394086058441511591756153781159121227", + "rms": "23836382972046033209463023456985914927629254782286444334728987813724281765327660893337383450653748691133061782449580026414785334582859397732571499366000805280757877601804441568263743400086744823885203441870748890135445454347495577599234477813361254101857848089907496868136222777024967328411073984887059985103475100012787049491016895625234124538894645853939428009610771524580099452739392988318945585946758355611531582519514003714424216836334706370901576611410508113637778751976890941210538254418937285168453791223070083264852447713991114719905171445881819334587600693321106919667204512182250084258986170095774914769107", + "r": { + "age": "15428480888651268593621235736458685943389726269437020388313417035842991073151072061010468945249435098482625869236498750525662874597991333642865524104221652457788998109101749530884821300954337535472137069380551054204373136155978715752232238326100335828797868667735730830741789880726890058203015780792583471770404478023662994191588489722949795849990796063953164194432710764145637578113087142419634074378464118254848566088943085760634805903735300398689750649630456000759025366784986694635635510206166144055869823907120081668956271923743188342071093889666111639924270726451727101864752767708690529389259470017692442002767", + "name": "74008461204977705404956807338714891429397387365673402608947856456696416827848931951447004905350314563364442667940680669672331872875260077257474781261367591510351742401708951175978700805098470304211391452678992053755170054677498844656517106987419550598382601263743442309896367374279461481792679346472671426558385003925845431219156475505665973289508268634194964491418902859845301351562575713510002838692825728016254605821829245646855474149449192539144107522081712005891593405826343897070114168186645885993480245755494685105636168333649181939830898090651120926156152753918086493335382129839850609934233944397884745134858", + "sex": "40646934914193532541511585946883243600955533193734077080129022860038019728021796610599139377923881754708640252789475144625086755150150612623804964347576907276705600241268266301487516824189453869193926251791711672689649199860304727280764676403810510047397326018392955950249975529169980045664874433828266623495515931483137318724210483205730962036282580749206735450480976847188040030165278917936054139926609849181885654646269083459580415131952938813839182742590617440550773580790446467896469090164142755499827316294406540664375065617280568303837662431668218593808092907551353093044984225946834165309588512359379032847125", + "height": "60077310006190228182950362501472785016827894350517184186566050586806482282196022414888288252599211919680339352529750982779980002923071031258837648242708410943080288964834346858544959217874890558006056551949543916094446891954292824146212277550956558692224016968153138097595802008943263818064605343108607131298420107448075252583276684858815371561492996587478784667827675142382692061950832554910690663724101360454494298013020706080246986445114235542283015624510836206522238238728405826712730615187235709554561445384409566940622412591208469650855059870671771721035756205878334354791247751663679130847366069215369484993653" + }, + "rctxt": "36378575722516953828830668112614685244571602424420162720244033008706985740860180373728219883172046821464173434592331868657297711725743060654773725561634332269874655603697872022630999786617840856366807034806938874090561725454026277048301648000835861491030368037108847175790943895107305383779598585532854170748970999977490244057635358075906501562932970296830906796719844887269636297064678777638050708353254894155336111384638276041851818109156194135995350001255928374102089400812445206030019103440866343736761861049159446083221399575945128480681798837648578166327164995640582517916904912672875184928940552983440410245037", + "z": "65210811645114955910002482704691499297899796787292244564644467629838455625296674951468505972574512639263601600908664306008863647466643899294681985964775001929521624341158696866597713112430928402519124073453804861185882073381514901830347278653016300430179820703804228663001232136885036042101307423527913402600370741689559698469878576457899715687929448757963179899698951620405467976414716277505767979494596626867505828267832223147104774684678295400387894506425769550011471322118172087199519094477785389750318762521728398390891214426117908390767403438354009767291938975195751081032073309083309746656253788033721103313036" + }, + "revocation": None + } + + claim_def_request = await ledger.build_claim_def_txn( + my_did, get_schema_response['result']['seqNo'], "CL", json.dumps(claim_def)) + + await ledger.sign_and_submit_request(pool_handle, wallet_handle, my_did, claim_def_request) + get_claim_def_request = await ledger.build_get_claim_def_txn( + my_did, get_schema_response['result']['seqNo'], "CL", get_schema_response['result']['data']['origin']) + get_claim_def_response = json.loads( + (await ledger.submit_request(pool_handle, get_claim_def_request))) + assert claim_def == get_claim_def_response['result']['data'] + + +@pytest.mark.asyncio +async def test_get_txn_request_works(pool_handle, wallet_handle): + (my_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + + schema_data = json.dumps({ + "name": "gvt3", + "version": "3.0", + "keys": ["name"] + }) + + schema_request = await ledger.build_schema_request(my_did, schema_data) + schema_response = json.loads(await ledger.sign_and_submit_request( + pool_handle, wallet_handle, my_did, schema_request)) + + get_schema_data = { + "name": "gvt3", + "version": "3.0" + } + get_schema_request = await ledger.build_get_schema_request( + my_did, my_did, json.dumps(get_schema_data)) + await ledger.submit_request(pool_handle, get_schema_request) + + get_txn_request = await ledger.build_get_txn_request(my_did, schema_response['result']['seqNo']) + get_txn_response = json.loads(await ledger.submit_request(pool_handle, get_txn_request)) + assert schema_data == json.loads(get_txn_response['result']['data'])['data'] + + +@pytest.mark.asyncio +async def test_get_txn_request_works_for_invalid_seq_no(pool_handle, wallet_handle): + (my_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + + schema_data = json.dumps({ + "name": "gvt3", + "version": "3.0", + "keys": ["name"] + }) + + schema_request = await ledger.build_schema_request(my_did, schema_data) + schema_response = json.loads(await ledger.sign_and_submit_request( + pool_handle, wallet_handle, my_did, schema_request)) + + seq_no = schema_response['result']['seqNo'] + 1 + + get_txn_request = await ledger.build_get_txn_request(my_did, seq_no) + get_txn_response = json.loads(await ledger.submit_request(pool_handle, get_txn_request)) + assert get_txn_response['result']['data'] == "{}" diff --git a/wrappers/python/tests/pool/test_close_pool_ledger.py b/wrappers/python/tests/pool/test_close_pool_ledger.py new file mode 100644 index 0000000000..39b2823efc --- /dev/null +++ b/wrappers/python/tests/pool/test_close_pool_ledger.py @@ -0,0 +1,19 @@ +from tests.utils import pool, storage +from indy.pool import close_pool_ledger +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_close_pool_ledger_works(): + handle = await pool.create_and_open_pool_ledger("pool_1") + await close_pool_ledger(handle) diff --git a/wrappers/python/tests/pool/test_create_pool_ledger_config.py b/wrappers/python/tests/pool/test_create_pool_ledger_config.py new file mode 100644 index 0000000000..94b0b72391 --- /dev/null +++ b/wrappers/python/tests/pool/test_create_pool_ledger_config.py @@ -0,0 +1,18 @@ +from tests.utils import pool, storage + +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_create_pool_ledger_config_works(): + await pool.create_pool_ledger_config("pool_create") diff --git a/wrappers/python/tests/pool/test_delete_pool_ledger_config.py b/wrappers/python/tests/pool/test_delete_pool_ledger_config.py new file mode 100644 index 0000000000..706a9f343b --- /dev/null +++ b/wrappers/python/tests/pool/test_delete_pool_ledger_config.py @@ -0,0 +1,20 @@ +from tests.utils import pool, storage +from indy.pool import delete_pool_ledger_config +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_delete_pool_ledger_config_works(): + name = "pool_name" + await pool.create_pool_ledger_config(name) + await delete_pool_ledger_config(name) diff --git a/wrappers/python/tests/pool/test_open_pool_ledger.py b/wrappers/python/tests/pool/test_open_pool_ledger.py new file mode 100644 index 0000000000..78b4e9c19a --- /dev/null +++ b/wrappers/python/tests/pool/test_open_pool_ledger.py @@ -0,0 +1,21 @@ +from tests.utils import pool, storage +from indy.pool import open_pool_ledger +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_open_pool_ledger_works(): + name = "pool_create" + await pool.create_pool_ledger_config(name) + pool_handle = await open_pool_ledger(name, "") + assert pool_handle is not None diff --git a/wrappers/python/tests/pool/test_refresh_pool_ledger.py b/wrappers/python/tests/pool/test_refresh_pool_ledger.py new file mode 100644 index 0000000000..6e18f6c03b --- /dev/null +++ b/wrappers/python/tests/pool/test_refresh_pool_ledger.py @@ -0,0 +1,19 @@ +from tests.utils import pool, storage +from indy.pool import refresh_pool_ledger +import pytest +import logging + +logging.basicConfig(level=logging.DEBUG) + + +@pytest.fixture(autouse=True) +def before_after_each(): + storage.cleanup() + yield + storage.cleanup() + + +@pytest.mark.asyncio +async def test_refresh_pool_ledger_works(): + handle = await pool.create_and_open_pool_ledger("pool_1") + await refresh_pool_ledger(handle) diff --git a/wrappers/python/tests/signus/__init__.py b/wrappers/python/tests/signus/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/wrappers/python/tests/signus/test_create_and_store_my_did.py b/wrappers/python/tests/signus/test_create_and_store_my_did.py new file mode 100644 index 0000000000..af0214cb2a --- /dev/null +++ b/wrappers/python/tests/signus/test_create_and_store_my_did.py @@ -0,0 +1,69 @@ +import json + +from indy import IndyError +from indy import signus +from indy.error import ErrorCode + +import base58 +import pytest + +seed = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +expected_verkey = 'CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW' +crypto_type = 'ed25519' +expected_did = 'NcYxiDXkpYi6ov5FcYDi1e' + + +@pytest.mark.asyncio +async def test_create_my_did_works_with_empty_json(wallet_handle): + (did, ver_key, _) = await signus.create_and_store_my_did(wallet_handle, "{}") + assert len(base58.b58decode(did)) == 16 + assert len(base58.b58decode(ver_key)) == 32 + + +@pytest.mark.asyncio +async def test_create_my_did_works_for_seed(wallet_handle): + (did, ver_key, _) = await signus.create_and_store_my_did(wallet_handle, json.dumps({'seed': seed})) + assert expected_did == did + assert expected_verkey == ver_key + + +@pytest.mark.asyncio +async def test_create_my_did_works_as_cid(wallet_handle): + (did, ver_key, _) = await signus.create_and_store_my_did(wallet_handle, json.dumps({'seed': seed, 'cid': True})) + assert expected_verkey == did + assert expected_verkey == ver_key + + +@pytest.mark.asyncio +async def test_create_my_did_works_for_passed_did(wallet_handle): + (did, _, _) = await signus.create_and_store_my_did(wallet_handle, json.dumps({'did': expected_did})) + assert expected_did == did + + +@pytest.mark.asyncio +async def test_create_my_did_works_for_correct_type(wallet_handle): + (did, ver_key, _) = \ + await signus.create_and_store_my_did(wallet_handle, json.dumps({'seed': seed, 'crypto_type': crypto_type})) + assert expected_did == did + assert expected_verkey == ver_key + + +@pytest.mark.asyncio +async def test_create_my_did_works_for_invalid_seed(wallet_handle): + with pytest.raises(IndyError) as e: + await signus.create_and_store_my_did(wallet_handle, json.dumps({'seed': 'aaaaaaaaaaa'})) + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_create_my_did_works_for_invalid_crypto_type(wallet_handle): + with pytest.raises(IndyError) as e: + await signus.create_and_store_my_did(wallet_handle, json.dumps({'crypto_type': 'crypto_type'})) + assert ErrorCode.SignusUnknownCryptoError == e.value.error_code + + +@pytest.mark.asyncio +async def test_create_my_did_works_for_invalid_handle(wallet_handle): + with pytest.raises(IndyError) as e: + await signus.create_and_store_my_did(wallet_handle + 1, '{}') + assert ErrorCode.WalletInvalidHandle == e.value.error_code diff --git a/wrappers/python/tests/signus/test_replace_keys.py b/wrappers/python/tests/signus/test_replace_keys.py new file mode 100644 index 0000000000..5a52fad89c --- /dev/null +++ b/wrappers/python/tests/signus/test_replace_keys.py @@ -0,0 +1,49 @@ +from indy import IndyError +from indy import signus +from indy.error import ErrorCode + +import pytest + + +@pytest.mark.asyncio +async def test_replace_keys_works(wallet_handle): + (did, ver_key, pk) = await signus.create_and_store_my_did(wallet_handle, "{}") + (new_ver_key, new_pk) = await signus.replace_keys(wallet_handle, did, "{}") + assert (new_ver_key != did) and (new_pk != pk) + + +@pytest.mark.asyncio +async def test_replace_keys_works_for_seed(wallet_handle): + (did, ver_key, pk) = await signus.create_and_store_my_did(wallet_handle, "{}") + (new_ver_key, new_pk) = await signus.replace_keys(wallet_handle, did, '{"seed": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}') + assert (new_ver_key != did) and (new_pk != pk) + assert 'CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW' == new_ver_key + +@pytest.mark.asyncio +async def test_replace_keys_works_for_correct_crypto_type(wallet_handle): + (did, ver_key, pk) = await signus.create_and_store_my_did(wallet_handle, "{}") + (new_ver_key, new_pk) = await signus.replace_keys(wallet_handle, did, '{"crypto_type": "ed25519"}') + assert (new_ver_key != did) and (new_pk != pk) + + +@pytest.mark.asyncio +async def test_replace_keys_works_for_invalid_did(wallet_handle): + with pytest.raises(IndyError) as e: + await signus.replace_keys(wallet_handle, 'invalid_base58_string', "{}") + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_replace_keys_works(wallet_handle): + with pytest.raises(IndyError) as e: + (did, _, _) = await signus.create_and_store_my_did(wallet_handle, "{}") + await signus.replace_keys(wallet_handle + 1, did, "{}") + assert ErrorCode.WalletInvalidHandle == e.value.error_code + + +@pytest.mark.asyncio +async def test_replace_keys_works_for_invalid_crypto_type(wallet_handle): + with pytest.raises(IndyError) as e: + (did, _, _) = await signus.create_and_store_my_did(wallet_handle, "{}") + await signus.replace_keys(wallet_handle, did, '{"crypto_type": "type"}') + assert ErrorCode.SignusUnknownCryptoError == e.value.error_code diff --git a/wrappers/python/tests/signus/test_sign.py b/wrappers/python/tests/signus/test_sign.py new file mode 100644 index 0000000000..c6270964b9 --- /dev/null +++ b/wrappers/python/tests/signus/test_sign.py @@ -0,0 +1,49 @@ +from indy import IndyError +from indy import signus +from indy.error import ErrorCode + +import json +import pytest + + +@pytest.mark.asyncio +async def test_sign_works(wallet_handle): + (did, _, _) = await signus.create_and_store_my_did(wallet_handle, '{"seed":"000000000000000000000000Trustee1"}') + + message = json.dumps({ + "reqId": 1496822211362017764, + "identifier": "GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL", + "operation": { + "type": "1", + "dest": "VsKV7grR1BUE29mG2Fm2kX", + "verkey": "GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa" + } + }) + + expected_signature = "65hzs4nsdQsTUqLCLy2qisbKLfwYKZSWoyh1C6CU59p5pfG3EHQXGAsjW4Qw4QdwkrvjSgQuyv8qyABcXRBznFKW" + + signed_msg = json.loads(await signus.sign(wallet_handle, did, message)) + assert signed_msg['signature'] == expected_signature + + +@pytest.mark.asyncio +async def test_sign_works_for_unknown_did(wallet_handle): + with pytest.raises(IndyError) as e: + await signus.sign(wallet_handle, '8wZcEriaNLNKtteJvx7f8i', json.dumps({"reqId": 1496822211362017764})) + assert ErrorCode.WalletNotFoundError == e.value.error_code + + +@pytest.mark.asyncio +async def test_sign_works_for_invalid_message_format(wallet_handle): + with pytest.raises(IndyError) as e: + (did, _, _) = await signus.create_and_store_my_did(wallet_handle, '{}') + await signus.sign(wallet_handle, did, '"reqId":1495034346617224651') + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_sign_works_for_invalid_handle(wallet_handle): + with pytest.raises(IndyError) as e: + (did, _, _) = await signus.create_and_store_my_did(wallet_handle, '{}') + await signus.sign(wallet_handle + 1, did, json.dumps({"reqId": 1496822211362017764})) + assert ErrorCode.WalletInvalidHandle == e.value.error_code diff --git a/wrappers/python/tests/signus/test_store_their_did.py b/wrappers/python/tests/signus/test_store_their_did.py new file mode 100644 index 0000000000..2505e44474 --- /dev/null +++ b/wrappers/python/tests/signus/test_store_their_did.py @@ -0,0 +1,51 @@ +from indy import IndyError +from indy import signus + +import pytest + +from indy.error import ErrorCode + + +@pytest.mark.asyncio +async def test_store_their_did_works(wallet_handle): + await signus.store_their_did(wallet_handle, '{"did":"8wZcEriaNLNKtteJvx7f8i"}') + + +@pytest.mark.asyncio +async def test_store_their_did_works_for_invalid_json(wallet_handle): + with pytest.raises(IndyError) as e: + await signus.store_their_did(wallet_handle, '{"field":"value"}') + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_store_their_did_works_for_invalid_handle(wallet_handle): + with pytest.raises(IndyError) as e: + await signus.store_their_did(wallet_handle + 1, '{"did":"8wZcEriaNLNKtteJvx7f8i"}') + assert ErrorCode.WalletInvalidHandle == e.value.error_code + + +@pytest.mark.asyncio +async def test_store_their_did_works_with_verkey(wallet_handle): + await signus.store_their_did(wallet_handle, '{"did":"8wZcEriaNLNKtteJvx7f8i",' + ' "verkey": "GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa"}') + + +@pytest.mark.asyncio +async def test_store_their_did_works_without_did(wallet_handle): + with pytest.raises(IndyError) as e: + await signus.store_their_did(wallet_handle, '{"verkey": "GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa"}') + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_store_their_did_works_for_correct_crypto_type(wallet_handle): + await signus.store_their_did(wallet_handle, '{"did":"8wZcEriaNLNKtteJvx7f8i", "crypto_type": "ed25519"}') + + +@pytest.mark.asyncio +async def test_store_their_did_works_for_invalid_did(wallet_handle): + with pytest.raises(IndyError) as e: + await signus.store_their_did(wallet_handle, '{"did": "invalid_base58_string"}') + assert ErrorCode.CommonInvalidStructure == e.value.error_code + diff --git a/wrappers/python/tests/signus/test_verify_signature.py b/wrappers/python/tests/signus/test_verify_signature.py new file mode 100644 index 0000000000..62a199bcba --- /dev/null +++ b/wrappers/python/tests/signus/test_verify_signature.py @@ -0,0 +1,160 @@ +import asyncio + +from indy import IndyError +from indy import ledger +from indy import wallet, signus +from indy.error import ErrorCode + +from ..utils.wallet import create_and_open_wallet +from ..utils.pool import create_and_open_pool_ledger + +import json +import pytest + + +@pytest.fixture +async def new_did(wallet_handle, pool_handle): + (trustee_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + + (did, ver_key, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"00000000000000000000000000000My1"}') + + nym_request = await ledger.build_nym_request(trustee_did, did, ver_key, None, None) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, trustee_did, nym_request) + yield did + + +@pytest.mark.asyncio +async def test_verify_works_for_verkey_cached_in_wallet(pool_handle, wallet_handle): + (did, ver_key, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + + await signus.store_their_did(wallet_handle, json.dumps({"did": did, "verkey": ver_key})) + + message = json.dumps({ + "reqId": 1496822211362017764, + "identifier": "GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL", + "operation": { + "type": "1", + "dest": "VsKV7grR1BUE29mG2Fm2kX", + "verkey": "GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa" + }, + "signature": "65hzs4nsdQsTUqLCLy2qisbKLfwYKZSWoyh1C6CU59p5pfG3EHQXGAsjW4Qw4QdwkrvjSgQuyv8qyABcXRBznFKW" + }) + + valid = await signus.verify_signature(wallet_handle, pool_handle, did, message) + assert valid + + +@pytest.mark.asyncio +async def test_verify_works_for_get_verkey_from_ledger(pool_handle, wallet_handle, new_did): + await signus.store_their_did(wallet_handle, json.dumps({"did": new_did})) + + message = '{"reqId":1496822211362017764,' \ + '"signature":"tibTuE59pZn1sCeZpNL5rDzpkpqV3EkDmRpFTizys9Gr3ZieLdGEGyq4h8jsVWW9zSaXSRnfYcVb1yTjUJ7vJai"}' + + valid = await signus.verify_signature(wallet_handle, pool_handle, new_did, message) + assert valid + + +@pytest.mark.asyncio +async def test_verify_works_for_expired_nym(pool_handle, cleanup_storage): + await wallet.create_wallet('pool_1', 'wallet2', None, None, None) + wallet_handle = await wallet.open_wallet('wallet2', '{"freshness_time":1}', None) + + (trustee_did, _, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Trustee1"}') + + (did, ver_key, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"00000000000000000000000000000My1"}') + + nym_request = await ledger.build_nym_request(trustee_did, did, ver_key, None, None) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, trustee_did, nym_request) + + await signus.store_their_did(wallet_handle, json.dumps({"did": did, 'verkey': ver_key})) + + message = '{"reqId":1496822211362017764,' \ + '"signature":"tibTuE59pZn1sCeZpNL5rDzpkpqV3EkDmRpFTizys9Gr3ZieLdGEGyq4h8jsVWW9zSaXSRnfYcVb1yTjUJ7vJai"}' + + await asyncio.sleep(2) + + valid = await signus.verify_signature(wallet_handle, pool_handle, did, message) + assert valid + + wallet.close_wallet(wallet_handle) + + +@pytest.mark.asyncio +async def test_verify_works_for_invalid_wallet(pool_handle, wallet_handle, new_did): + with pytest.raises(IndyError) as e: + message = '{"reqId":1496822211362017764,' \ + '"signature":"tibTuE59pZn1sCeZpNL5rDzpkpqV3EkDmRpFTizys9Gr3ZieLdGEGyq4h8jsVWW9zSaXSRnfYcVb1yTjUJ7vJai"}' + await signus.verify_signature(wallet_handle + 1, pool_handle, new_did, message) + assert ErrorCode.WalletInvalidHandle == e.value.error_code + + +@pytest.mark.asyncio +async def test_verify_works_for_invalid_pool(pool_handle, wallet_handle, new_did): + with pytest.raises(IndyError) as e: + message = '{"reqId":1496822211362017764,' \ + '"signature":"tibTuE59pZn1sCeZpNL5rDzpkpqV3EkDmRpFTizys9Gr3ZieLdGEGyq4h8jsVWW9zSaXSRnfYcVb1yTjUJ7vJai"}' + await signus.verify_signature(wallet_handle, pool_handle + 1, new_did, message) + assert ErrorCode.PoolLedgerInvalidPoolHandle == e.value.error_code + + +@pytest.mark.asyncio +async def test_verify_works_for_other_signer(pool_handle, wallet_handle, new_did): + (did, ver_key, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"000000000000000000000000Steward1"}') + + await signus.store_their_did(wallet_handle, json.dumps({"did": did, "verkey": ver_key})) + + message = json.dumps({ + "reqId": 1496822211362017764, + "identifier": "GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL", + "operation": { + "type": "1", + "dest": "VsKV7grR1BUE29mG2Fm2kX", + "verkey": "GjZWsBLgZCR18aL468JAT7w9CZRiBnpxUPPgyQxh4voa" + }, + "signature": "65hzs4nsdQsTUqLCLy2qisbKLfwYKZSWoyh1C6CU59p5pfG3EHQXGAsjW4Qw4QdwkrvjSgQuyv8qyABcXRBznFKW" + }) + + valid = await signus.verify_signature(wallet_handle, pool_handle, did, message) + assert not valid + + +@pytest.mark.asyncio +async def test_verify_works_for_invalid_message_format(pool_handle, wallet_handle, new_did): + with pytest.raises(IndyError) as e: + message = '"reqId":1496822211362017764,' \ + '"signature":"tibTuE59pZn1sCeZpNL5rDzpkpqV3EkDmRpFTizys9Gr3ZieLdGEGyq4h8jsVWW9zSaXSRnfYcVb1yTjUJ7vJai"' + await signus.verify_signature(wallet_handle, pool_handle, new_did, message) + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_verify_works_for_message_without_signature(pool_handle, wallet_handle, new_did): + with pytest.raises(IndyError) as e: + await signus.verify_signature(wallet_handle, pool_handle, new_did, '{"reqId":1496822211362017764}') + assert ErrorCode.CommonInvalidStructure == e.value.error_code + + +@pytest.mark.asyncio +async def test_verify_works_for_get_nym_from_ledger_with_incompatible_wallet(cleanup_storage): + with pytest.raises(IndyError) as e: + pool_handle = await create_and_open_pool_ledger("pool_name") + wallet_handle = await create_and_open_wallet("other_pool_name") + + (did, ver_key, _) = await signus.create_and_store_my_did(wallet_handle, + '{"seed":"00000000000000000000000000000My1"}') + + await signus.store_their_did(wallet_handle, json.dumps({"did": did})) + + message = '{"reqId":1496822211362017764,' \ + '"signature":"tibTuE59pZn1sCeZpNL5rDzpkpqV3EkDmRpFTizys9Gr3ZieLdGEGyq4h8jsVWW9zSaXSRnfYcVb1yTjUJ7vJai"}' + + await signus.verify_signature(wallet_handle, pool_handle, did, message) + + assert ErrorCode.WalletIncompatiblePoolError == e.value.error_code diff --git a/wrappers/python/tests/test_wallet.py b/wrappers/python/tests/test_wallet.py deleted file mode 100644 index 365b78142d..0000000000 --- a/wrappers/python/tests/test_wallet.py +++ /dev/null @@ -1,11 +0,0 @@ -import asyncio - -from sovrin import * - -async def main(): - await Wallet.create_wallet(None, "wallet", "wallet-type", "config", "creds") - - -loop = asyncio.get_event_loop() -loop.run_until_complete(main()) -loop.close() diff --git a/wrappers/python/tests/utils/__init__.py b/wrappers/python/tests/utils/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/wrappers/python/tests/utils/anoncreds.py b/wrappers/python/tests/utils/anoncreds.py new file mode 100644 index 0000000000..a02df9f0f6 --- /dev/null +++ b/wrappers/python/tests/utils/anoncreds.py @@ -0,0 +1,120 @@ +from indy import anoncreds + +import json + +ISSUER_DID = "NcYxiDXkpYi6ov5FcYDi1e" +COMMON_SCHEMA_SEQ_NO = 1 +COMMON_MASTER_SECRET_NAME = "common_master_secret_name" +COMMON_MASTER_SECRET_NAME_1 = "common_master_secret_name_1" + + +async def prepare_common_wallet(wallet_handle): + schema = get_gvt_schema_json(1) + claim_def_json = await anoncreds.issuer_create_and_store_claim_def( + wallet_handle, ISSUER_DID, json.dumps(schema), None, False) + + claim_offer_json_1 = get_claim_offer(ISSUER_DID, 1) + claim_offer_json_2 = get_claim_offer(ISSUER_DID, 2) + claim_offer_json_3 = get_claim_offer("CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW", 2) + await anoncreds.prover_store_claim_offer(wallet_handle, json.dumps(claim_offer_json_1)) + await anoncreds.prover_store_claim_offer(wallet_handle, json.dumps(claim_offer_json_2)) + await anoncreds.prover_store_claim_offer(wallet_handle, json.dumps(claim_offer_json_3)) + await anoncreds.prover_create_master_secret(wallet_handle, COMMON_MASTER_SECRET_NAME) + + claim_req = await anoncreds.prover_create_and_store_claim_req( + wallet_handle, "HEJ9gvWX64wW7UD", json.dumps(claim_offer_json_1), claim_def_json, COMMON_MASTER_SECRET_NAME) + (_, claim_json) = await anoncreds.issuer_create_claim( + wallet_handle, claim_req, json.dumps(get_gvt_claim_json()), -1, -1) + await anoncreds.prover_store_claim(wallet_handle, claim_json) + + return claim_def_json + + +def get_claim_offer(issuer_did, schema_seq_no): + return {"issuer_did": issuer_did, "schema_seq_no": schema_seq_no} + + +def get_gvt_schema_json(schema_seq_no: int): + return { + "seqNo": schema_seq_no, + "data": { + "name": "gvt", + "version": "1.0", + "keys": ["age", "sex", "height", "name"] + } + } + + +def get_gvt_claim_json(): + return { + "sex": ["male", "5944657099558967239210949258394887428692050081607692519917050011144233115103"], + "name": ["Alex", "1139481716457488690172217916278103335"], + "height": ["175", "175"], + "age": ["28", "28"] + } + + +def get_xyz_claim_json(): + return { + "status": ["partial", "51792877103171595686471452153480627530895"], + "period": ["8", "8"] + } + + +def get_claim_req(): + return {"blinded_ms": {"prover_did": "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW", + "u": "541727375645293327107242131390489410830131768916446771173223218236303087346206273292" + "275918450941006362568297619591573147842939390451766213271549909084590728218268187187" + "396963232997879281735355290245565403237095788507069932942349664408266908992668726827" + "902285139739992123705745482398771085112836294238073386324354310973398756650754537851" + "417229890983878959703959824327090115058645337274155525667150696753462207525844495604" + "072614465677317118141888367033373659867254296561952756168465435357073642154989807508" + "60746440672050640048215761507774996460985293327604627646056062013419674090094698841" + "792968543317468164175921100038", + "ur": None}, "issuer_did": ISSUER_DID, "schema_seq_no": 1} + + +def get_proof_req(predicate_value=18): + return { + "nonce": "123432421212", + "name": "proof_req_1", + "version": "0.1", + "requested_attrs": { + "attr1_uuid": + { + "schema_seq_no": 1, + "name": "name" + } + }, + "requested_predicates": { + "predicate1_uuid": { + "attr_name": "age", + "p_type": "GE", + "value": predicate_value + } + } + } + + +def get_claim_def(): + return { + "ref": 1, + "signature_type": "CL", + "origin": ISSUER_DID, + "data": { + "primary": { + "n": "94759924268422840873493186881483285628376767714620627055233230078254863658476446487556117977593248501523199451418346650764648601684276437772084327637083000213497377603495837360299641742248892290843802071224822481683143989223918276185323177379400413928352871249494885563503003839960930062341074783742062464846448855510814252519824733234277681749977392772900212293652238651538092092030867161752390937372967233462027620699196724949212432236376627703446877808405786247217818975482797381180714523093913559060716447170497587855871901716892114835713057965087473682457896508094049813280368069805661739141591558517233009123957", + "s": "3589207374161609293256840431433442367968556468254553005135697551692970564853243905310862234226531556373974144223993822323573625466428920716249949819187529684239371465431718456502388533731367046146704547241076626874082510133130124364613881638153345624380195335138152993132904167470515345775215584510356780117368593105284564368954871044494967246738070895990267205643985529060025311535539534155086912661927003271053443110788963970349858709526217650537936123121324492871282397691771309596632805099306241616501610166028401599243350835158479028294769235556557248339060399322556412171888114265194198405765574333538019124846", + "rms": "57150374376895616256492932008792437185713712934712117819417607831438470701645904776986426606717466732609284990796923331049549544903261623636958698296956103821068569714644825742048584174696465882627177060166162341112552851798863535031243458188976013190131935905789786836375734914391914349188643340535242562896244661798678234667651641013894284156416773868299435641426810968290584996112925365638881750944407842890875840705650290814965768221299488400872767679122749231050406680432079499973527780212310700022178178822528199576164498116369689770884051691678056831493476045361227274839673581033532995523269047577973637307053", + "r": { + "age": "94304485801056920773231824603827244147437820123357994068540328541540143488826838939836897544389872126768239056314698953816072289663428273075648246498659039419931054256171488371404693243192741923382499918184822032756852725234903892700640856294525441486319095181804549558538523888770076173572615957495813339649470619615099181648313548341951673407624414494737018574238782648822189142664108450534642272145962844003886059737965854042074083374478426875684184904488545593139633653407062308621502392373426120986761417580127895634822264744063122368296502161439648408926687989964483291459079738447940651025900007635890755686910", + "sex": "29253365609829921413347591854991689007250272038394995372767401325848195298844802462252851926995846503104090589196060683329875231216529049681648909174047403783834364995363938741001507091534282239210301727771803410513303526378812888571225762557471133950393342500638551458868147905023198508660460641434022020257614450354085808398293279060446966692082427506909617283562394303716193372887306176319841941848888379308208426966697446699225783646634631703732019477632822374479322570142967559738439193417309205283438893083349863592921249218168590490390313109776446516881569691499831380592661740653935515397472059631417493981532", + "name": "25134437486609445980011967476486104706321061312022352268621323694861467756181853100693555519614894168921947814126694858839278103549577703105305116890325322098078409416441750313062396467567140699008203113519528887729951138845002409659317083029073793314514377377412805387401717457417895322600145580639449003584446356048213839274172751441145076183734269045919984853749007476629365146654240675320041155618450449041510280560040162429566008590065069477149918088087715269037925211599101597422023202484497946662159070023999719865939258557778022770035320019440597702090334486792710436579355608406897769514395306079855023848170", + "height": "59326960517737425423547279838932030505937927873589489863081026714907925093402287263487670945897247474465655528290016645774365383046524346223348261262488616342337864633104758662753452450299389775751012589698563659277683974188553993694220606310980581680471280640591973543996299789038056921309016983827578247477799948667666717056420270448516049047961099547588510086600581628091290215485826514170097211360599793229701811672966818089371089216189744274422526431130783428589346341196561742409198605034972210917502326180305735092988639850309253190875578501020679137562856724998821945605494355779034135306337094344532980411836" + }, + "rctxt": "9641986614889199796257508700106896585587271615330980339636468819377346498767697681332046156705231986464570206666984343024200482683981302064613556104594051003956610353281701880542337665385482309134369756144345334575765116656633321636736946947493150642615481313285221467998414924865943067790561494301461899025374692884841352282256044388512875752628313052128404892424405230961678931620525106856624692942373538946467902799339061714326383378018581568876147181355325663707572429090278505823900491548970098691127791086305310899642155499128171811034581730190877600697624903963241473287185133286356124371104261592694271730029", + "z": "77594127026421654059198621152153180600664927707984020918609426112642522289621323453889995053400171879296098965678384769043918218957929606187082395048777546641833348694470081024386996548890150355901703252426977094536933434556202865213941384425538749866521536494046548509344678288447175898173634381514948562261015286492185924659638474376885655055568341574638453213864956407243206035973349529545863886325462867413885904072942842465859476940638839087894582648849969332663627779378998245133055807038199937421971988505911494931665143822588532097754480882750243126847177560978100527491344463525107644125030963904001009159559" + }, + "revocation": None + } + } diff --git a/wrappers/python/tests/utils/pool.py b/wrappers/python/tests/utils/pool.py new file mode 100644 index 0000000000..cdb40f8ade --- /dev/null +++ b/wrappers/python/tests/utils/pool.py @@ -0,0 +1,41 @@ +from .storage import indy_temp_path, create_temp_dir +from indy import pool + +import json + + +async def create_pool_ledger_config(config_name, nodes=None, pool_config=None, gen_txn_file_name=None): + file_name = gen_txn_file_name or (config_name + '.txn') + path = create_genesis_txn_file(file_name, nodes) + + pool_config = json.dumps(pool_config or {"genesis_txn": str(path)}) + await pool.create_pool_ledger_config(config_name, pool_config) + + +def create_genesis_txn_file(file_name, predefined_data=None): + path = indy_temp_path().joinpath(file_name) + + default_txn = [ + "{\"data\":{\"alias\":\"Node1\",\"client_ip\":\"10.0.0.2\",\"client_port\":9702,\"node_ip\":\"10.0.0.2\",\"node_port\":9701,\"services\":[\"VALIDATOR\"]},\"dest\":\"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv\",\"identifier\":\"Th7MpTaRZVRYnPiabds81Y\",\"txnId\":\"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62\",\"type\":\"0\"}\n", + "{\"data\":{\"alias\":\"Node2\",\"client_ip\":\"10.0.0.2\",\"client_port\":9704,\"node_ip\":\"10.0.0.2\",\"node_port\":9703,\"services\":[\"VALIDATOR\"]},\"dest\":\"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb\",\"identifier\":\"EbP4aYNeTHL6q385GuVpRV\",\"txnId\":\"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc\",\"type\":\"0\"}\n", + "{\"data\":{\"alias\":\"Node3\",\"client_ip\":\"10.0.0.2\",\"client_port\":9706,\"node_ip\":\"10.0.0.2\",\"node_port\":9705,\"services\":[\"VALIDATOR\"]},\"dest\":\"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya\",\"identifier\":\"4cU41vWW82ArfxJxHkzXPG\",\"txnId\":\"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4\",\"type\":\"0\"}\n", + "{\"data\":{\"alias\":\"Node4\",\"client_ip\":\"10.0.0.2\",\"client_port\":9708,\"node_ip\":\"10.0.0.2\",\"node_port\":9707,\"services\":[\"VALIDATOR\"]},\"dest\":\"4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA\",\"identifier\":\"TWwCRQRZ2ZHMJFn9TzLp7W\",\"txnId\":\"aa5e817d7cc626170eca175822029339a444eb0ee8f0bd20d3b0b76e566fb008\",\"type\":\"0\"}\n" + ] + + create_temp_dir() + + with open(str(path), "w+") as f: + f.writelines(predefined_data or default_txn) + + return path + + +async def create_and_open_pool_ledger(name="pool_1"): + await create_pool_ledger_config(name) + pool_handle = await pool.open_pool_ledger(name, "") + assert pool_handle is not None + return pool_handle + + +async def close_pool_ledger(pool_handle): + await pool.close_pool_ledger(pool_handle) diff --git a/wrappers/python/tests/utils/storage.py b/wrappers/python/tests/utils/storage.py new file mode 100644 index 0000000000..5a3c214383 --- /dev/null +++ b/wrappers/python/tests/utils/storage.py @@ -0,0 +1,49 @@ +from pathlib import Path +from shutil import rmtree +from tempfile import gettempdir + +import os +import logging + + +def indy_temp_path() -> Path: + logger = logging.getLogger(__name__) + logger.debug("indy_temp_path: >>>") + + res = Path(gettempdir()).joinpath("indy") + + logger.debug("indy_temp_path: <<< res: %s", res) + return res + + +def indy_home_path() -> Path: + logger = logging.getLogger(__name__) + logger.debug("indy_home_path: >>>") + + res = Path.home().joinpath(".indy") + + logger.debug("indy_home_path: <<< res: %s", res) + return res + + +def create_temp_dir(): + os.makedirs(str(indy_temp_path())) + + +def cleanup(): + logger = logging.getLogger(__name__) + logger.debug("cleanup: >>>") + + tmp_path = indy_temp_path() + + if tmp_path.exists(): + logger.debug("cleanup: Cleaning tmp path: %s", tmp_path) + rmtree(str(tmp_path)) + + home_path = indy_home_path() + + if home_path.exists(): + logger.debug("cleanup: Cleaning home path: %s", home_path) + rmtree(str(home_path)) + + logger.debug("cleanup: <<<") diff --git a/wrappers/python/tests/utils/test_storage.py b/wrappers/python/tests/utils/test_storage.py new file mode 100644 index 0000000000..0fab92ce70 --- /dev/null +++ b/wrappers/python/tests/utils/test_storage.py @@ -0,0 +1,20 @@ +from .storage import indy_home_path, indy_temp_path, cleanup + +import logging + +logging.basicConfig(level=logging.DEBUG) + + +def test_storage_utils_indy_home_path_works(): + home_path = indy_home_path() + assert '.indy' in str(home_path) + + +def test_storage_utils_indy_temp_path_works(): + tmp_path = indy_temp_path() + assert 'indy' in str(tmp_path) + + +def test_storage_utils_cleanup_works(): + cleanup() + assert True diff --git a/wrappers/python/tests/utils/wallet.py b/wrappers/python/tests/utils/wallet.py new file mode 100644 index 0000000000..883ba78bc3 --- /dev/null +++ b/wrappers/python/tests/utils/wallet.py @@ -0,0 +1,11 @@ +from indy import wallet + +async def create_and_open_wallet(pool_name="pool_1", wallet_name="wallet_1"): + await wallet.create_wallet(pool_name, wallet_name, None, None, None) + wallet_handle = await wallet.open_wallet(wallet_name, None, None) + assert wallet_handle is not None + return wallet_handle + + +async def close_wallet(wallet_handle): + await wallet.close_wallet(wallet_handle) diff --git a/wrappers/python/tests/wallet/__init__.py b/wrappers/python/tests/wallet/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/wrappers/python/tests/wallet/test_close_wallet.py b/wrappers/python/tests/wallet/test_close_wallet.py new file mode 100644 index 0000000000..77df5e591e --- /dev/null +++ b/wrappers/python/tests/wallet/test_close_wallet.py @@ -0,0 +1,28 @@ +from indy import IndyError +from indy import wallet +from indy.error import ErrorCode + +import pytest + + +@pytest.mark.asyncio +async def test_close_wallet_works(cleanup_storage): + await wallet.create_wallet('pool1', 'wallet_1', None, None, None) + + wallet_handle = await wallet.open_wallet('wallet_1', None, None) + await wallet.close_wallet(wallet_handle) + + wallet_handle = await wallet.open_wallet('wallet_1', None, None) + await wallet.close_wallet(wallet_handle) + + +@pytest.mark.asyncio +async def test_close_wallet_works_for_twice(cleanup_storage): + with pytest.raises(IndyError) as e: + await wallet.create_wallet('pool1', 'wallet_for_twice', None, None, None) + + wallet_handle = await wallet.open_wallet('wallet_for_twice', None, None) + await wallet.close_wallet(wallet_handle) + await wallet.close_wallet(wallet_handle) + + assert ErrorCode.WalletInvalidHandle == e.value.error_code diff --git a/wrappers/python/tests/wallet/test_create_wallet.py b/wrappers/python/tests/wallet/test_create_wallet.py new file mode 100644 index 0000000000..924fa3cca1 --- /dev/null +++ b/wrappers/python/tests/wallet/test_create_wallet.py @@ -0,0 +1,42 @@ +from indy import IndyError +from indy import wallet +from indy.error import ErrorCode + +import pytest + + +@pytest.mark.asyncio +async def test_create_wallet_works(cleanup_storage): + await wallet.create_wallet('pool1', 'wallet1', 'default', None, None) + + +@pytest.mark.asyncio +async def test_create_wallet_works_for_empty_type(cleanup_storage): + await wallet.create_wallet('pool1', 'wallet1', None, None, None) + + +@pytest.mark.asyncio +async def test_create_wallet_works_for_config_json(cleanup_storage): + await wallet.create_wallet('pool1', 'wallet3', 'default', '{"freshness_time":1000}', None) + + +@pytest.mark.asyncio +async def test_create_wallet_works_for_unknown_type(cleanup_storage): + with pytest.raises(IndyError) as e: + await wallet.create_wallet('pool1', 'wallet3', 'unknown_type', None, None) + assert ErrorCode.WalletUnknownTypeError == e.value.error_code + + +@pytest.mark.asyncio +async def test_create_wallet_works_for_empty_name(cleanup_storage): + with pytest.raises(IndyError) as e: + await wallet.create_wallet('pool1', '', 'default', None, None) + assert ErrorCode.CommonInvalidParam3 == e.value.error_code + + +@pytest.mark.asyncio +async def test_create_wallet_works_for_duplicate_name(cleanup_storage): + with pytest.raises(IndyError) as e: + await wallet.create_wallet('pool1', 'wallet4', 'default', None, None) + await wallet.create_wallet('pool1', 'wallet4', 'default', None, None) + assert ErrorCode.WalletAlreadyExistsError == e.value.error_code diff --git a/wrappers/python/tests/wallet/test_delete_wallet.py b/wrappers/python/tests/wallet/test_delete_wallet.py new file mode 100644 index 0000000000..ff0c5bdbe1 --- /dev/null +++ b/wrappers/python/tests/wallet/test_delete_wallet.py @@ -0,0 +1,46 @@ +from indy import IndyError +from indy import wallet +from indy.error import ErrorCode + +import pytest + + +@pytest.mark.asyncio +async def test_delete_wallet_works(cleanup_storage): + await wallet.create_wallet('pool1', 'wallet_1', None, None, None) + await wallet.delete_wallet('wallet_1', None) + await wallet.create_wallet('pool1', 'wallet_1', None, None, None) + + +@pytest.mark.asyncio +async def test_delete_wallet_works_for_closed(cleanup_storage): + await wallet.create_wallet('pool1', 'wallet_1', None, None, None) + wallet_handle = await wallet.open_wallet('wallet_1', None, None) + await wallet.close_wallet(wallet_handle) + await wallet.delete_wallet('wallet_1', None) + await wallet.create_wallet('pool1', 'wallet_1', None, None, None) + + +@pytest.mark.skip(reason="There is BUG in indy-sdk") +async def test_delete_wallet_works_for_opened(cleanup_storage): + with pytest.raises(IndyError) as e: + await wallet.create_wallet('pool1', 'wallet_for_opened', None, None, None) + await wallet.open_wallet('wallet_for_opened', None, None) + await wallet.delete_wallet('wallet_for_opened', None) + assert ErrorCode.CommonIOError == e.value.error_code + + +@pytest.mark.asyncio +async def test_delete_wallet_works_for_twice(cleanup_storage): + with pytest.raises(IndyError) as e: + await wallet.create_wallet('pool1', 'wallet_for_twice', None, None, None) + await wallet.delete_wallet('wallet_for_twice', None) + await wallet.delete_wallet('wallet_for_twice', None) + assert ErrorCode.CommonIOError == e.value.error_code + + +@pytest.mark.asyncio +async def test_delete_wallet_works_for_not_created(cleanup_storage): + with pytest.raises(IndyError) as e: + await wallet.delete_wallet('wallet_not_created', None) + assert ErrorCode.CommonIOError == e.value.error_code \ No newline at end of file diff --git a/wrappers/python/tests/wallet/test_open_wallet.py b/wrappers/python/tests/wallet/test_open_wallet.py new file mode 100644 index 0000000000..72e72738a7 --- /dev/null +++ b/wrappers/python/tests/wallet/test_open_wallet.py @@ -0,0 +1,39 @@ +from indy import IndyError +from indy import wallet +from indy.error import ErrorCode + +import pytest + + +@pytest.mark.asyncio +async def test_open_wallet_works(cleanup_storage): + await wallet.create_wallet('pool1', 'wallet1', None, None, None) + wallet_handle = await wallet.open_wallet('wallet1', None, None) + assert wallet_handle is not None + + await wallet.close_wallet(wallet_handle) + + +@pytest.mark.asyncio +async def test_open_wallet_works_for_config(cleanup_storage): + await wallet.create_wallet('pool1', 'wallet1', None, None, None) + wallet_handle = await wallet.open_wallet('wallet1', '{"freshness_time":1000}', None) + assert wallet_handle is not None + + await wallet.close_wallet(wallet_handle) + + +@pytest.mark.asyncio +async def test_open_wallet_works_for_not_created_wallet(cleanup_storage): + with pytest.raises(IndyError) as e: + await wallet.open_wallet('wallet_not_created', None, None) + assert ErrorCode.CommonIOError == e.value.error_code + + +@pytest.mark.asyncio +async def test_open_wallet_works_for_twice(cleanup_storage): + with pytest.raises(IndyError) as e: + await wallet.create_wallet('pool1', 'wallet_twice', None, None, None) + await wallet.open_wallet('wallet_twice', None, None) + await wallet.open_wallet('wallet_twice', None, None) + assert ErrorCode.WalletAlreadyOpenedError == e.value.error_code \ No newline at end of file