diff --git a/README.md b/README.md index 6fda756f..dca4d01e 100644 --- a/README.md +++ b/README.md @@ -1,73 +1,28 @@ -[//]: # (SPDX-License-Identifier: CC-BY-4.0) -# Hyperledger Fabric Samples - -You can use Fabric samples to get started working with Hyperledger Fabric, explore important Fabric features, and learn how to build applications that can interact with blockchain networks using the Fabric SDKs. To learn more about Hyperledger Fabric, visit the [Fabric documentation](https://hyperledger-fabric.readthedocs.io/en/latest). - -Note that this branch contains samples for the latest Fabric release. For older Fabric versions, refer to the corresponding branches: - -- [release-2.2](https://github.com/hyperledger/fabric-samples/tree/release-2.2) -- [release-1.4](https://github.com/hyperledger/fabric-samples/tree/release-1.4) - -## Getting started with the Fabric samples - -To use the Fabric samples, you need to download the Fabric Docker images and the Fabric CLI tools. First, make sure that you have installed all of the [Fabric prerequisites](https://hyperledger-fabric.readthedocs.io/en/latest/prereqs.html). You can then follow the instructions to [Install the Fabric Samples, Binaries, and Docker Images](https://hyperledger-fabric.readthedocs.io/en/latest/install.html) in the Fabric documentation. In addition to downloading the Fabric images and tool binaries, the Fabric samples will also be cloned to your local machine. - -## Test network - -The [Fabric test network](test-network) in the samples repository provides a Docker Compose based test network with two -Organization peers and an ordering service node. You can use it on your local machine to run the samples listed below. -You can also use it to deploy and test your own Fabric chaincodes and applications. To get started, see -the [test network tutorial](https://hyperledger-fabric.readthedocs.io/en/latest/test_network.html). - -The [Kubernetes Test Network](test-network-k8s) sample builds upon the Compose network, constructing a Fabric -network with peer, orderer, and CA infrastructure nodes running on Kubernetes. In addition to providing a sample -Kubernetes guide, the Kube test network can be used as a platform to author and debug _cloud ready_ Fabric Client -applications on a development or CI workstation. +# Required: +Docker +GO lang +Node 16 -## Asset transfer samples and tutorials +# Network Startup -The asset transfer series provides a series of sample smart contracts and applications to demonstrate how to store and transfer assets using Hyperledger Fabric. -Each sample and associated tutorial in the series demonstrates a different core capability in Hyperledger Fabric. The **Basic** sample provides an introduction on how -to write smart contracts and how to interact with a Fabric network using the Fabric SDKs. The **Ledger queries**, **Private data**, and **State-based endorsement** -samples demonstrate these additional capabilities. Finally, the **Secured agreement** sample demonstrates how to bring all the capabilities together to securely -transfer an asset in a more realistic transfer scenario. +cd test-network -| **Smart Contract** | **Description** | **Tutorial** | **Smart contract languages** | **Application languages** | -| -----------|------------------------------|----------|---------|---------| -| [Basic](asset-transfer-basic) | The Basic sample smart contract that allows you to create and transfer an asset by putting data on the ledger and retrieving it. This sample is recommended for new Fabric users. | [Writing your first application](https://hyperledger-fabric.readthedocs.io/en/latest/write_first_app.html) | Go, JavaScript, TypeScript, Java | Go, TypeScript, Java | -| [Ledger queries](asset-transfer-ledger-queries) | The ledger queries sample demonstrates range queries and transaction updates using range queries (applicable for both LevelDB and CouchDB state databases), and how to deploy an index with your chaincode to support JSON queries (applicable for CouchDB state database only). | [Using CouchDB](https://hyperledger-fabric.readthedocs.io/en/latest/couchdb_tutorial.html) | Go, JavaScript | Java, JavaScript | -| [Private data](asset-transfer-private-data) | This sample demonstrates the use of private data collections, how to manage private data collections with the chaincode lifecycle, and how the private data hash can be used to verify private data on the ledger. It also demonstrates how to control asset updates and transfers using client-based ownership and access control. | [Using Private Data](https://hyperledger-fabric.readthedocs.io/en/latest/private_data_tutorial.html) | Go, TypeScript, Java | TypeScript | -| [State-Based Endorsement](asset-transfer-sbe) | This sample demonstrates how to override the chaincode-level endorsement policy to set endorsement policies at the key-level (data/asset level). | [Using State-based endorsement](https://github.com/hyperledger/fabric-samples/tree/main/asset-transfer-sbe) | Java, TypeScript | JavaScript | -| [Secured agreement](asset-transfer-secured-agreement) | Smart contract that uses implicit private data collections, state-based endorsement, and organization-based ownership and access control to keep data private and securely transfer an asset with the consent of both the current owner and buyer. | [Secured asset transfer](https://hyperledger-fabric.readthedocs.io/en/latest/secured_asset_transfer/secured_private_asset_transfer_tutorial.html) | Go | TypeScript | -| [Events](asset-transfer-events) | The events sample demonstrates how smart contracts can emit events that are read by the applications interacting with the network. | [README](asset-transfer-events/README.md) | Go, JavaScript, Java | Go, TypeScript, Java | -| [Attribute-based access control](asset-transfer-abac) | Demonstrates the use of attribute and identity based access control using a simple asset transfer scenario | [README](asset-transfer-abac/README.md) | Go | _None_ | +./network.sh up createChannel -c mychannel -ca -## Full stack asset transfer guide - -The [full stack asset transfer guide](full-stack-asset-transfer-guide#readme) workshop demonstrates how a generic asset transfer solution for Hyperledger Fabric can be developed and deployed. This covers chaincode development, client application development, and deployment to a production-like environment. - -## Additional samples - -Additional samples demonstrate various Fabric use cases and application patterns. - -| **Sample** | **Description** | **Documentation** | -| -------------|------------------------------|------------------| -| [Off chain data](off_chain_data) | Learn how to use block events to build an off-chain database for reporting and analytics. | [Peer channel-based event services](https://hyperledger-fabric.readthedocs.io/en/latest/peer_event_services.html) | -| [Token SDK](token-sdk) | Sample REST API around the Hyperledger Labs [Token SDK](https://github.com/hyperledger-labs/fabric-token-sdk) for privacy friendly (zero knowledge proof) UTXO transactions. | [README](token-sdk/README.md) | -| [Token ERC-20](token-erc-20) | Smart contract demonstrating how to create and transfer fungible tokens using an account-based model. | [README](token-erc-20/README.md) | -| [Token UTXO](token-utxo) | Smart contract demonstrating how to create and transfer fungible tokens using a UTXO (unspent transaction output) model. | [README](token-utxo/README.md) | -| [Token ERC-1155](token-erc-1155) | Smart contract demonstrating how to create and transfer multiple tokens (both fungible and non-fungible) using an account based model. | [README](token-erc-1155/README.md) | -| [Token ERC-721](token-erc-721) | Smart contract demonstrating how to create and transfer non-fungible tokens using an account-based model. | [README](token-erc-721/README.md) | -| [High throughput](high-throughput) | Learn how you can design your smart contract to avoid transaction collisions in high volume environments. | [README](high-throughput/README.md) | -| [Simple Auction](auction-simple) | Run an auction where bids are kept private until the auction is closed, after which users can reveal their bid. | [README](auction-simple/README.md) | -| [Dutch Auction](auction-dutch) | Run an auction in which multiple items of the same type can be sold to more than one buyer. This example also includes the ability to add an auditor organization. | [README](auction-dutch/README.md) | +./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-typescript/ -ccl typescript -## License +# Backend Startup -Hyperledger Project source code files are made available under the Apache -License, Version 2.0 (Apache-2.0), located in the [LICENSE](LICENSE) file. -Hyperledger Project documentation files are made available under the Creative -Commons Attribution 4.0 International License (CC-BY-4.0), available at http://creativecommons.org/licenses/by/4.0/. +cd asset-transfer-basic/rest-api-typescript + +TEST_NETWORK_HOME=/home/calvin/go/src/github.com/delete_me0/sandbx/fabric-samples/test-network npm run generateEnv + +export REDIS_PASSWORD=$(uuidgen) +npm run start:redis + +npm run build + +npm run start:dev diff --git a/StudentDBInit.txt b/StudentDBInit.txt new file mode 100644 index 00000000..a32fdeb3 --- /dev/null +++ b/StudentDBInit.txt @@ -0,0 +1,29 @@ + +Required: +Docker +GO lang +Node 16 + + +#Network Startup + +cd test-network + +./network.sh up createChannel -c mychannel -ca + +./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-typescript/ -ccl typescript + + + +#Backend Startup + +cd asset-transfer-basic/rest-api-typescript + +TEST_NETWORK_HOME=/home/calvin/go/src/github.com/delete_me0/sandbx/fabric-samples/test-network npm run generateEnv + +export REDIS_PASSWORD=$(uuidgen) +npm run start:redis + +npm run build + +npm run start:dev diff --git a/asset-transfer-abac/README.md b/asset-transfer-abac/README.md deleted file mode 100644 index 09cb106c..00000000 --- a/asset-transfer-abac/README.md +++ /dev/null @@ -1,173 +0,0 @@ -# Attribute based access control - -The `asset-transfer-abac` sample demonstrates the use of Attribute-based access control within the context of a simple asset transfer scenario. The sample also uses authorization based on individual client identities to allow the users that interact with the network to own assets on the blockchain ledger. - -Attribute-Based Access Control (ABAC) refers to the ability to restrict access to certain functionality within a smart contract based on the attributes within a users certificate. For example, you may want certain functions within a smart contract to be used only by application administrators. ABAC allows organizations to provide elevated access to certain users without requiring those users be administrators of the network. For more information, see [Attribute-based access control](https://hyperledger-fabric-ca.readthedocs.io/en/latest/users-guide.html#attribute-based-access-control) in the Fabric CA users guide. - -The `asset-transfer-abac` smart contract allows you to create assets that can be updated or transferred by the asset owner. However, the ability to create or remove assets from the ledger is restricted to identities with the `abac.creator=true` attribute. The identity that creates the asset is assigned as the asset owner. Only the owner can transfer the asset to a new owner or update the asset properties. In the course of the tutorial, we will use the Fabric CA client to create identities with the attribute required to create a new asset. We will then transfer the asset to another identity and demonstrate how the `GetID()` function can be used to enforce asset ownership. We will then use the owner identity to delete the asset. Both Attribute based access control and the `GetID()` function are provided by the [Client Identity Chaincode Library](https://github.com/hyperledger/fabric-chaincode-go/blob/master/pkg/cid/README.md). - -## Start the network and deploy the smart contract - -We can use the Fabric test network to deploy and interact with the `asset-transfer-abac` smart contract. Run the following command to change into the test network directory and bring down any running nodes: -``` -cd fabric-samples/test-network -./network.sh down -``` - -Run the following command to deploy the test network using Certificate Authorities: -``` -./network.sh up createChannel -ca -``` - -You can then use the test network script to deploy the `asset-transfer-abac` smart contract to a channel on the network: -``` -./network.sh deployCC -ccn abac -ccp ../asset-transfer-abac/chaincode-go/ -ccl go -``` - -## Register identities with attributes - -We can use the one of the test network Certificate Authorities to register and enroll identities with the attribute of `abac.creator=true`. First, we need to set the following environment variables in order to use the Fabric CA client. -``` -export PATH=${PWD}/../bin:${PWD}:$PATH -export FABRIC_CFG_PATH=$PWD/../config/ -``` - -We will create the identities using the Org1 CA. Set the Fabric CA client home to the MSP of the Org1 CA admin: -``` -export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/peerOrganizations/org1.example.com/ -``` - -There are two ways to generate certificates with attributes added. We will use both methods and create two identities in the process. The first method is to specify that the attribute be added to the certificate by default when the identity is registered. The following command will register an identity named creator1 with the attribute of `abac.creator=true`. - -``` -fabric-ca-client register --id.name creator1 --id.secret creator1pw --id.type client --id.affiliation org1 --id.attrs 'abac.creator=true:ecert' --tls.certfiles "${PWD}/organizations/fabric-ca/org1/tls-cert.pem" -``` - -The `ecert` suffix adds the attribute to the certificate automatically when the identity is enrolled. As a result, the following enroll command will contain the attribute that was provided in the registration command. - -``` -fabric-ca-client enroll -u https://creator1:creator1pw@localhost:7054 --caname ca-org1 -M "${PWD}/organizations/peerOrganizations/org1.example.com/users/creator1@org1.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org1/tls-cert.pem" -``` - -Now that we have enrolled the identity, run the command below to copy the Node OU configuration file into the creator1 MSP folder. -``` -cp "${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org1.example.com/users/creator1@org1.example.com/msp/config.yaml" -``` - -The second method is to request that the attribute be added upon enrollment. The following command will register an identity named creator2 with the same `abac.creator` attribute. -``` -fabric-ca-client register --id.name creator2 --id.secret creator2pw --id.type client --id.affiliation org1 --id.attrs 'abac.creator=true:' --tls.certfiles "${PWD}/organizations/fabric-ca/org1/tls-cert.pem" -``` - -The following enroll command will add the attribute to the certificate: - -``` -fabric-ca-client enroll -u https://creator2:creator2pw@localhost:7054 --caname ca-org1 --enrollment.attrs "abac.creator" -M "${PWD}/organizations/peerOrganizations/org1.example.com/users/creator2@org1.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org1/tls-cert.pem" -``` - -Run the command below to copy the Node OU configuration file into the creator2 MSP folder. -``` -cp "${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org1.example.com/users/creator2@org1.example.com/msp/config.yaml" -``` - -## Create an asset - -You can use either identity with the `abac.creator=true` attribute to create an asset using the `asset-transfer-abac` smart contract. We will set the following environment variables to use the first identity that was generated, creator1: - -``` -export CORE_PEER_TLS_ENABLED=true -export CORE_PEER_LOCALMSPID=Org1MSP -export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/creator1@org1.example.com/msp -export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt -export CORE_PEER_ADDRESS=localhost:7051 -export TARGET_TLS_OPTIONS=(-o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt") -``` - -Run the following command to create Asset1: -``` -peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n abac -c '{"function":"CreateAsset","Args":["Asset1","blue","20","100"]}' -``` - -You can use the command below to query the asset on the ledger: -``` -peer chaincode query -C mychannel -n abac -c '{"function":"ReadAsset","Args":["Asset1"]}' -``` -The result will list the creator1 identity as the asset owner. The `GetID()` API reads the name and issuer from the certificate of the identity that submitted the transaction and assigns that identity as the asset owner: -``` -{"ID":"Asset1","color":"blue","size":20,"owner":"x509::CN=creator1,OU=client+OU=org1,O=Hyperledger,ST=North Carolina,C=US::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US","appraisedValue":100} -``` - -## Transfer the asset - -As the owner of Asset1, the creator1 identity has the ability to transfer the asset to another owner. In order to transfer the asset, the owner needs to provide the name and issuer of the new owner to the `TransferAsset` function. The `asset-transfer-abac` smart contract has a `GetSubmittingClientIdentity` function that allows users to retrieve their certificate information and provide it to the asset owner out of band (we omit this step). Issue the command below to transfer Asset1 to the user1 identity from Org1 that was created when the test network was deployed: -``` -export RECIPIENT="x509::CN=user1,OU=client,O=Hyperledger,ST=North Carolina,C=US::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US" -peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n abac -c '{"function":"TransferAsset","Args":["Asset1","'"$RECIPIENT"'"]}' -``` -Query the ledger to verify that the asset has a new owner: -``` -peer chaincode query -C mychannel -n abac -c '{"function":"ReadAsset","Args":["Asset1"]}' -``` -We can see that Asset1 with is now owned by User1: -``` -{"ID":"Asset1","color":"blue","size":20,"owner":"x509::CN=user1,OU=client,O=Hyperledger,ST=North Carolina,C=US::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US","appraisedValue":100} -``` - -## Update the asset - -Now that the asset has been transferred, the new owner can update the asset properties. The smart contract uses the `GetID()` API to ensure that the update is being submitted by the asset owner. To demonstrate the difference between identity and attribute based access control, lets try to update the asset using the creator1 identity first: -``` -peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n abac -c '{"function":"UpdateAsset","Args":["Asset1","green","20","100"]}' -``` - -Even though creator1 can create new assets, the smart contract detects that the transaction was not submitted by the identity that owns the asset, user1. The command returns the following error: -``` -Error: endorsement failure during invoke. response: status:500 message:"submitting client not authorized to update asset, does not own asset" -``` - -Run the following command to operate as the asset owner by setting the MSP path to User1: -``` -export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp -``` - -We can now update the asset. Run the following command to change the asset color from blue to green. All other aspects of the asset will remain unchanged. -``` -peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n abac -c '{"function":"UpdateAsset","Args":["Asset1","green","20","100"]}' -``` -Run the query command again to verify that the asset has changed color: -``` -peer chaincode query -C mychannel -n abac -c '{"function":"ReadAsset","Args":["Asset1"]}' -``` -The result will display that Asset1 is now green: -``` -{"ID":"Asset1","color":"green","size":20,"owner":"x509::CN=user1,OU=client,O=Hyperledger,ST=North Carolina,C=US::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US","appraisedValue":100} -``` - -## Delete the asset - -The owner also has the ability to delete the asset. Run the following command to remove Asset1 from the ledger: -``` -peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n abac -c '{"function":"DeleteAsset","Args":["Asset1"]}' -``` - -If you query the ledger once more, you will see that Asset1 no longer exists: -``` -peer chaincode query -C mychannel -n abac -c '{"function":"ReadAsset","Args":["Asset1"]}' -``` - -While we are operating as User1, we can demonstrate attribute based access control by trying to create an asset using an identity without the `abac.creator=true` attribute. Run the following command to try to create Asset1 as User1: -``` -peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n abac -c '{"function":"CreateAsset","Args":["Asset2","red","20","100"]}' -``` - -The smart contract will return the following error: -``` -Error: endorsement failure during invoke. response: status:500 message:"submitting client not authorized to create asset, does not have abac.creator role" -``` - -## Clean up - -When you are finished, you can run the following command to bring down the test network: -``` -./network.sh down -``` diff --git a/asset-transfer-abac/chaincode-go/go.mod b/asset-transfer-abac/chaincode-go/go.mod deleted file mode 100644 index 7111955e..00000000 --- a/asset-transfer-abac/chaincode-go/go.mod +++ /dev/null @@ -1,26 +0,0 @@ -module github.com/hyperledger/fabric-samples/asset-transfer-abac/chaincode-go - -go 1.22.0 - -require github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 - -require ( - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 // indirect - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.36.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/asset-transfer-abac/chaincode-go/go.sum b/asset-transfer-abac/chaincode-go/go.sum deleted file mode 100644 index fa4d3b24..00000000 --- a/asset-transfer-abac/chaincode-go/go.sum +++ /dev/null @@ -1,61 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 h1:IhkHfrl5X/fVnmB6pWeCYCdIJRi9bxj+WTnVN8DtW3c= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0/go.mod h1:PHHaFffjw7p7n9bmCfcm7RqDqYdivNEsJdiNIKZo5Lk= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 h1:rmUoBmciB0GL/miqcbJmJbgp5QTWoJUrZo+CNxrNLF4= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0/go.mod h1:FeWeO/jwGjiME7ak3GufqKIcwkejtzrDG4QxbfKydWs= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/asset-transfer-abac/chaincode-go/smart-contract/abac.go b/asset-transfer-abac/chaincode-go/smart-contract/abac.go deleted file mode 100644 index 30816c64..00000000 --- a/asset-transfer-abac/chaincode-go/smart-contract/abac.go +++ /dev/null @@ -1,214 +0,0 @@ -package abac - -import ( - "encoding/base64" - "encoding/json" - "fmt" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -// SmartContract provides functions for managing an Asset -type SmartContract struct { - contractapi.Contract -} - -// Asset describes basic details of what makes up a simple asset -type Asset struct { - ID string `json:"ID"` - Color string `json:"color"` - Size int `json:"size"` - Owner string `json:"owner"` - AppraisedValue int `json:"appraisedValue"` -} - -// CreateAsset issues a new asset to the world state with given details. -func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, appraisedValue int) error { - - // Demonstrate the use of Attribute-Based Access Control (ABAC) by checking - // to see if the caller has the "abac.creator" attribute with a value of true; - // if not, return an error. - - err := ctx.GetClientIdentity().AssertAttributeValue("abac.creator", "true") - if err != nil { - return fmt.Errorf("submitting client not authorized to create asset, does not have abac.creator role") - } - - exists, err := s.AssetExists(ctx, id) - if err != nil { - return err - } - if exists { - return fmt.Errorf("the asset %s already exists", id) - } - - // Get ID of submitting client identity - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return err - } - - asset := Asset{ - ID: id, - Color: color, - Size: size, - Owner: clientID, - AppraisedValue: appraisedValue, - } - assetJSON, err := json.Marshal(asset) - if err != nil { - return err - } - - return ctx.GetStub().PutState(id, assetJSON) -} - -// UpdateAsset updates an existing asset in the world state with provided parameters. -func (s *SmartContract) UpdateAsset(ctx contractapi.TransactionContextInterface, id string, newColor string, newSize int, newValue int) error { - - asset, err := s.ReadAsset(ctx, id) - if err != nil { - return err - } - - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return err - } - - if clientID != asset.Owner { - return fmt.Errorf("submitting client not authorized to update asset, does not own asset") - } - - asset.Color = newColor - asset.Size = newSize - asset.AppraisedValue = newValue - - assetJSON, err := json.Marshal(asset) - if err != nil { - return err - } - - return ctx.GetStub().PutState(id, assetJSON) -} - -// DeleteAsset deletes a given asset from the world state. -func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface, id string) error { - - asset, err := s.ReadAsset(ctx, id) - if err != nil { - return err - } - - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return err - } - - if clientID != asset.Owner { - return fmt.Errorf("submitting client not authorized to update asset, does not own asset") - } - - return ctx.GetStub().DelState(id) -} - -// TransferAsset updates the owner field of asset with given id in world state. -func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface, id string, newOwner string) error { - - asset, err := s.ReadAsset(ctx, id) - if err != nil { - return err - } - - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return err - } - - if clientID != asset.Owner { - return fmt.Errorf("submitting client not authorized to update asset, does not own asset") - } - - asset.Owner = newOwner - assetJSON, err := json.Marshal(asset) - if err != nil { - return err - } - - return ctx.GetStub().PutState(id, assetJSON) -} - -// ReadAsset returns the asset stored in the world state with given id. -func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, id string) (*Asset, error) { - - assetJSON, err := ctx.GetStub().GetState(id) - if err != nil { - return nil, fmt.Errorf("failed to read from world state: %v", err) - } - if assetJSON == nil { - return nil, fmt.Errorf("the asset %s does not exist", id) - } - - var asset Asset - err = json.Unmarshal(assetJSON, &asset) - if err != nil { - return nil, err - } - - return &asset, nil -} - -// GetAllAssets returns all assets found in world state -func (s *SmartContract) GetAllAssets(ctx contractapi.TransactionContextInterface) ([]*Asset, error) { - // range query with empty string for startKey and endKey does an - // open-ended query of all assets in the chaincode namespace. - resultsIterator, err := ctx.GetStub().GetStateByRange("", "") - if err != nil { - return nil, err - } - defer resultsIterator.Close() - - var assets []*Asset - for resultsIterator.HasNext() { - queryResponse, err := resultsIterator.Next() - if err != nil { - return nil, err - } - - var asset Asset - err = json.Unmarshal(queryResponse.Value, &asset) - if err != nil { - return nil, err - } - assets = append(assets, &asset) - } - - return assets, nil -} - -// AssetExists returns true when asset with given ID exists in world state -func (s *SmartContract) AssetExists(ctx contractapi.TransactionContextInterface, id string) (bool, error) { - - assetJSON, err := ctx.GetStub().GetState(id) - if err != nil { - return false, fmt.Errorf("failed to read from world state: %v", err) - } - - return assetJSON != nil, nil -} - -// GetSubmittingClientIdentity returns the name and issuer of the identity that -// invokes the smart contract. This function base64 decodes the identity string -// before returning the value to the client or smart contract. -func (s *SmartContract) GetSubmittingClientIdentity(ctx contractapi.TransactionContextInterface) (string, error) { - - b64ID, err := ctx.GetClientIdentity().GetID() - if err != nil { - return "", fmt.Errorf("Failed to read clientID: %v", err) - } - decodeID, err := base64.StdEncoding.DecodeString(b64ID) - if err != nil { - return "", fmt.Errorf("failed to base64 decode clientID: %v", err) - } - return string(decodeID), nil -} diff --git a/asset-transfer-abac/chaincode-go/smartContract.go b/asset-transfer-abac/chaincode-go/smartContract.go deleted file mode 100644 index cef4262b..00000000 --- a/asset-transfer-abac/chaincode-go/smartContract.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "log" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" - abac "github.com/hyperledger/fabric-samples/asset-transfer-abac/chaincode-go/smart-contract" -) - -func main() { - abacSmartContract, err := contractapi.NewChaincode(&abac.SmartContract{}) - if err != nil { - log.Panicf("Error creating abac chaincode: %v", err) - } - - if err := abacSmartContract.Start(); err != nil { - log.Panicf("Error starting abac chaincode: %v", err) - } -} diff --git a/asset-transfer-basic/application-gateway-go/assetTransfer.go b/asset-transfer-basic/application-gateway-go/assetTransfer.go deleted file mode 100755 index 348d2341..00000000 --- a/asset-transfer-basic/application-gateway-go/assetTransfer.go +++ /dev/null @@ -1,296 +0,0 @@ -/* -Copyright 2021 IBM All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "bytes" - "context" - "crypto/x509" - "encoding/json" - "errors" - "fmt" - "os" - "path" - "time" - - "github.com/hyperledger/fabric-gateway/pkg/client" - "github.com/hyperledger/fabric-gateway/pkg/hash" - "github.com/hyperledger/fabric-gateway/pkg/identity" - "github.com/hyperledger/fabric-protos-go-apiv2/gateway" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/status" -) - -const ( - mspID = "Org1MSP" - cryptoPath = "../../test-network/organizations/peerOrganizations/org1.example.com" - certPath = cryptoPath + "/users/User1@org1.example.com/msp/signcerts" - keyPath = cryptoPath + "/users/User1@org1.example.com/msp/keystore" - tlsCertPath = cryptoPath + "/peers/peer0.org1.example.com/tls/ca.crt" - peerEndpoint = "dns:///localhost:7051" - gatewayPeer = "peer0.org1.example.com" -) - -var now = time.Now() -var assetId = fmt.Sprintf("asset%d", now.Unix()*1e3+int64(now.Nanosecond())/1e6) - -func main() { - // The gRPC client connection should be shared by all Gateway connections to this endpoint - clientConnection := newGrpcConnection() - defer clientConnection.Close() - - id := newIdentity() - sign := newSign() - - // Create a Gateway connection for a specific client identity - gw, err := client.Connect( - id, - client.WithSign(sign), - client.WithHash(hash.SHA256), - client.WithClientConnection(clientConnection), - // Default timeouts for different gRPC calls - client.WithEvaluateTimeout(5*time.Second), - client.WithEndorseTimeout(15*time.Second), - client.WithSubmitTimeout(5*time.Second), - client.WithCommitStatusTimeout(1*time.Minute), - ) - if err != nil { - panic(err) - } - defer gw.Close() - - // Override default values for chaincode and channel name as they may differ in testing contexts. - chaincodeName := "basic" - if ccname := os.Getenv("CHAINCODE_NAME"); ccname != "" { - chaincodeName = ccname - } - - channelName := "mychannel" - if cname := os.Getenv("CHANNEL_NAME"); cname != "" { - channelName = cname - } - - network := gw.GetNetwork(channelName) - contract := network.GetContract(chaincodeName) - - initLedger(contract) - getAllAssets(contract) - createAsset(contract) - readAssetByID(contract) - transferAssetAsync(contract) - exampleErrorHandling(contract) -} - -// newGrpcConnection creates a gRPC connection to the Gateway server. -func newGrpcConnection() *grpc.ClientConn { - certificatePEM, err := os.ReadFile(tlsCertPath) - if err != nil { - panic(fmt.Errorf("failed to read TLS certifcate file: %w", err)) - } - - certificate, err := identity.CertificateFromPEM(certificatePEM) - if err != nil { - panic(err) - } - - certPool := x509.NewCertPool() - certPool.AddCert(certificate) - transportCredentials := credentials.NewClientTLSFromCert(certPool, gatewayPeer) - - connection, err := grpc.NewClient(peerEndpoint, grpc.WithTransportCredentials(transportCredentials)) - if err != nil { - panic(fmt.Errorf("failed to create gRPC connection: %w", err)) - } - - return connection -} - -// newIdentity creates a client identity for this Gateway connection using an X.509 certificate. -func newIdentity() *identity.X509Identity { - certificatePEM, err := readFirstFile(certPath) - if err != nil { - panic(fmt.Errorf("failed to read certificate file: %w", err)) - } - - certificate, err := identity.CertificateFromPEM(certificatePEM) - if err != nil { - panic(err) - } - - id, err := identity.NewX509Identity(mspID, certificate) - if err != nil { - panic(err) - } - - return id -} - -// newSign creates a function that generates a digital signature from a message digest using a private key. -func newSign() identity.Sign { - privateKeyPEM, err := readFirstFile(keyPath) - if err != nil { - panic(fmt.Errorf("failed to read private key file: %w", err)) - } - - privateKey, err := identity.PrivateKeyFromPEM(privateKeyPEM) - if err != nil { - panic(err) - } - - sign, err := identity.NewPrivateKeySign(privateKey) - if err != nil { - panic(err) - } - - return sign -} - -func readFirstFile(dirPath string) ([]byte, error) { - dir, err := os.Open(dirPath) - if err != nil { - return nil, err - } - - fileNames, err := dir.Readdirnames(1) - if err != nil { - return nil, err - } - - return os.ReadFile(path.Join(dirPath, fileNames[0])) -} - -// This type of transaction would typically only be run once by an application the first time it was started after its -// initial deployment. A new version of the chaincode deployed later would likely not need to run an "init" function. -func initLedger(contract *client.Contract) { - fmt.Printf("\n--> Submit Transaction: InitLedger, function creates the initial set of assets on the ledger \n") - - _, err := contract.SubmitTransaction("InitLedger") - if err != nil { - panic(fmt.Errorf("failed to submit transaction: %w", err)) - } - - fmt.Printf("*** Transaction committed successfully\n") -} - -// Evaluate a transaction to query ledger state. -func getAllAssets(contract *client.Contract) { - fmt.Println("\n--> Evaluate Transaction: GetAllAssets, function returns all the current assets on the ledger") - - evaluateResult, err := contract.EvaluateTransaction("GetAllAssets") - if err != nil { - panic(fmt.Errorf("failed to evaluate transaction: %w", err)) - } - result := formatJSON(evaluateResult) - - fmt.Printf("*** Result:%s\n", result) -} - -// Submit a transaction synchronously, blocking until it has been committed to the ledger. -func createAsset(contract *client.Contract) { - fmt.Printf("\n--> Submit Transaction: CreateAsset, creates new asset with ID, Color, Size, Owner and AppraisedValue arguments \n") - - _, err := contract.SubmitTransaction("CreateAsset", assetId, "yellow", "5", "Tom", "1300") - if err != nil { - panic(fmt.Errorf("failed to submit transaction: %w", err)) - } - - fmt.Printf("*** Transaction committed successfully\n") -} - -// Evaluate a transaction by assetID to query ledger state. -func readAssetByID(contract *client.Contract) { - fmt.Printf("\n--> Evaluate Transaction: ReadAsset, function returns asset attributes\n") - - evaluateResult, err := contract.EvaluateTransaction("ReadAsset", assetId) - if err != nil { - panic(fmt.Errorf("failed to evaluate transaction: %w", err)) - } - result := formatJSON(evaluateResult) - - fmt.Printf("*** Result:%s\n", result) -} - -// Submit transaction asynchronously, blocking until the transaction has been sent to the orderer, and allowing -// this thread to process the chaincode response (e.g. update a UI) without waiting for the commit notification -func transferAssetAsync(contract *client.Contract) { - fmt.Printf("\n--> Async Submit Transaction: TransferAsset, updates existing asset owner") - - submitResult, commit, err := contract.SubmitAsync("TransferAsset", client.WithArguments(assetId, "Mark")) - if err != nil { - panic(fmt.Errorf("failed to submit transaction asynchronously: %w", err)) - } - - fmt.Printf("\n*** Successfully submitted transaction to transfer ownership from %s to Mark. \n", string(submitResult)) - fmt.Println("*** Waiting for transaction commit.") - - if commitStatus, err := commit.Status(); err != nil { - panic(fmt.Errorf("failed to get commit status: %w", err)) - } else if !commitStatus.Successful { - panic(fmt.Errorf("transaction %s failed to commit with status: %d", commitStatus.TransactionID, int32(commitStatus.Code))) - } - - fmt.Printf("*** Transaction committed successfully\n") -} - -// Submit transaction, passing in the wrong number of arguments ,expected to throw an error containing details of any error responses from the smart contract. -func exampleErrorHandling(contract *client.Contract) { - fmt.Println("\n--> Submit Transaction: UpdateAsset asset70, asset70 does not exist and should return an error") - - _, err := contract.SubmitTransaction("UpdateAsset", "asset70", "blue", "5", "Tomoko", "300") - if err == nil { - panic("******** FAILED to return an error") - } - - fmt.Println("*** Successfully caught the error:") - - var endorseErr *client.EndorseError - var submitErr *client.SubmitError - var commitStatusErr *client.CommitStatusError - var commitErr *client.CommitError - - if errors.As(err, &endorseErr) { - fmt.Printf("Endorse error for transaction %s with gRPC status %v: %s\n", endorseErr.TransactionID, status.Code(endorseErr), endorseErr) - } else if errors.As(err, &submitErr) { - fmt.Printf("Submit error for transaction %s with gRPC status %v: %s\n", submitErr.TransactionID, status.Code(submitErr), submitErr) - } else if errors.As(err, &commitStatusErr) { - if errors.Is(err, context.DeadlineExceeded) { - fmt.Printf("Timeout waiting for transaction %s commit status: %s", commitStatusErr.TransactionID, commitStatusErr) - } else { - fmt.Printf("Error obtaining commit status for transaction %s with gRPC status %v: %s\n", commitStatusErr.TransactionID, status.Code(commitStatusErr), commitStatusErr) - } - } else if errors.As(err, &commitErr) { - fmt.Printf("Transaction %s failed to commit with status %d: %s\n", commitErr.TransactionID, int32(commitErr.Code), err) - } else { - panic(fmt.Errorf("unexpected error type %T: %w", err, err)) - } - - // Any error that originates from a peer or orderer node external to the gateway will have its details - // embedded within the gRPC status error. The following code shows how to extract that. - statusErr := status.Convert(err) - - details := statusErr.Details() - if len(details) > 0 { - fmt.Println("Error Details:") - - for _, detail := range details { - switch detail := detail.(type) { - case *gateway.ErrorDetail: - fmt.Printf("- address: %s; mspId: %s; message: %s\n", detail.Address, detail.MspId, detail.Message) - } - } - } -} - -// Format JSON data -func formatJSON(data []byte) string { - var prettyJSON bytes.Buffer - if err := json.Indent(&prettyJSON, data, "", " "); err != nil { - panic(fmt.Errorf("failed to parse JSON: %w", err)) - } - return prettyJSON.String() -} diff --git a/asset-transfer-basic/application-gateway-go/go.mod b/asset-transfer-basic/application-gateway-go/go.mod deleted file mode 100644 index 7261969c..00000000 --- a/asset-transfer-basic/application-gateway-go/go.mod +++ /dev/null @@ -1,19 +0,0 @@ -module assetTransfer - -go 1.22.0 - -require ( - github.com/hyperledger/fabric-gateway v1.7.0 - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 - google.golang.org/grpc v1.67.1 -) - -require ( - github.com/miekg/pkcs11 v1.1.1 // indirect - golang.org/x/crypto v0.28.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/protobuf v1.35.1 // indirect -) diff --git a/asset-transfer-basic/application-gateway-go/go.sum b/asset-transfer-basic/application-gateway-go/go.sum deleted file mode 100644 index 01eab6a8..00000000 --- a/asset-transfer-basic/application-gateway-go/go.sum +++ /dev/null @@ -1,32 +0,0 @@ -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-gateway v1.7.0 h1:bd1quU8qYPYqYO69m1tPIDSjB+D+u/rBJfE1eWFcpjY= -github.com/hyperledger/fabric-gateway v1.7.0/go.mod h1:TItDGnq71eJcgz5TW+m5Sq3kWGp0AEI1HPCNxj0Eu7k= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= -github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/asset-transfer-basic/application-gateway-java/build.gradle b/asset-transfer-basic/application-gateway-java/build.gradle deleted file mode 100644 index 7db92de8..00000000 --- a/asset-transfer-basic/application-gateway-java/build.gradle +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * This generated file contains a sample Java project to get you started. - * For more details take a look at the Java Quickstart chapter in the Gradle - * User Manual available at https://docs.gradle.org/6.5/userguide/tutorial_java_projects.html - */ -plugins { - // Apply the application plugin to add support for building a CLI application. - id 'application' -} - -ext { - javaMainClass = "application.java.App" -} - -repositories { - mavenCentral() -} - -dependencies { - implementation 'org.hyperledger.fabric:fabric-gateway:1.7.0' - implementation platform('com.google.protobuf:protobuf-bom:4.28.2') - implementation platform('io.grpc:grpc-bom:1.67.1') - compileOnly 'io.grpc:grpc-api' - runtimeOnly 'io.grpc:grpc-netty-shaded' - implementation 'com.google.code.gson:gson:2.11.0' -} - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(11) - } -} - -application { - // Define the main class for the application. - mainClass = 'App' -} diff --git a/asset-transfer-basic/application-gateway-java/gradle/wrapper/gradle-wrapper.jar b/asset-transfer-basic/application-gateway-java/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index d64cd491..00000000 Binary files a/asset-transfer-basic/application-gateway-java/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/asset-transfer-basic/application-gateway-java/gradle/wrapper/gradle-wrapper.properties b/asset-transfer-basic/application-gateway-java/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e2847c82..00000000 --- a/asset-transfer-basic/application-gateway-java/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/asset-transfer-basic/application-gateway-java/gradlew b/asset-transfer-basic/application-gateway-java/gradlew deleted file mode 100755 index 1aa94a42..00000000 --- a/asset-transfer-basic/application-gateway-java/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/asset-transfer-basic/application-gateway-java/gradlew.bat b/asset-transfer-basic/application-gateway-java/gradlew.bat deleted file mode 100644 index 7101f8e4..00000000 --- a/asset-transfer-basic/application-gateway-java/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/asset-transfer-basic/application-gateway-java/pom.xml b/asset-transfer-basic/application-gateway-java/pom.xml deleted file mode 100644 index 76c7dc7b..00000000 --- a/asset-transfer-basic/application-gateway-java/pom.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - 4.0.0 - - org.hyperledger.fabric.example - asset-transfer-basic - 1.0-SNAPSHOT - - - UTF-8 - 11 - - - - - - com.google.protobuf - protobuf-bom - 4.28.2 - pom - import - - - io.grpc - grpc-bom - 1.67.1 - pom - import - - - - - - - org.hyperledger.fabric - fabric-gateway - 1.7.0 - - - io.grpc - grpc-api - - - io.grpc - grpc-netty-shaded - runtime - - - - - - - - - maven-clean-plugin - 3.4.0 - - - - maven-resources-plugin - 3.3.1 - - - maven-compiler-plugin - 3.13.0 - - - maven-surefire-plugin - 3.3.0 - - - maven-jar-plugin - 3.4.2 - - - maven-install-plugin - 3.1.2 - - - maven-deploy-plugin - 3.1.2 - - - - maven-site-plugin - 3.12.1 - - - maven-project-info-reports-plugin - 3.6.1 - - - - - diff --git a/asset-transfer-basic/application-gateway-java/settings.gradle b/asset-transfer-basic/application-gateway-java/settings.gradle deleted file mode 100644 index be3a1b3b..00000000 --- a/asset-transfer-basic/application-gateway-java/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * The settings file is used to specify which projects to include in your build. - * - * Detailed information about configuring a multi-project build in Gradle can be found - * in the user manual at https://docs.gradle.org/6.5/userguide/multi_project_builds.html - */ - -rootProject.name = 'asset-transfer-basic' diff --git a/asset-transfer-basic/application-gateway-java/src/main/java/App.java b/asset-transfer-basic/application-gateway-java/src/main/java/App.java deleted file mode 100644 index 57285ef8..00000000 --- a/asset-transfer-basic/application-gateway-java/src/main/java/App.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonParser; -import io.grpc.Grpc; -import io.grpc.ManagedChannel; -import io.grpc.TlsChannelCredentials; -import org.hyperledger.fabric.client.CommitException; -import org.hyperledger.fabric.client.CommitStatusException; -import org.hyperledger.fabric.client.Contract; -import org.hyperledger.fabric.client.EndorseException; -import org.hyperledger.fabric.client.Gateway; -import org.hyperledger.fabric.client.GatewayException; -import org.hyperledger.fabric.client.Hash; -import org.hyperledger.fabric.client.SubmitException; -import org.hyperledger.fabric.client.identity.Identities; -import org.hyperledger.fabric.client.identity.Identity; -import org.hyperledger.fabric.client.identity.Signer; -import org.hyperledger.fabric.client.identity.Signers; -import org.hyperledger.fabric.client.identity.X509Identity; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.InvalidKeyException; -import java.security.cert.CertificateException; -import java.time.Instant; -import java.util.concurrent.TimeUnit; - -public final class App { - private static final String MSP_ID = System.getenv().getOrDefault("MSP_ID", "Org1MSP"); - private static final String CHANNEL_NAME = System.getenv().getOrDefault("CHANNEL_NAME", "mychannel"); - private static final String CHAINCODE_NAME = System.getenv().getOrDefault("CHAINCODE_NAME", "basic"); - - // Path to crypto materials. - private static final Path CRYPTO_PATH = Paths.get("../../test-network/organizations/peerOrganizations/org1.example.com"); - // Path to user certificate. - private static final Path CERT_DIR_PATH = CRYPTO_PATH.resolve(Paths.get("users/User1@org1.example.com/msp/signcerts")); - // Path to user private key directory. - private static final Path KEY_DIR_PATH = CRYPTO_PATH.resolve(Paths.get("users/User1@org1.example.com/msp/keystore")); - // Path to peer tls certificate. - private static final Path TLS_CERT_PATH = CRYPTO_PATH.resolve(Paths.get("peers/peer0.org1.example.com/tls/ca.crt")); - - // Gateway peer end point. - private static final String PEER_ENDPOINT = "localhost:7051"; - private static final String OVERRIDE_AUTH = "peer0.org1.example.com"; - - private final Contract contract; - private final String assetId = "asset" + Instant.now().toEpochMilli(); - private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - - public static void main(final String[] args) throws Exception { - // The gRPC client connection should be shared by all Gateway connections to - // this endpoint. - var channel = newGrpcConnection(); - - var builder = Gateway.newInstance() - .identity(newIdentity()) - .signer(newSigner()) - .hash(Hash.SHA256) - .connection(channel) - // Default timeouts for different gRPC calls - .evaluateOptions(options -> options.withDeadlineAfter(5, TimeUnit.SECONDS)) - .endorseOptions(options -> options.withDeadlineAfter(15, TimeUnit.SECONDS)) - .submitOptions(options -> options.withDeadlineAfter(5, TimeUnit.SECONDS)) - .commitStatusOptions(options -> options.withDeadlineAfter(1, TimeUnit.MINUTES)); - - try (var gateway = builder.connect()) { - new App(gateway).run(); - } finally { - channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); - } - } - - private static ManagedChannel newGrpcConnection() throws IOException { - var credentials = TlsChannelCredentials.newBuilder() - .trustManager(TLS_CERT_PATH.toFile()) - .build(); - return Grpc.newChannelBuilder(PEER_ENDPOINT, credentials) - .overrideAuthority(OVERRIDE_AUTH) - .build(); - } - - private static Identity newIdentity() throws IOException, CertificateException { - try (var certReader = Files.newBufferedReader(getFirstFilePath(CERT_DIR_PATH))) { - var certificate = Identities.readX509Certificate(certReader); - return new X509Identity(MSP_ID, certificate); - } - } - - private static Signer newSigner() throws IOException, InvalidKeyException { - try (var keyReader = Files.newBufferedReader(getFirstFilePath(KEY_DIR_PATH))) { - var privateKey = Identities.readPrivateKey(keyReader); - return Signers.newPrivateKeySigner(privateKey); - } - } - - private static Path getFirstFilePath(Path dirPath) throws IOException { - try (var keyFiles = Files.list(dirPath)) { - return keyFiles.findFirst().orElseThrow(); - } - } - - public App(final Gateway gateway) { - // Get a network instance representing the channel where the smart contract is - // deployed. - var network = gateway.getNetwork(CHANNEL_NAME); - - // Get the smart contract from the network. - contract = network.getContract(CHAINCODE_NAME); - } - - public void run() throws GatewayException, CommitException { - // Initialize a set of asset data on the ledger using the chaincode 'InitLedger' function. - initLedger(); - - // Return all the current assets on the ledger. - getAllAssets(); - - // Create a new asset on the ledger. - createAsset(); - - // Update an existing asset asynchronously. - transferAssetAsync(); - - // Get the asset details by assetID. - readAssetById(); - - // Update an asset which does not exist. - updateNonExistentAsset(); - } - - /** - * This type of transaction would typically only be run once by an application - * the first time it was started after its initial deployment. A new version of - * the chaincode deployed later would likely not need to run an "init" function. - */ - private void initLedger() throws EndorseException, SubmitException, CommitStatusException, CommitException { - System.out.println("\n--> Submit Transaction: InitLedger, function creates the initial set of assets on the ledger"); - - contract.submitTransaction("InitLedger"); - - System.out.println("*** Transaction committed successfully"); - } - - /** - * Evaluate a transaction to query ledger state. - */ - private void getAllAssets() throws GatewayException { - System.out.println("\n--> Evaluate Transaction: GetAllAssets, function returns all the current assets on the ledger"); - - var result = contract.evaluateTransaction("GetAllAssets"); - - System.out.println("*** Result: " + prettyJson(result)); - } - - private String prettyJson(final byte[] json) { - return prettyJson(new String(json, StandardCharsets.UTF_8)); - } - - private String prettyJson(final String json) { - var parsedJson = JsonParser.parseString(json); - return gson.toJson(parsedJson); - } - - /** - * Submit a transaction synchronously, blocking until it has been committed to - * the ledger. - */ - private void createAsset() throws EndorseException, SubmitException, CommitStatusException, CommitException { - System.out.println("\n--> Submit Transaction: CreateAsset, creates new asset with ID, Color, Size, Owner and AppraisedValue arguments"); - - contract.submitTransaction("CreateAsset", assetId, "yellow", "5", "Tom", "1300"); - - System.out.println("*** Transaction committed successfully"); - } - - /** - * Submit transaction asynchronously, allowing the application to process the - * smart contract response (e.g. update a UI) while waiting for the commit - * notification. - */ - private void transferAssetAsync() throws EndorseException, SubmitException, CommitStatusException { - System.out.println("\n--> Async Submit Transaction: TransferAsset, updates existing asset owner"); - - var commit = contract.newProposal("TransferAsset") - .addArguments(assetId, "Saptha") - .build() - .endorse() - .submitAsync(); - - var result = commit.getResult(); - var oldOwner = new String(result, StandardCharsets.UTF_8); - - System.out.println("*** Successfully submitted transaction to transfer ownership from " + oldOwner + " to Saptha"); - System.out.println("*** Waiting for transaction commit"); - - var status = commit.getStatus(); - if (!status.isSuccessful()) { - throw new RuntimeException("Transaction " + status.getTransactionId() + - " failed to commit with status code " + status.getCode()); - } - - System.out.println("*** Transaction committed successfully"); - } - - private void readAssetById() throws GatewayException { - System.out.println("\n--> Evaluate Transaction: ReadAsset, function returns asset attributes"); - - var evaluateResult = contract.evaluateTransaction("ReadAsset", assetId); - - System.out.println("*** Result:" + prettyJson(evaluateResult)); - } - - /** - * submitTransaction() will throw an error containing details of any error - * responses from the smart contract. - */ - private void updateNonExistentAsset() { - try { - System.out.println("\n--> Submit Transaction: UpdateAsset asset70, asset70 does not exist and should return an error"); - - contract.submitTransaction("UpdateAsset", "asset70", "blue", "5", "Tomoko", "300"); - - System.out.println("******** FAILED to return an error"); - } catch (EndorseException | SubmitException | CommitStatusException e) { - System.out.println("*** Successfully caught the error:"); - e.printStackTrace(System.out); - System.out.println("Transaction ID: " + e.getTransactionId()); - } catch (CommitException e) { - System.out.println("*** Successfully caught the error:"); - e.printStackTrace(System.out); - System.out.println("Transaction ID: " + e.getTransactionId()); - System.out.println("Status code: " + e.getCode()); - } - } -} diff --git a/asset-transfer-basic/application-gateway-javascript/.gitignore b/asset-transfer-basic/application-gateway-javascript/.gitignore deleted file mode 100644 index 24a64171..00000000 --- a/asset-transfer-basic/application-gateway-javascript/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - - -# Coverage directory used by tools like istanbul -coverage - -# Dependency directories -node_modules/ -jspm_packages/ diff --git a/asset-transfer-basic/application-gateway-javascript/.npmrc b/asset-transfer-basic/application-gateway-javascript/.npmrc deleted file mode 100644 index b6f27f13..00000000 --- a/asset-transfer-basic/application-gateway-javascript/.npmrc +++ /dev/null @@ -1 +0,0 @@ -engine-strict=true diff --git a/asset-transfer-basic/application-gateway-javascript/eslint.config.mjs b/asset-transfer-basic/application-gateway-javascript/eslint.config.mjs deleted file mode 100644 index 861b4f0d..00000000 --- a/asset-transfer-basic/application-gateway-javascript/eslint.config.mjs +++ /dev/null @@ -1,15 +0,0 @@ -import js from '@eslint/js'; -import globals from 'globals'; - -export default [ - js.configs.recommended, - { - languageOptions: { - ecmaVersion: 2023, - sourceType: 'commonjs', - globals: { - ...globals.node, - }, - }, - }, -]; diff --git a/asset-transfer-basic/application-gateway-javascript/package.json b/asset-transfer-basic/application-gateway-javascript/package.json deleted file mode 100644 index 896e6339..00000000 --- a/asset-transfer-basic/application-gateway-javascript/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "asset-transfer-basic", - "version": "1.0.0", - "description": "Asset Transfer Basic Application implemented in JavaScript using fabric-gateway", - "engines": { - "node": ">=18" - }, - "scripts": { - "lint": "eslint src", - "pretest": "npm run lint", - "start": "node src/app.js" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "@grpc/grpc-js": "^1.12.2", - "@hyperledger/fabric-gateway": "^1.7.0" - }, - "devDependencies": { - "@eslint/js": "^9.5.0", - "eslint": "^9.5.0", - "globals": "^15.6.0" - } -} diff --git a/asset-transfer-basic/application-gateway-javascript/src/app.js b/asset-transfer-basic/application-gateway-javascript/src/app.js deleted file mode 100644 index 389d4821..00000000 --- a/asset-transfer-basic/application-gateway-javascript/src/app.js +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -const grpc = require('@grpc/grpc-js'); -const { connect, hash, signers } = require('@hyperledger/fabric-gateway'); -const crypto = require('node:crypto'); -const fs = require('node:fs/promises'); -const path = require('node:path'); -const { TextDecoder } = require('node:util'); - -const channelName = envOrDefault('CHANNEL_NAME', 'mychannel'); -const chaincodeName = envOrDefault('CHAINCODE_NAME', 'basic'); -const mspId = envOrDefault('MSP_ID', 'Org1MSP'); - -// Path to crypto materials. -const cryptoPath = envOrDefault( - 'CRYPTO_PATH', - path.resolve( - __dirname, - '..', - '..', - '..', - 'test-network', - 'organizations', - 'peerOrganizations', - 'org1.example.com' - ) -); - -// Path to user private key directory. -const keyDirectoryPath = envOrDefault( - 'KEY_DIRECTORY_PATH', - path.resolve( - cryptoPath, - 'users', - 'User1@org1.example.com', - 'msp', - 'keystore' - ) -); - -// Path to user certificate directory. -const certDirectoryPath = envOrDefault( - 'CERT_DIRECTORY_PATH', - path.resolve( - cryptoPath, - 'users', - 'User1@org1.example.com', - 'msp', - 'signcerts' - ) -); - -// Path to peer tls certificate. -const tlsCertPath = envOrDefault( - 'TLS_CERT_PATH', - path.resolve(cryptoPath, 'peers', 'peer0.org1.example.com', 'tls', 'ca.crt') -); - -// Gateway peer endpoint. -const peerEndpoint = envOrDefault('PEER_ENDPOINT', 'localhost:7051'); - -// Gateway peer SSL host name override. -const peerHostAlias = envOrDefault('PEER_HOST_ALIAS', 'peer0.org1.example.com'); - -const utf8Decoder = new TextDecoder(); -const assetId = `asset${String(Date.now())}`; - -async function main() { - displayInputParameters(); - - // The gRPC client connection should be shared by all Gateway connections to this endpoint. - const client = await newGrpcConnection(); - - const gateway = connect({ - client, - identity: await newIdentity(), - signer: await newSigner(), - hash: hash.sha256, - // Default timeouts for different gRPC calls - evaluateOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - endorseOptions: () => { - return { deadline: Date.now() + 15000 }; // 15 seconds - }, - submitOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - commitStatusOptions: () => { - return { deadline: Date.now() + 60000 }; // 1 minute - }, - }); - - try { - // Get a network instance representing the channel where the smart contract is deployed. - const network = gateway.getNetwork(channelName); - - // Get the smart contract from the network. - const contract = network.getContract(chaincodeName); - - // Initialize a set of asset data on the ledger using the chaincode 'InitLedger' function. - await initLedger(contract); - - // Return all the current assets on the ledger. - await getAllAssets(contract); - - // Create a new asset on the ledger. - await createAsset(contract); - - // Update an existing asset asynchronously. - await transferAssetAsync(contract); - - // Get the asset details by assetID. - await readAssetByID(contract); - - // Update an asset which does not exist. - await updateNonExistentAsset(contract); - } finally { - gateway.close(); - client.close(); - } -} - -main().catch((error) => { - console.error('******** FAILED to run the application:', error); - process.exitCode = 1; -}); - -async function newGrpcConnection() { - const tlsRootCert = await fs.readFile(tlsCertPath); - const tlsCredentials = grpc.credentials.createSsl(tlsRootCert); - return new grpc.Client(peerEndpoint, tlsCredentials, { - 'grpc.ssl_target_name_override': peerHostAlias, - }); -} - -async function newIdentity() { - const certPath = await getFirstDirFileName(certDirectoryPath); - const credentials = await fs.readFile(certPath); - return { mspId, credentials }; -} - -async function getFirstDirFileName(dirPath) { - const files = await fs.readdir(dirPath); - const file = files[0]; - if (!file) { - throw new Error(`No files in directory: ${dirPath}`); - } - return path.join(dirPath, file); -} - -async function newSigner() { - const keyPath = await getFirstDirFileName(keyDirectoryPath); - const privateKeyPem = await fs.readFile(keyPath); - const privateKey = crypto.createPrivateKey(privateKeyPem); - return signers.newPrivateKeySigner(privateKey); -} - -/** - * This type of transaction would typically only be run once by an application the first time it was started after its - * initial deployment. A new version of the chaincode deployed later would likely not need to run an "init" function. - */ -async function initLedger(contract) { - console.log( - '\n--> Submit Transaction: InitLedger, function creates the initial set of assets on the ledger' - ); - - await contract.submitTransaction('InitLedger'); - - console.log('*** Transaction committed successfully'); -} - -/** - * Evaluate a transaction to query ledger state. - */ -async function getAllAssets(contract) { - console.log( - '\n--> Evaluate Transaction: GetAllAssets, function returns all the current assets on the ledger' - ); - - const resultBytes = await contract.evaluateTransaction('GetAllAssets'); - - const resultJson = utf8Decoder.decode(resultBytes); - const result = JSON.parse(resultJson); - console.log('*** Result:', result); -} - -/** - * Submit a transaction synchronously, blocking until it has been committed to the ledger. - */ -async function createAsset(contract) { - console.log( - '\n--> Submit Transaction: CreateAsset, creates new asset with ID, Color, Size, Owner and AppraisedValue arguments' - ); - - await contract.submitTransaction( - 'CreateAsset', - assetId, - 'yellow', - '5', - 'Tom', - '1300' - ); - - console.log('*** Transaction committed successfully'); -} - -/** - * Submit transaction asynchronously, allowing the application to process the smart contract response (e.g. update a UI) - * while waiting for the commit notification. - */ -async function transferAssetAsync(contract) { - console.log( - '\n--> Async Submit Transaction: TransferAsset, updates existing asset owner' - ); - - const commit = await contract.submitAsync('TransferAsset', { - arguments: [assetId, 'Saptha'], - }); - const oldOwner = utf8Decoder.decode(commit.getResult()); - - console.log( - `*** Successfully submitted transaction to transfer ownership from ${oldOwner} to Saptha` - ); - console.log('*** Waiting for transaction commit'); - - const status = await commit.getStatus(); - if (!status.successful) { - throw new Error( - `Transaction ${ - status.transactionId - } failed to commit with status code ${String(status.code)}` - ); - } - - console.log('*** Transaction committed successfully'); -} - -async function readAssetByID(contract) { - console.log( - '\n--> Evaluate Transaction: ReadAsset, function returns asset attributes' - ); - - const resultBytes = await contract.evaluateTransaction( - 'ReadAsset', - assetId - ); - - const resultJson = utf8Decoder.decode(resultBytes); - const result = JSON.parse(resultJson); - console.log('*** Result:', result); -} - -/** - * submitTransaction() will throw an error containing details of any error responses from the smart contract. - */ -async function updateNonExistentAsset(contract) { - console.log( - '\n--> Submit Transaction: UpdateAsset asset70, asset70 does not exist and should return an error' - ); - - try { - await contract.submitTransaction( - 'UpdateAsset', - 'asset70', - 'blue', - '5', - 'Tomoko', - '300' - ); - console.log('******** FAILED to return an error'); - } catch (error) { - console.log('*** Successfully caught the error: \n', error); - } -} - -/** - * envOrDefault() will return the value of an environment variable, or a default value if the variable is undefined. - */ -function envOrDefault(key, defaultValue) { - return process.env[key] || defaultValue; -} - -/** - * displayInputParameters() will print the global scope parameters used by the main driver routine. - */ -function displayInputParameters() { - console.log(`channelName: ${channelName}`); - console.log(`chaincodeName: ${chaincodeName}`); - console.log(`mspId: ${mspId}`); - console.log(`cryptoPath: ${cryptoPath}`); - console.log(`keyDirectoryPath: ${keyDirectoryPath}`); - console.log(`certDirectoryPath: ${certDirectoryPath}`); - console.log(`tlsCertPath: ${tlsCertPath}`); - console.log(`peerEndpoint: ${peerEndpoint}`); - console.log(`peerHostAlias: ${peerHostAlias}`); -} diff --git a/asset-transfer-basic/application-gateway-typescript/.gitignore b/asset-transfer-basic/application-gateway-typescript/.gitignore deleted file mode 100644 index 99e5af9f..00000000 --- a/asset-transfer-basic/application-gateway-typescript/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - - -# Coverage directory used by tools like istanbul -coverage - -# Dependency directories -node_modules/ -jspm_packages/ - -# Compiled TypeScript files -dist diff --git a/asset-transfer-basic/application-gateway-typescript/.npmrc b/asset-transfer-basic/application-gateway-typescript/.npmrc deleted file mode 100644 index b6f27f13..00000000 --- a/asset-transfer-basic/application-gateway-typescript/.npmrc +++ /dev/null @@ -1 +0,0 @@ -engine-strict=true diff --git a/asset-transfer-basic/application-gateway-typescript/eslint.config.mjs b/asset-transfer-basic/application-gateway-typescript/eslint.config.mjs deleted file mode 100644 index 9ef6b243..00000000 --- a/asset-transfer-basic/application-gateway-typescript/eslint.config.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import js from '@eslint/js'; -import tseslint from 'typescript-eslint'; - -export default tseslint.config(js.configs.recommended, ...tseslint.configs.strictTypeChecked, { - languageOptions: { - ecmaVersion: 2023, - sourceType: 'module', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: import.meta.dirname, - }, - }, -}); diff --git a/asset-transfer-basic/application-gateway-typescript/package.json b/asset-transfer-basic/application-gateway-typescript/package.json deleted file mode 100644 index 5327cb76..00000000 --- a/asset-transfer-basic/application-gateway-typescript/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "asset-transfer-basic", - "version": "1.0.0", - "description": "Asset Transfer Basic Application implemented in typeScript using fabric-gateway", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "engines": { - "node": ">=18" - }, - "scripts": { - "build": "tsc", - "build:watch": "tsc -w", - "lint": "eslint src", - "prepare": "npm run build", - "pretest": "npm run lint", - "start": "node dist/app.js" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "@grpc/grpc-js": "^1.12.2", - "@hyperledger/fabric-gateway": "^1.7.0" - }, - "devDependencies": { - "@eslint/js": "^9.3.0", - "@tsconfig/node18": "^18.2.2", - "@types/node": "^18.18.6", - "eslint": "^8.57.0", - "typescript": "~5.4", - "typescript-eslint": "^7.13.0" - } -} diff --git a/asset-transfer-basic/application-gateway-typescript/src/app.ts b/asset-transfer-basic/application-gateway-typescript/src/app.ts deleted file mode 100644 index fd4bdc95..00000000 --- a/asset-transfer-basic/application-gateway-typescript/src/app.ts +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as grpc from '@grpc/grpc-js'; -import { connect, Contract, hash, Identity, Signer, signers } from '@hyperledger/fabric-gateway'; -import * as crypto from 'crypto'; -import { promises as fs } from 'fs'; -import * as path from 'path'; -import { TextDecoder } from 'util'; - -const channelName = envOrDefault('CHANNEL_NAME', 'mychannel'); -const chaincodeName = envOrDefault('CHAINCODE_NAME', 'basic'); -const mspId = envOrDefault('MSP_ID', 'Org1MSP'); - -// Path to crypto materials. -const cryptoPath = envOrDefault('CRYPTO_PATH', path.resolve(__dirname, '..', '..', '..', 'test-network', 'organizations', 'peerOrganizations', 'org1.example.com')); - -// Path to user private key directory. -const keyDirectoryPath = envOrDefault('KEY_DIRECTORY_PATH', path.resolve(cryptoPath, 'users', 'User1@org1.example.com', 'msp', 'keystore')); - -// Path to user certificate directory. -const certDirectoryPath = envOrDefault('CERT_DIRECTORY_PATH', path.resolve(cryptoPath, 'users', 'User1@org1.example.com', 'msp', 'signcerts')); - -// Path to peer tls certificate. -const tlsCertPath = envOrDefault('TLS_CERT_PATH', path.resolve(cryptoPath, 'peers', 'peer0.org1.example.com', 'tls', 'ca.crt')); - -// Gateway peer endpoint. -const peerEndpoint = envOrDefault('PEER_ENDPOINT', 'localhost:7051'); - -// Gateway peer SSL host name override. -const peerHostAlias = envOrDefault('PEER_HOST_ALIAS', 'peer0.org1.example.com'); - -const utf8Decoder = new TextDecoder(); -const assetId = `asset${String(Date.now())}`; - -async function main(): Promise { - displayInputParameters(); - - // The gRPC client connection should be shared by all Gateway connections to this endpoint. - const client = await newGrpcConnection(); - - const gateway = connect({ - client, - identity: await newIdentity(), - signer: await newSigner(), - hash: hash.sha256, - // Default timeouts for different gRPC calls - evaluateOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - endorseOptions: () => { - return { deadline: Date.now() + 15000 }; // 15 seconds - }, - submitOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - commitStatusOptions: () => { - return { deadline: Date.now() + 60000 }; // 1 minute - }, - }); - - try { - // Get a network instance representing the channel where the smart contract is deployed. - const network = gateway.getNetwork(channelName); - - // Get the smart contract from the network. - const contract = network.getContract(chaincodeName); - - // Initialize a set of asset data on the ledger using the chaincode 'InitLedger' function. - await initLedger(contract); - - // Return all the current assets on the ledger. - await getAllAssets(contract); - - // Create a new asset on the ledger. - await createAsset(contract); - - // Update an existing asset asynchronously. - await transferAssetAsync(contract); - - // Get the asset details by assetID. - await readAssetByID(contract); - - // Update an asset which does not exist. - await updateNonExistentAsset(contract) - } finally { - gateway.close(); - client.close(); - } -} - -main().catch((error: unknown) => { - console.error('******** FAILED to run the application:', error); - process.exitCode = 1; -}); - -async function newGrpcConnection(): Promise { - const tlsRootCert = await fs.readFile(tlsCertPath); - const tlsCredentials = grpc.credentials.createSsl(tlsRootCert); - return new grpc.Client(peerEndpoint, tlsCredentials, { - 'grpc.ssl_target_name_override': peerHostAlias, - }); -} - -async function newIdentity(): Promise { - const certPath = await getFirstDirFileName(certDirectoryPath); - const credentials = await fs.readFile(certPath); - return { mspId, credentials }; -} - -async function getFirstDirFileName(dirPath: string): Promise { - const files = await fs.readdir(dirPath); - const file = files[0]; - if (!file) { - throw new Error(`No files in directory: ${dirPath}`); - } - return path.join(dirPath, file); -} - -async function newSigner(): Promise { - const keyPath = await getFirstDirFileName(keyDirectoryPath); - const privateKeyPem = await fs.readFile(keyPath); - const privateKey = crypto.createPrivateKey(privateKeyPem); - return signers.newPrivateKeySigner(privateKey); -} - -/** - * This type of transaction would typically only be run once by an application the first time it was started after its - * initial deployment. A new version of the chaincode deployed later would likely not need to run an "init" function. - */ -async function initLedger(contract: Contract): Promise { - console.log('\n--> Submit Transaction: InitLedger, function creates the initial set of assets on the ledger'); - - await contract.submitTransaction('InitLedger'); - - console.log('*** Transaction committed successfully'); -} - -/** - * Evaluate a transaction to query ledger state. - */ -async function getAllAssets(contract: Contract): Promise { - console.log('\n--> Evaluate Transaction: GetAllAssets, function returns all the current assets on the ledger'); - - const resultBytes = await contract.evaluateTransaction('GetAllAssets'); - - const resultJson = utf8Decoder.decode(resultBytes); - const result: unknown = JSON.parse(resultJson); - console.log('*** Result:', result); -} - -/** - * Submit a transaction synchronously, blocking until it has been committed to the ledger. - */ -async function createAsset(contract: Contract): Promise { - console.log('\n--> Submit Transaction: CreateAsset, creates new asset with ID, Color, Size, Owner and AppraisedValue arguments'); - - await contract.submitTransaction( - 'CreateAsset', - assetId, - 'yellow', - '5', - 'Tom', - '1300', - ); - - console.log('*** Transaction committed successfully'); -} - -/** - * Submit transaction asynchronously, allowing the application to process the smart contract response (e.g. update a UI) - * while waiting for the commit notification. - */ -async function transferAssetAsync(contract: Contract): Promise { - console.log('\n--> Async Submit Transaction: TransferAsset, updates existing asset owner'); - - const commit = await contract.submitAsync('TransferAsset', { - arguments: [assetId, 'Saptha'], - }); - const oldOwner = utf8Decoder.decode(commit.getResult()); - - console.log(`*** Successfully submitted transaction to transfer ownership from ${oldOwner} to Saptha`); - console.log('*** Waiting for transaction commit'); - - const status = await commit.getStatus(); - if (!status.successful) { - throw new Error(`Transaction ${status.transactionId} failed to commit with status code ${String(status.code)}`); - } - - console.log('*** Transaction committed successfully'); -} - -async function readAssetByID(contract: Contract): Promise { - console.log('\n--> Evaluate Transaction: ReadAsset, function returns asset attributes'); - - const resultBytes = await contract.evaluateTransaction('ReadAsset', assetId); - - const resultJson = utf8Decoder.decode(resultBytes); - const result: unknown = JSON.parse(resultJson); - console.log('*** Result:', result); -} - -/** - * submitTransaction() will throw an error containing details of any error responses from the smart contract. - */ -async function updateNonExistentAsset(contract: Contract): Promise{ - console.log('\n--> Submit Transaction: UpdateAsset asset70, asset70 does not exist and should return an error'); - - try { - await contract.submitTransaction( - 'UpdateAsset', - 'asset70', - 'blue', - '5', - 'Tomoko', - '300', - ); - console.log('******** FAILED to return an error'); - } catch (error) { - console.log('*** Successfully caught the error: \n', error); - } -} - -/** - * envOrDefault() will return the value of an environment variable, or a default value if the variable is undefined. - */ -function envOrDefault(key: string, defaultValue: string): string { - return process.env[key] || defaultValue; -} - -/** - * displayInputParameters() will print the global scope parameters used by the main driver routine. - */ -function displayInputParameters(): void { - console.log(`channelName: ${channelName}`); - console.log(`chaincodeName: ${chaincodeName}`); - console.log(`mspId: ${mspId}`); - console.log(`cryptoPath: ${cryptoPath}`); - console.log(`keyDirectoryPath: ${keyDirectoryPath}`); - console.log(`certDirectoryPath: ${certDirectoryPath}`); - console.log(`tlsCertPath: ${tlsCertPath}`); - console.log(`peerEndpoint: ${peerEndpoint}`); - console.log(`peerHostAlias: ${peerHostAlias}`); -} diff --git a/asset-transfer-basic/application-gateway-typescript/tsconfig.json b/asset-transfer-basic/application-gateway-typescript/tsconfig.json deleted file mode 100644 index 4c20df24..00000000 --- a/asset-transfer-basic/application-gateway-typescript/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "@tsconfig/node18/tsconfig.json", - "compilerOptions": { - "outDir": "dist", - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "noUnusedLocals": true, - "noImplicitReturns": true, - "noUncheckedIndexedAccess": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["./src/**/*"], - "exclude": ["./src/**/*.spec.ts"] -} diff --git a/asset-transfer-basic/chaincode-external/.dockerignore b/asset-transfer-basic/chaincode-external/.dockerignore deleted file mode 100644 index 61260e58..00000000 --- a/asset-transfer-basic/chaincode-external/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -chaincode.env* -*.json -*.md -*.tar.gz -*.tgz diff --git a/asset-transfer-basic/chaincode-external/.gitignore b/asset-transfer-basic/chaincode-external/.gitignore deleted file mode 100644 index 438df6cb..00000000 --- a/asset-transfer-basic/chaincode-external/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.tar.gz -*.tgz -crypto/*.pem diff --git a/asset-transfer-basic/chaincode-external/Dockerfile b/asset-transfer-basic/chaincode-external/Dockerfile deleted file mode 100644 index 8341e6fd..00000000 --- a/asset-transfer-basic/chaincode-external/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright IBM Corp. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 - -ARG GO_VER=1.22 -ARG ALPINE_VER=3.20 - -FROM golang:${GO_VER}-alpine${ALPINE_VER} - -WORKDIR /go/src/github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-external -COPY . . - -RUN go get -d -v ./... -RUN go install -v ./... - -EXPOSE 9999 -CMD ["chaincode-external"] diff --git a/asset-transfer-basic/chaincode-external/README.md b/asset-transfer-basic/chaincode-external/README.md deleted file mode 100755 index 2a20da90..00000000 --- a/asset-transfer-basic/chaincode-external/README.md +++ /dev/null @@ -1,252 +0,0 @@ -# Asset-Transfer-Basic as an external service - -This sample provides an introduction to how to use external builder and launcher scripts to run chaincode as an external service to your peer. For more information, see the [Chaincode as an external service](https://hyperledger-fabric.readthedocs.io/en/latest/cc_service.html) topic in the Fabric documentation. - -**Note:** each organization in a real network would need to setup and host their own instance of the external service. In this tutorial, we use the same instance for both organizations for simplicity. - -## Setting up the external builder and launcher - -External Builders and Launchers is an advanced feature that typically requires custom packaging of the peer image so that it contains all the tools your builder and launcher require. This sample uses very simple (and crude) shell scripts that can be run directly within the default Fabric peer images. - -Open the `config/core.yaml` file at the top of the `fabric-samples` directory. If you do not have this file, follow the instructions to [Install the Samples, Binaries and Docker Images](https://hyperledger-fabric.readthedocs.io/en/latest/install.html) to download the Fabric binaries and configuration files alongside the Fabric samples. - -Modify the `externalBuilders` field in the `core.yaml` file to resemble the configuration below: - -``` -externalBuilders: - - path: /opt/gopath/src/github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-external/sampleBuilder - name: external-sample-builder -``` - -This update sets the name of the external builder as `external-sample-builder`, and the path of the builder to the scripts provided in this sample. Note that this is the path within the peer container, not your local machine. - -To set the path within the peer container, you will need to modify the docker compose file to mount a couple of additional volumes. Open the file `test-network/compose/docker/docker-compose-test-net.yaml`, and add to the `volumes` section of both `peer0.org1.example.com` and `peer0.org2.example.com` the following two lines: - -``` - - ../..:/opt/gopath/src/github.com/hyperledger/fabric-samples - - ../../config/core.yaml:/etc/hyperledger/peercfg/core.yaml -``` - -This update will mount the `core.yaml` that you modified into the peer container and override the configuration file within the peer image. The update also mounts the fabric-sample builder so that it can be found at the location that you specified in `core.yaml`. You also have the option of commenting out the line `- /var/run/docker.sock:/host/var/run/docker.sock`, since we no longer need to access the docker daemon from inside the peer container to launch the chaincode. - -## Packaging and installing Chaincode - -The Asset-Transfer-Basic external chaincode requires two environment variables to run, `CHAINCODE_SERVER_ADDRESS` and `CHAINCODE_ID`, which are described and set in the `chaincode.env` file. - -You need to provide a `connection.json` configuration file to your peer in order to connect to the external Asset-Transfer-Basic service. The address specified in the `connection.json` must correspond to the `CHAINCODE_SERVER_ADDRESS` value in `chaincode.env`, which is `asset-transfer-basic.org1.example.com:9999` in our example. - -Because we will run our chaincode as an external service, the chaincode itself does not need to be included in the chaincode -package that gets installed to each peer. Only the configuration and metadata information needs to be included -in the package. Since the packaging is trivial, we can manually create the chaincode package. - -Open a new terminal and navigate to the `fabric-samples/asset-transfer-basic/chaincode-external` directory. - -``` -cd fabric-samples/asset-transfer-basic/chaincode-external -``` - -First, create a `code.tar.gz` archive containing the `connection.json` file: - -``` -tar cfz code.tar.gz connection.json -``` - -Then, create the chaincode package, including the `code.tar.gz` file and the supplied `metadata.json` file: - -``` -tar cfz asset-transfer-basic-external.tgz metadata.json code.tar.gz -``` - -You are now ready to deploy the external chaincode sample. - -## Starting the test network - -We will use the Fabric test network to run the external chaincode. Open a new terminal and navigate to the `fabric-samples/test-network` directory. - -``` -cd fabric-samples/test-network -``` - -Run the following command to deploy the test network and create a new channel: - -``` -./network.sh up createChannel -c mychannel -ca -``` - -We are now ready to deploy the external chaincode. - -## Installing the external chaincode - -We can't use the test network script to install an external chaincode so we will have to do a bit more work. However, we can still leverage part of the test-network scripts to make this easier. - -From the `test-network` directory, set the following environment variables to use the Fabric binaries: - -``` -export PATH=${PWD}/../bin:$PATH -export FABRIC_CFG_PATH=$PWD/../config/ -``` - -Run the following command to import functions from the `envVar.sh` script into your terminal. These functions allow you to act as either test network organization. - -``` -. ./scripts/envVar.sh -``` - -Run the following commands to install the `asset-transfer-basic-external.tar.gz` chaincode on org1. The `setGlobals` function simply sets the environment variables that allow you to act as org1 or org2. - -``` -setGlobals 1 -peer lifecycle chaincode install ../asset-transfer-basic/chaincode-external/asset-transfer-basic-external.tgz -``` - -Install the chaincode package on the org2 peer: - -``` -setGlobals 2 -peer lifecycle chaincode install ../asset-transfer-basic/chaincode-external/asset-transfer-basic-external.tgz -``` - -Run the following command to query the package ID of the chaincode that you just installed: - -``` -setGlobals 1 -peer lifecycle chaincode queryinstalled --peerAddresses localhost:7051 --tlsRootCertFiles organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt -``` - -The command will return output similar to the following: - -``` -Installed chaincodes on peer: -Package ID: basic_1.0:ecfc83f251b7c2d9ef376bc3fc20fc6b9744c0fc0a8923092af6542af94790c3, Label: basic_1.0 -``` - -Save the package ID that was returned by the command as an environment variable. The ID will not be the same for all users, so you need to set the variable using the ID from your command window: - -``` -export CHAINCODE_ID=basic_1.0:ecfc83f251b7c2d9ef376bc3fc20fc6b9744c0fc0a8923092af6542af94790c3 -``` - -## Running the Asset-Transfer-Basic external service - -We are going to run the smart contract as an external service by first building and then starting a docker container. Open a new terminal and navigate back to the `chaincode-external` directory: - -``` -cd fabric-samples/asset-transfer-basic/chaincode-external -``` - -In this directory, open the `chaincode.env` file to set the `CHAINCODE_ID` variable to the same package ID that was returned by the `peer lifecycle chaincode queryinstalled` command. The value should be the same as the environment variable that you set in the previous terminal. - -After you edit the `chaincode.env` file, you can use the `Dockerfile` to build an image of the external Asset-Transfer-Basic chaincode: - -``` -docker build -t hyperledger/asset-transfer-basic . -``` - -You can then run the image to start the Asset-Transfer-Basic service: - -``` -docker run -it --rm --name asset-transfer-basic.org1.example.com --hostname asset-transfer-basic.org1.example.com --env-file chaincode.env --network=fabric_test hyperledger/asset-transfer-basic -``` - -This will start and run the external chaincode service within the container. - -## Deploy the Asset-Transfer-Basic external chaincode definition to the channel - -Navigate back to the `test-network` directory to finish deploying the chaincode definition of the external smart contract to the channel. Make sure that your environment variables are still set. - -``` -setGlobals 2 -peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$PWD/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --channelID mychannel --name basic --version 1.0 --package-id $CHAINCODE_ID --sequence 1 - -setGlobals 1 -peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$PWD/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --channelID mychannel --name basic --version 1.0 --package-id $CHAINCODE_ID --sequence 1 - -peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$PWD/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --channelID mychannel --name basic --peerAddresses localhost:7051 --tlsRootCertFiles "$PWD/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1.0 --sequence 1 -``` - -The commands above approve the chaincode definition for the external chaincode and commits the definition to the channel. The resulting output should be similar to the following: - -``` -2020-08-05 15:41:44.982 PDT [chaincodeCmd] ClientWait -> INFO 001 txid [6bdbe040b99a45cc90a23ec21f02ea5da7be8b70590eb04ff3323ef77fdedfc7] committed with status (VALID) at localhost:7051 -2020-08-05 15:41:44.983 PDT [chaincodeCmd] ClientWait -> INFO 002 txid [6bdbe040b99a45cc90a23ec21f02ea5da7be8b70590eb04ff3323ef77fdedfc7] committed with status (VALID) at localhost:9051 -``` - -Now that we have started the chaincode service and deployed it to the channel, we can submit transactions as we would with a normal chaincode. - -## Using the Asset-Transfer-Basic external chaincode - -Open yet another terminal and navigate to the `fabric-samples/asset-transfer-basic/application-gateway-go` directory: - -``` -cd fabric-samples/asset-transfer-basic/application-gateway-go -``` - -Run the following commands to use the node application in this directory to test the external smart contract: - -``` -go run . -``` - -If all goes well, the program should run exactly the same as described in the "Writing Your First Application" tutorial. - -## Enabling TLS for chaincode and peer communication - -**Note:** This section uses an example of self-signed certificate. You may use your organization hosted CA to issue the certificate and generate a key for production deployment. - -In the sample so far, you connected both peers in `test-network` to the single instance of chaincode server. However, if you would like to enable TLS between the peer nodes and the chaincode server, each peer node needs to have its own CA certificate. Enabling TLS is made possible at runtime in the chaincode. - -- As a first step generate a keypair that can be used. Run these commands from the `fabric-samples/asset-transfer-basic/chaincode-external` directory. - -_Find instructions to install `openssl` in [openssl.org](https://www.openssl.org/)_ - -For `org1.example.com` - -``` -openssl req -nodes -x509 -newkey rsa:4096 -keyout crypto/key1.pem -out crypto/cert1.pem -subj "/C=IN/ST=KA/L=Bangalore/O=example Inc/OU=Developer/CN=asset-transfer-basic.org1.example.com/emailAddress=dev@asset-transfer-basic.org1.example.com" -``` - -For `org2.example.com` - -``` -openssl req -nodes -x509 -newkey rsa:4096 -keyout crypto/key2.pem -out crypto/cert2.pem -subj "/C=IN/ST=KA/L=Bangalore/O=example Inc/OU=Developer/CN=asset-transfer-basic.org2.example.com/emailAddress=dev@asset-transfer-basic.org2.example.com" -``` - -- Copy the CA file contents for both `org1.example.com` & `org2.example.com` - -``` -cp ../../test-network/organizations/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem crypto/rootcert1.pem -cp ../../test-network/organizations/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem crypto/rootcert2.pem -``` - -- Generate a client key and cert for auth purpose. You need a key and cert generated from the CA of each organization. Peer nodes act as clients to chaincode server. - -- Change the `connection.json` with the below contents. The `root_cert` parameter is the root CA certificate which the chaincode server is run with. You may run the below commands to get the certificate file contents as strings and copy them when needed. - -``` -awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto/cert1.pem -awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto/cert2.pem -``` - -Similarly, replace the `client_key` and the `client_cert` contents with the values from the previous step. - -``` -{ - "address": "asset-transfer-basic.org1.example.com:9999", - "dial_timeout": "10s", - "tls_required": true, - "client_auth_required": true, - "client_key": "-----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----", - "client_cert": "-----BEGIN CERTIFICATE---- ... -----END CERTIFICATE-----", - "root_cert": "-----BEGIN CERTIFICATE---- ... -----END CERTIFICATE-----" -} -``` - -- Follow the instructions in [Package](#packaging-and-installing-chaincode) and [Install](#installing-the-external-chaincode) steps for each organization. Remember that the chaincode server's address for the second organization is `asset-transfer-basic.org2.example.com:9999`. - -- Copy the appropriate `CHAINCODE_ID` to both [chaincode1.env](./chaincode1.env) and [chaincode2.env](./chaincode2.env) files. Bring up the chaincode containers using the docker-compose command below - -``` -docker-compose up -f docker-compose-chaincode.yaml up --build -d -``` - -- Follow the instructions in [Finish Deployment](#finish-deploying-the-asset-transfer-basic-external-chaincode-) for each organization seperately. diff --git a/asset-transfer-basic/chaincode-external/assetTransfer.go b/asset-transfer-basic/chaincode-external/assetTransfer.go deleted file mode 100644 index 665ccf53..00000000 --- a/asset-transfer-basic/chaincode-external/assetTransfer.go +++ /dev/null @@ -1,297 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "encoding/json" - "fmt" - "log" - "os" - "strconv" - - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -type serverConfig struct { - CCID string - Address string -} - -// SmartContract provides functions for managing an asset -type SmartContract struct { - contractapi.Contract -} - -// Asset describes basic details of what makes up a simple asset -type Asset struct { - ID string `json:"ID"` - Color string `json:"color"` - Size int `json:"size"` - Owner string `json:"owner"` - AppraisedValue int `json:"appraisedValue"` -} - -// QueryResult structure used for handling result of query -type QueryResult struct { - Key string `json:"Key"` - Record *Asset -} - -// InitLedger adds a base set of cars to the ledger -func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error { - assets := []Asset{ - {ID: "asset1", Color: "blue", Size: 5, Owner: "Tomoko", AppraisedValue: 300}, - {ID: "asset2", Color: "red", Size: 5, Owner: "Brad", AppraisedValue: 400}, - {ID: "asset3", Color: "green", Size: 10, Owner: "Jin Soo", AppraisedValue: 500}, - {ID: "asset4", Color: "yellow", Size: 10, Owner: "Max", AppraisedValue: 600}, - {ID: "asset5", Color: "black", Size: 15, Owner: "Adriana", AppraisedValue: 700}, - {ID: "asset6", Color: "white", Size: 15, Owner: "Michel", AppraisedValue: 800}, - } - - for _, asset := range assets { - assetJSON, err := json.Marshal(asset) - if err != nil { - return err - } - - err = ctx.GetStub().PutState(asset.ID, assetJSON) - if err != nil { - return fmt.Errorf("failed to put to world state: %v", err) - } - } - - return nil -} - -// CreateAsset issues a new asset to the world state with given details. -func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id, color string, size int, owner string, appraisedValue int) error { - exists, err := s.AssetExists(ctx, id) - if err != nil { - return err - } - if exists { - return fmt.Errorf("the asset %s already exists", id) - } - asset := Asset{ - ID: id, - Color: color, - Size: size, - Owner: owner, - AppraisedValue: appraisedValue, - } - - assetJSON, err := json.Marshal(asset) - if err != nil { - return err - } - - return ctx.GetStub().PutState(id, assetJSON) -} - -// ReadAsset returns the asset stored in the world state with given id. -func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, id string) (*Asset, error) { - assetJSON, err := ctx.GetStub().GetState(id) - if err != nil { - return nil, fmt.Errorf("failed to read from world state. %s", err.Error()) - } - if assetJSON == nil { - return nil, fmt.Errorf("the asset %s does not exist", id) - } - - var asset Asset - err = json.Unmarshal(assetJSON, &asset) - if err != nil { - return nil, err - } - - return &asset, nil -} - -// UpdateAsset updates an existing asset in the world state with provided parameters. -func (s *SmartContract) UpdateAsset(ctx contractapi.TransactionContextInterface, id, color string, size int, owner string, appraisedValue int) error { - exists, err := s.AssetExists(ctx, id) - if err != nil { - return err - } - if !exists { - return fmt.Errorf("the asset %s does not exist", id) - } - - // overwriting original asset with new asset - asset := Asset{ - ID: id, - Color: color, - Size: size, - Owner: owner, - AppraisedValue: appraisedValue, - } - - assetJSON, err := json.Marshal(asset) - if err != nil { - return err - } - - return ctx.GetStub().PutState(id, assetJSON) -} - -// DeleteAsset deletes a given asset from the world state. -func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface, id string) error { - exists, err := s.AssetExists(ctx, id) - if err != nil { - return err - } - if !exists { - return fmt.Errorf("the asset %s does not exist", id) - } - - return ctx.GetStub().DelState(id) -} - -// AssetExists returns true when asset with given ID exists in world state -func (s *SmartContract) AssetExists(ctx contractapi.TransactionContextInterface, id string) (bool, error) { - assetJSON, err := ctx.GetStub().GetState(id) - if err != nil { - return false, fmt.Errorf("failed to read from world state. %s", err.Error()) - } - - return assetJSON != nil, nil -} - -// TransferAsset updates the owner field of asset with given id in world state, and returns the old owner. -func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface, id string, newOwner string) (string, error) { - asset, err := s.ReadAsset(ctx, id) - if err != nil { - return "", err - } - - oldOwner := asset.Owner - asset.Owner = newOwner - - assetJSON, err := json.Marshal(asset) - if err != nil { - return "", err - } - - err = ctx.GetStub().PutState(id, assetJSON) - if err != nil { - return "", err - } - - return oldOwner, nil -} - -// GetAllAssets returns all assets found in world state -func (s *SmartContract) GetAllAssets(ctx contractapi.TransactionContextInterface) ([]QueryResult, error) { - // range query with empty string for startKey and endKey does an open-ended query of all assets in the chaincode namespace. - resultsIterator, err := ctx.GetStub().GetStateByRange("", "") - - if err != nil { - return nil, err - } - defer resultsIterator.Close() - - var results []QueryResult - - for resultsIterator.HasNext() { - queryResponse, err := resultsIterator.Next() - - if err != nil { - return nil, err - } - - var asset Asset - err = json.Unmarshal(queryResponse.Value, &asset) - if err != nil { - return nil, err - } - - queryResult := QueryResult{Key: queryResponse.Key, Record: &asset} - results = append(results, queryResult) - } - - return results, nil -} - -func main() { - // See chaincode.env.example - config := serverConfig{ - CCID: os.Getenv("CHAINCODE_ID"), - Address: os.Getenv("CHAINCODE_SERVER_ADDRESS"), - } - - chaincode, err := contractapi.NewChaincode(&SmartContract{}) - - if err != nil { - log.Panicf("error create asset-transfer-basic chaincode: %s", err) - } - - server := &shim.ChaincodeServer{ - CCID: config.CCID, - Address: config.Address, - CC: chaincode, - TLSProps: getTLSProperties(), - } - - if err := server.Start(); err != nil { - log.Panicf("error starting asset-transfer-basic chaincode: %s", err) - } -} - -func getTLSProperties() shim.TLSProperties { - // Check if chaincode is TLS enabled - tlsDisabledStr := getEnvOrDefault("CHAINCODE_TLS_DISABLED", "true") - key := getEnvOrDefault("CHAINCODE_TLS_KEY", "") - cert := getEnvOrDefault("CHAINCODE_TLS_CERT", "") - clientCACert := getEnvOrDefault("CHAINCODE_CLIENT_CA_CERT", "") - - // convert tlsDisabledStr to boolean - tlsDisabled := getBoolOrDefault(tlsDisabledStr, false) - var keyBytes, certBytes, clientCACertBytes []byte - var err error - - if !tlsDisabled { - keyBytes, err = os.ReadFile(key) - if err != nil { - log.Panicf("error while reading the crypto file: %s", err) - } - certBytes, err = os.ReadFile(cert) - if err != nil { - log.Panicf("error while reading the crypto file: %s", err) - } - } - // Did not request for the peer cert verification - if clientCACert != "" { - clientCACertBytes, err = os.ReadFile(clientCACert) - if err != nil { - log.Panicf("error while reading the crypto file: %s", err) - } - } - - return shim.TLSProperties{ - Disabled: tlsDisabled, - Key: keyBytes, - Cert: certBytes, - ClientCACerts: clientCACertBytes, - } -} - -func getEnvOrDefault(env, defaultVal string) string { - value, ok := os.LookupEnv(env) - if !ok { - value = defaultVal - } - return value -} - -// Note that the method returns default value if the string -// cannot be parsed! -func getBoolOrDefault(value string, defaultVal bool) bool { - parsed, err := strconv.ParseBool(value) - if err != nil { - return defaultVal - } - return parsed -} diff --git a/asset-transfer-basic/chaincode-external/chaincode.env b/asset-transfer-basic/chaincode-external/chaincode.env deleted file mode 100644 index 3daa988c..00000000 --- a/asset-transfer-basic/chaincode-external/chaincode.env +++ /dev/null @@ -1,24 +0,0 @@ -# CHAINCODE_SERVER_ADDRESS must be set to the host and port where the peer can -# connect to the chaincode server -CHAINCODE_SERVER_ADDRESS=asset-transfer-basic.org1.example.com:9999 - -# CHAINCODE_ID must be set to the Package ID that is assigned to the chaincode -# on install. The `peer lifecycle chaincode queryinstalled` command can be -# used to get the ID after install if required -CHAINCODE_ID=basic_1.0:0262396ccaffaa2174bc09f750f742319c4f14d60b16334d2c8921b6842c090c - -# Optional parameters that will be used for TLS connection between peer node -# and the chaincode. -# TLS is disabled by default, uncomment the following line to enable TLS connection -# CHAINCODE_TLS_DISABLED=false - -# Following variables will be ignored if TLS is not enabled. -# They need to be in PEM format -# CHAINCODE_TLS_KEY=/path/to/private/key/file -# CHAINCODE_TLS_CERT=/path/to/public/cert/file - -# The following variable will be used by the chaincode server to verify the -# connection from the peer node. -# Note that when this is set a single chaincode server cannot be shared -# across organizations unless their root CA is same. -# CHAINCODE_CLIENT_CA_CERT=/path/to/peer/organization/root/ca/cert/file diff --git a/asset-transfer-basic/chaincode-external/chaincode1.env b/asset-transfer-basic/chaincode-external/chaincode1.env deleted file mode 100644 index 26319adb..00000000 --- a/asset-transfer-basic/chaincode-external/chaincode1.env +++ /dev/null @@ -1,24 +0,0 @@ -# CHAINCODE_SERVER_ADDRESS must be set to the host and port where the peer can -# connect to the chaincode server -CHAINCODE_SERVER_ADDRESS=asset-transfer-basic.org1.example.com:9999 - -# CHAINCODE_ID must be set to the Package ID that is assigned to the chaincode -# on install. The `peer lifecycle chaincode queryinstalled` command can be -# used to get the ID after install if required -CHAINCODE_ID=basic_1.0:6726c6b6d8ff66fcf5710b72c6ce512d24f118c51c3de510b3d43e51fa592a7d - -# Optional parameters that will be used for TLS connection between peer node -# and the chaincode. -# TLS is disabled by default, uncomment the following line to enable TLS connection -CHAINCODE_TLS_DISABLED=false - -# Following variables will be ignored if TLS is not enabled. -# They need to be in PEM format -CHAINCODE_TLS_KEY=/crypto/key1.pem -CHAINCODE_TLS_CERT=/crypto/cert1.pem - -# The following variable will be used by the chaincode server to verify the -# connection from the peer node. -# Note that when this is set a single chaincode server cannot be shared -# across organizations unless their root CA is same. -CHAINCODE_CLIENT_CA_CERT=/crypto/rootcert1.pem diff --git a/asset-transfer-basic/chaincode-external/chaincode2.env b/asset-transfer-basic/chaincode-external/chaincode2.env deleted file mode 100644 index 7884f24a..00000000 --- a/asset-transfer-basic/chaincode-external/chaincode2.env +++ /dev/null @@ -1,24 +0,0 @@ -# CHAINCODE_SERVER_ADDRESS must be set to the host and port where the peer can -# connect to the chaincode server -CHAINCODE_SERVER_ADDRESS=asset-transfer-basic.org2.example.com:9999 - -# CHAINCODE_ID must be set to the Package ID that is assigned to the chaincode -# on install. The `peer lifecycle chaincode queryinstalled` command can be -# used to get the ID after install if required -CHAINCODE_ID=basic_1.0:e8f9052385e3763ecf5635591155da05d8efbb6905ccbfc1c7229eb6bd28df1b - -# Optional parameters that will be used for TLS connection between peer node -# and the chaincode. -# TLS is disabled by default, uncomment the following line to enable TLS connection -CHAINCODE_TLS_DISABLED=false - -# Following variables will be ignored if TLS is not enabled. -# They need to be in PEM format -CHAINCODE_TLS_KEY=/crypto/key2.pem -CHAINCODE_TLS_CERT=/crypto/cert2.pem - -# The following variable will be used by the chaincode server to verify the -# connection from the peer node. -# Note that when this is set a single chaincode server cannot be shared -# across organizations unless their root CA is same. -CHAINCODE_CLIENT_CA_CERT=/crypto/rootcert2.pem diff --git a/asset-transfer-basic/chaincode-external/connection.json b/asset-transfer-basic/chaincode-external/connection.json deleted file mode 100644 index d97f8f12..00000000 --- a/asset-transfer-basic/chaincode-external/connection.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "address": "asset-transfer-basic.org1.example.com:9999", - "dial_timeout": "10s", - "tls_required": false -} diff --git a/asset-transfer-basic/chaincode-external/crypto/.gitkeep b/asset-transfer-basic/chaincode-external/crypto/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/asset-transfer-basic/chaincode-external/docker-compose-chaincode.yaml b/asset-transfer-basic/chaincode-external/docker-compose-chaincode.yaml deleted file mode 100644 index f7aa6f29..00000000 --- a/asset-transfer-basic/chaincode-external/docker-compose-chaincode.yaml +++ /dev/null @@ -1,32 +0,0 @@ -version: "3.6" - -networks: - docker_test: - external: true - -services: - asset-transfer-basic.org1.example.com: - build: . - container_name: asset-transfer-basic.org1.example.com - hostname: asset-transfer-basic.org1.example.com - volumes: - - ./crypto:/crypto - env_file: - - chaincode1.env - networks: - docker_test: - expose: - - 9999 - - asset-transfer-basic.org2.example.com: - build: . - container_name: asset-transfer-basic.org2.example.com - hostname: asset-transfer-basic.org2.example.com - volumes: - - ./crypto:/crypto - env_file: - - chaincode2.env - networks: - docker_test: - expose: - - 9999 diff --git a/asset-transfer-basic/chaincode-external/go.mod b/asset-transfer-basic/chaincode-external/go.mod deleted file mode 100644 index b3bde4a4..00000000 --- a/asset-transfer-basic/chaincode-external/go.mod +++ /dev/null @@ -1,28 +0,0 @@ -module github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-external - -go 1.22.0 - -require ( - github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 - github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 -) - -require ( - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.36.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/asset-transfer-basic/chaincode-external/go.sum b/asset-transfer-basic/chaincode-external/go.sum deleted file mode 100644 index fa4d3b24..00000000 --- a/asset-transfer-basic/chaincode-external/go.sum +++ /dev/null @@ -1,61 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 h1:IhkHfrl5X/fVnmB6pWeCYCdIJRi9bxj+WTnVN8DtW3c= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0/go.mod h1:PHHaFffjw7p7n9bmCfcm7RqDqYdivNEsJdiNIKZo5Lk= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 h1:rmUoBmciB0GL/miqcbJmJbgp5QTWoJUrZo+CNxrNLF4= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0/go.mod h1:FeWeO/jwGjiME7ak3GufqKIcwkejtzrDG4QxbfKydWs= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/asset-transfer-basic/chaincode-external/metadata.json b/asset-transfer-basic/chaincode-external/metadata.json deleted file mode 100644 index ae238606..00000000 --- a/asset-transfer-basic/chaincode-external/metadata.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "external", - "label": "basic_1.0" -} diff --git a/asset-transfer-basic/chaincode-external/sampleBuilder/bin/build b/asset-transfer-basic/chaincode-external/sampleBuilder/bin/build deleted file mode 100755 index 57e90f35..00000000 --- a/asset-transfer-basic/chaincode-external/sampleBuilder/bin/build +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -SOURCE=$1 -OUTPUT=$3 - -#external chaincodes expect connection.json file in the chaincode package -if [ ! -f "$SOURCE/connection.json" ]; then - >&2 echo "$SOURCE/connection.json not found" - exit 1 -fi - -#simply copy the endpoint information to specified output location -cp $SOURCE/connection.json $OUTPUT/connection.json - -if [ -d "$SOURCE/metadata" ]; then - cp -a $SOURCE/metadata $OUTPUT/metadata -fi - -exit 0 diff --git a/asset-transfer-basic/chaincode-external/sampleBuilder/bin/detect b/asset-transfer-basic/chaincode-external/sampleBuilder/bin/detect deleted file mode 100755 index d6ed2edc..00000000 --- a/asset-transfer-basic/chaincode-external/sampleBuilder/bin/detect +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -METADIR=$2 -# check if the "type" field is set to "external" -# crude way without jq which is not in the default fabric peer image -TYPE=$(tr -d '\n' < "$METADIR/metadata.json" | awk -F':' '{ for (i = 1; i < NF; i++){ if ($i~/type/) { print $(i+1); break }}}'| cut -d\" -f2) - -if [ "$TYPE" = "external" ]; then - exit 0 -fi - -exit 1 diff --git a/asset-transfer-basic/chaincode-external/sampleBuilder/bin/release b/asset-transfer-basic/chaincode-external/sampleBuilder/bin/release deleted file mode 100755 index cd3cd1b5..00000000 --- a/asset-transfer-basic/chaincode-external/sampleBuilder/bin/release +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -BLD="$1" -RELEASE="$2" - -if [ -d "$BLD/metadata" ]; then - cp -a "$BLD/metadata/"* "$RELEASE/" -fi - -#external chaincodes expect artifacts to be placed under "$RELEASE"/chaincode/server -if [ -f $BLD/connection.json ]; then - mkdir -p "$RELEASE"/chaincode/server - cp $BLD/connection.json "$RELEASE"/chaincode/server - - #if tls_required is true, copy TLS files (using above example, the fully qualified path for these fils would be "$RELEASE"/chaincode/server/tls) - - exit 0 -fi - -exit 1 diff --git a/asset-transfer-basic/chaincode-go/assetTransfer.go b/asset-transfer-basic/chaincode-go/assetTransfer.go deleted file mode 100644 index f86fcac1..00000000 --- a/asset-transfer-basic/chaincode-go/assetTransfer.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "log" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" - "github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-go/chaincode" -) - -func main() { - assetChaincode, err := contractapi.NewChaincode(&chaincode.SmartContract{}) - if err != nil { - log.Panicf("Error creating asset-transfer-basic chaincode: %v", err) - } - - if err := assetChaincode.Start(); err != nil { - log.Panicf("Error starting asset-transfer-basic chaincode: %v", err) - } -} diff --git a/asset-transfer-basic/chaincode-go/chaincode/mocks/chaincodestub.go b/asset-transfer-basic/chaincode-go/chaincode/mocks/chaincodestub.go deleted file mode 100644 index 06248e33..00000000 --- a/asset-transfer-basic/chaincode-go/chaincode/mocks/chaincodestub.go +++ /dev/null @@ -1,2991 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package mocks - -import ( - "sync" - - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-protos-go-apiv2/peer" - "google.golang.org/protobuf/types/known/timestamppb" -) - -type ChaincodeStub struct { - CreateCompositeKeyStub func(string, []string) (string, error) - createCompositeKeyMutex sync.RWMutex - createCompositeKeyArgsForCall []struct { - arg1 string - arg2 []string - } - createCompositeKeyReturns struct { - result1 string - result2 error - } - createCompositeKeyReturnsOnCall map[int]struct { - result1 string - result2 error - } - DelPrivateDataStub func(string, string) error - delPrivateDataMutex sync.RWMutex - delPrivateDataArgsForCall []struct { - arg1 string - arg2 string - } - delPrivateDataReturns struct { - result1 error - } - delPrivateDataReturnsOnCall map[int]struct { - result1 error - } - DelStateStub func(string) error - delStateMutex sync.RWMutex - delStateArgsForCall []struct { - arg1 string - } - delStateReturns struct { - result1 error - } - delStateReturnsOnCall map[int]struct { - result1 error - } - GetArgsStub func() [][]byte - getArgsMutex sync.RWMutex - getArgsArgsForCall []struct { - } - getArgsReturns struct { - result1 [][]byte - } - getArgsReturnsOnCall map[int]struct { - result1 [][]byte - } - GetArgsSliceStub func() ([]byte, error) - getArgsSliceMutex sync.RWMutex - getArgsSliceArgsForCall []struct { - } - getArgsSliceReturns struct { - result1 []byte - result2 error - } - getArgsSliceReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetBindingStub func() ([]byte, error) - getBindingMutex sync.RWMutex - getBindingArgsForCall []struct { - } - getBindingReturns struct { - result1 []byte - result2 error - } - getBindingReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetChannelIDStub func() string - getChannelIDMutex sync.RWMutex - getChannelIDArgsForCall []struct { - } - getChannelIDReturns struct { - result1 string - } - getChannelIDReturnsOnCall map[int]struct { - result1 string - } - GetCreatorStub func() ([]byte, error) - getCreatorMutex sync.RWMutex - getCreatorArgsForCall []struct { - } - getCreatorReturns struct { - result1 []byte - result2 error - } - getCreatorReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetDecorationsStub func() map[string][]byte - getDecorationsMutex sync.RWMutex - getDecorationsArgsForCall []struct { - } - getDecorationsReturns struct { - result1 map[string][]byte - } - getDecorationsReturnsOnCall map[int]struct { - result1 map[string][]byte - } - GetFunctionAndParametersStub func() (string, []string) - getFunctionAndParametersMutex sync.RWMutex - getFunctionAndParametersArgsForCall []struct { - } - getFunctionAndParametersReturns struct { - result1 string - result2 []string - } - getFunctionAndParametersReturnsOnCall map[int]struct { - result1 string - result2 []string - } - GetHistoryForKeyStub func(string) (shim.HistoryQueryIteratorInterface, error) - getHistoryForKeyMutex sync.RWMutex - getHistoryForKeyArgsForCall []struct { - arg1 string - } - getHistoryForKeyReturns struct { - result1 shim.HistoryQueryIteratorInterface - result2 error - } - getHistoryForKeyReturnsOnCall map[int]struct { - result1 shim.HistoryQueryIteratorInterface - result2 error - } - GetPrivateDataStub func(string, string) ([]byte, error) - getPrivateDataMutex sync.RWMutex - getPrivateDataArgsForCall []struct { - arg1 string - arg2 string - } - getPrivateDataReturns struct { - result1 []byte - result2 error - } - getPrivateDataReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetPrivateDataByPartialCompositeKeyStub func(string, string, []string) (shim.StateQueryIteratorInterface, error) - getPrivateDataByPartialCompositeKeyMutex sync.RWMutex - getPrivateDataByPartialCompositeKeyArgsForCall []struct { - arg1 string - arg2 string - arg3 []string - } - getPrivateDataByPartialCompositeKeyReturns struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - getPrivateDataByPartialCompositeKeyReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - GetPrivateDataByRangeStub func(string, string, string) (shim.StateQueryIteratorInterface, error) - getPrivateDataByRangeMutex sync.RWMutex - getPrivateDataByRangeArgsForCall []struct { - arg1 string - arg2 string - arg3 string - } - getPrivateDataByRangeReturns struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - getPrivateDataByRangeReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - GetPrivateDataHashStub func(string, string) ([]byte, error) - getPrivateDataHashMutex sync.RWMutex - getPrivateDataHashArgsForCall []struct { - arg1 string - arg2 string - } - getPrivateDataHashReturns struct { - result1 []byte - result2 error - } - getPrivateDataHashReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetPrivateDataQueryResultStub func(string, string) (shim.StateQueryIteratorInterface, error) - getPrivateDataQueryResultMutex sync.RWMutex - getPrivateDataQueryResultArgsForCall []struct { - arg1 string - arg2 string - } - getPrivateDataQueryResultReturns struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - getPrivateDataQueryResultReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - GetPrivateDataValidationParameterStub func(string, string) ([]byte, error) - getPrivateDataValidationParameterMutex sync.RWMutex - getPrivateDataValidationParameterArgsForCall []struct { - arg1 string - arg2 string - } - getPrivateDataValidationParameterReturns struct { - result1 []byte - result2 error - } - getPrivateDataValidationParameterReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetQueryResultStub func(string) (shim.StateQueryIteratorInterface, error) - getQueryResultMutex sync.RWMutex - getQueryResultArgsForCall []struct { - arg1 string - } - getQueryResultReturns struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - getQueryResultReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - GetQueryResultWithPaginationStub func(string, int32, string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error) - getQueryResultWithPaginationMutex sync.RWMutex - getQueryResultWithPaginationArgsForCall []struct { - arg1 string - arg2 int32 - arg3 string - } - getQueryResultWithPaginationReturns struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - } - getQueryResultWithPaginationReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - } - GetSignedProposalStub func() (*peer.SignedProposal, error) - getSignedProposalMutex sync.RWMutex - getSignedProposalArgsForCall []struct { - } - getSignedProposalReturns struct { - result1 *peer.SignedProposal - result2 error - } - getSignedProposalReturnsOnCall map[int]struct { - result1 *peer.SignedProposal - result2 error - } - GetStateStub func(string) ([]byte, error) - getStateMutex sync.RWMutex - getStateArgsForCall []struct { - arg1 string - } - getStateReturns struct { - result1 []byte - result2 error - } - getStateReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetStateByPartialCompositeKeyStub func(string, []string) (shim.StateQueryIteratorInterface, error) - getStateByPartialCompositeKeyMutex sync.RWMutex - getStateByPartialCompositeKeyArgsForCall []struct { - arg1 string - arg2 []string - } - getStateByPartialCompositeKeyReturns struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - getStateByPartialCompositeKeyReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - GetStateByPartialCompositeKeyWithPaginationStub func(string, []string, int32, string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error) - getStateByPartialCompositeKeyWithPaginationMutex sync.RWMutex - getStateByPartialCompositeKeyWithPaginationArgsForCall []struct { - arg1 string - arg2 []string - arg3 int32 - arg4 string - } - getStateByPartialCompositeKeyWithPaginationReturns struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - } - getStateByPartialCompositeKeyWithPaginationReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - } - GetStateByRangeStub func(string, string) (shim.StateQueryIteratorInterface, error) - getStateByRangeMutex sync.RWMutex - getStateByRangeArgsForCall []struct { - arg1 string - arg2 string - } - getStateByRangeReturns struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - getStateByRangeReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - GetStateByRangeWithPaginationStub func(string, string, int32, string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error) - getStateByRangeWithPaginationMutex sync.RWMutex - getStateByRangeWithPaginationArgsForCall []struct { - arg1 string - arg2 string - arg3 int32 - arg4 string - } - getStateByRangeWithPaginationReturns struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - } - getStateByRangeWithPaginationReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - } - GetStateValidationParameterStub func(string) ([]byte, error) - getStateValidationParameterMutex sync.RWMutex - getStateValidationParameterArgsForCall []struct { - arg1 string - } - getStateValidationParameterReturns struct { - result1 []byte - result2 error - } - getStateValidationParameterReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetStringArgsStub func() []string - getStringArgsMutex sync.RWMutex - getStringArgsArgsForCall []struct { - } - getStringArgsReturns struct { - result1 []string - } - getStringArgsReturnsOnCall map[int]struct { - result1 []string - } - GetTransientStub func() (map[string][]byte, error) - getTransientMutex sync.RWMutex - getTransientArgsForCall []struct { - } - getTransientReturns struct { - result1 map[string][]byte - result2 error - } - getTransientReturnsOnCall map[int]struct { - result1 map[string][]byte - result2 error - } - GetTxIDStub func() string - getTxIDMutex sync.RWMutex - getTxIDArgsForCall []struct { - } - getTxIDReturns struct { - result1 string - } - getTxIDReturnsOnCall map[int]struct { - result1 string - } - GetTxTimestampStub func() (*timestamppb.Timestamp, error) - getTxTimestampMutex sync.RWMutex - getTxTimestampArgsForCall []struct { - } - getTxTimestampReturns struct { - result1 *timestamppb.Timestamp - result2 error - } - getTxTimestampReturnsOnCall map[int]struct { - result1 *timestamppb.Timestamp - result2 error - } - InvokeChaincodeStub func(string, [][]byte, string) *peer.Response - invokeChaincodeMutex sync.RWMutex - invokeChaincodeArgsForCall []struct { - arg1 string - arg2 [][]byte - arg3 string - } - invokeChaincodeReturns struct { - result1 *peer.Response - } - invokeChaincodeReturnsOnCall map[int]struct { - result1 *peer.Response - } - PurgePrivateDataStub func(string, string) error - purgePrivateDataMutex sync.RWMutex - purgePrivateDataArgsForCall []struct { - arg1 string - arg2 string - } - purgePrivateDataReturns struct { - result1 error - } - purgePrivateDataReturnsOnCall map[int]struct { - result1 error - } - PutPrivateDataStub func(string, string, []byte) error - putPrivateDataMutex sync.RWMutex - putPrivateDataArgsForCall []struct { - arg1 string - arg2 string - arg3 []byte - } - putPrivateDataReturns struct { - result1 error - } - putPrivateDataReturnsOnCall map[int]struct { - result1 error - } - PutStateStub func(string, []byte) error - putStateMutex sync.RWMutex - putStateArgsForCall []struct { - arg1 string - arg2 []byte - } - putStateReturns struct { - result1 error - } - putStateReturnsOnCall map[int]struct { - result1 error - } - SetEventStub func(string, []byte) error - setEventMutex sync.RWMutex - setEventArgsForCall []struct { - arg1 string - arg2 []byte - } - setEventReturns struct { - result1 error - } - setEventReturnsOnCall map[int]struct { - result1 error - } - SetPrivateDataValidationParameterStub func(string, string, []byte) error - setPrivateDataValidationParameterMutex sync.RWMutex - setPrivateDataValidationParameterArgsForCall []struct { - arg1 string - arg2 string - arg3 []byte - } - setPrivateDataValidationParameterReturns struct { - result1 error - } - setPrivateDataValidationParameterReturnsOnCall map[int]struct { - result1 error - } - SetStateValidationParameterStub func(string, []byte) error - setStateValidationParameterMutex sync.RWMutex - setStateValidationParameterArgsForCall []struct { - arg1 string - arg2 []byte - } - setStateValidationParameterReturns struct { - result1 error - } - setStateValidationParameterReturnsOnCall map[int]struct { - result1 error - } - SplitCompositeKeyStub func(string) (string, []string, error) - splitCompositeKeyMutex sync.RWMutex - splitCompositeKeyArgsForCall []struct { - arg1 string - } - splitCompositeKeyReturns struct { - result1 string - result2 []string - result3 error - } - splitCompositeKeyReturnsOnCall map[int]struct { - result1 string - result2 []string - result3 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *ChaincodeStub) CreateCompositeKey(arg1 string, arg2 []string) (string, error) { - var arg2Copy []string - if arg2 != nil { - arg2Copy = make([]string, len(arg2)) - copy(arg2Copy, arg2) - } - fake.createCompositeKeyMutex.Lock() - ret, specificReturn := fake.createCompositeKeyReturnsOnCall[len(fake.createCompositeKeyArgsForCall)] - fake.createCompositeKeyArgsForCall = append(fake.createCompositeKeyArgsForCall, struct { - arg1 string - arg2 []string - }{arg1, arg2Copy}) - stub := fake.CreateCompositeKeyStub - fakeReturns := fake.createCompositeKeyReturns - fake.recordInvocation("CreateCompositeKey", []interface{}{arg1, arg2Copy}) - fake.createCompositeKeyMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) CreateCompositeKeyCallCount() int { - fake.createCompositeKeyMutex.RLock() - defer fake.createCompositeKeyMutex.RUnlock() - return len(fake.createCompositeKeyArgsForCall) -} - -func (fake *ChaincodeStub) CreateCompositeKeyCalls(stub func(string, []string) (string, error)) { - fake.createCompositeKeyMutex.Lock() - defer fake.createCompositeKeyMutex.Unlock() - fake.CreateCompositeKeyStub = stub -} - -func (fake *ChaincodeStub) CreateCompositeKeyArgsForCall(i int) (string, []string) { - fake.createCompositeKeyMutex.RLock() - defer fake.createCompositeKeyMutex.RUnlock() - argsForCall := fake.createCompositeKeyArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) CreateCompositeKeyReturns(result1 string, result2 error) { - fake.createCompositeKeyMutex.Lock() - defer fake.createCompositeKeyMutex.Unlock() - fake.CreateCompositeKeyStub = nil - fake.createCompositeKeyReturns = struct { - result1 string - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) CreateCompositeKeyReturnsOnCall(i int, result1 string, result2 error) { - fake.createCompositeKeyMutex.Lock() - defer fake.createCompositeKeyMutex.Unlock() - fake.CreateCompositeKeyStub = nil - if fake.createCompositeKeyReturnsOnCall == nil { - fake.createCompositeKeyReturnsOnCall = make(map[int]struct { - result1 string - result2 error - }) - } - fake.createCompositeKeyReturnsOnCall[i] = struct { - result1 string - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) DelPrivateData(arg1 string, arg2 string) error { - fake.delPrivateDataMutex.Lock() - ret, specificReturn := fake.delPrivateDataReturnsOnCall[len(fake.delPrivateDataArgsForCall)] - fake.delPrivateDataArgsForCall = append(fake.delPrivateDataArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.DelPrivateDataStub - fakeReturns := fake.delPrivateDataReturns - fake.recordInvocation("DelPrivateData", []interface{}{arg1, arg2}) - fake.delPrivateDataMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) DelPrivateDataCallCount() int { - fake.delPrivateDataMutex.RLock() - defer fake.delPrivateDataMutex.RUnlock() - return len(fake.delPrivateDataArgsForCall) -} - -func (fake *ChaincodeStub) DelPrivateDataCalls(stub func(string, string) error) { - fake.delPrivateDataMutex.Lock() - defer fake.delPrivateDataMutex.Unlock() - fake.DelPrivateDataStub = stub -} - -func (fake *ChaincodeStub) DelPrivateDataArgsForCall(i int) (string, string) { - fake.delPrivateDataMutex.RLock() - defer fake.delPrivateDataMutex.RUnlock() - argsForCall := fake.delPrivateDataArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) DelPrivateDataReturns(result1 error) { - fake.delPrivateDataMutex.Lock() - defer fake.delPrivateDataMutex.Unlock() - fake.DelPrivateDataStub = nil - fake.delPrivateDataReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) DelPrivateDataReturnsOnCall(i int, result1 error) { - fake.delPrivateDataMutex.Lock() - defer fake.delPrivateDataMutex.Unlock() - fake.DelPrivateDataStub = nil - if fake.delPrivateDataReturnsOnCall == nil { - fake.delPrivateDataReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.delPrivateDataReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) DelState(arg1 string) error { - fake.delStateMutex.Lock() - ret, specificReturn := fake.delStateReturnsOnCall[len(fake.delStateArgsForCall)] - fake.delStateArgsForCall = append(fake.delStateArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.DelStateStub - fakeReturns := fake.delStateReturns - fake.recordInvocation("DelState", []interface{}{arg1}) - fake.delStateMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) DelStateCallCount() int { - fake.delStateMutex.RLock() - defer fake.delStateMutex.RUnlock() - return len(fake.delStateArgsForCall) -} - -func (fake *ChaincodeStub) DelStateCalls(stub func(string) error) { - fake.delStateMutex.Lock() - defer fake.delStateMutex.Unlock() - fake.DelStateStub = stub -} - -func (fake *ChaincodeStub) DelStateArgsForCall(i int) string { - fake.delStateMutex.RLock() - defer fake.delStateMutex.RUnlock() - argsForCall := fake.delStateArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ChaincodeStub) DelStateReturns(result1 error) { - fake.delStateMutex.Lock() - defer fake.delStateMutex.Unlock() - fake.DelStateStub = nil - fake.delStateReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) DelStateReturnsOnCall(i int, result1 error) { - fake.delStateMutex.Lock() - defer fake.delStateMutex.Unlock() - fake.DelStateStub = nil - if fake.delStateReturnsOnCall == nil { - fake.delStateReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.delStateReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) GetArgs() [][]byte { - fake.getArgsMutex.Lock() - ret, specificReturn := fake.getArgsReturnsOnCall[len(fake.getArgsArgsForCall)] - fake.getArgsArgsForCall = append(fake.getArgsArgsForCall, struct { - }{}) - stub := fake.GetArgsStub - fakeReturns := fake.getArgsReturns - fake.recordInvocation("GetArgs", []interface{}{}) - fake.getArgsMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) GetArgsCallCount() int { - fake.getArgsMutex.RLock() - defer fake.getArgsMutex.RUnlock() - return len(fake.getArgsArgsForCall) -} - -func (fake *ChaincodeStub) GetArgsCalls(stub func() [][]byte) { - fake.getArgsMutex.Lock() - defer fake.getArgsMutex.Unlock() - fake.GetArgsStub = stub -} - -func (fake *ChaincodeStub) GetArgsReturns(result1 [][]byte) { - fake.getArgsMutex.Lock() - defer fake.getArgsMutex.Unlock() - fake.GetArgsStub = nil - fake.getArgsReturns = struct { - result1 [][]byte - }{result1} -} - -func (fake *ChaincodeStub) GetArgsReturnsOnCall(i int, result1 [][]byte) { - fake.getArgsMutex.Lock() - defer fake.getArgsMutex.Unlock() - fake.GetArgsStub = nil - if fake.getArgsReturnsOnCall == nil { - fake.getArgsReturnsOnCall = make(map[int]struct { - result1 [][]byte - }) - } - fake.getArgsReturnsOnCall[i] = struct { - result1 [][]byte - }{result1} -} - -func (fake *ChaincodeStub) GetArgsSlice() ([]byte, error) { - fake.getArgsSliceMutex.Lock() - ret, specificReturn := fake.getArgsSliceReturnsOnCall[len(fake.getArgsSliceArgsForCall)] - fake.getArgsSliceArgsForCall = append(fake.getArgsSliceArgsForCall, struct { - }{}) - stub := fake.GetArgsSliceStub - fakeReturns := fake.getArgsSliceReturns - fake.recordInvocation("GetArgsSlice", []interface{}{}) - fake.getArgsSliceMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetArgsSliceCallCount() int { - fake.getArgsSliceMutex.RLock() - defer fake.getArgsSliceMutex.RUnlock() - return len(fake.getArgsSliceArgsForCall) -} - -func (fake *ChaincodeStub) GetArgsSliceCalls(stub func() ([]byte, error)) { - fake.getArgsSliceMutex.Lock() - defer fake.getArgsSliceMutex.Unlock() - fake.GetArgsSliceStub = stub -} - -func (fake *ChaincodeStub) GetArgsSliceReturns(result1 []byte, result2 error) { - fake.getArgsSliceMutex.Lock() - defer fake.getArgsSliceMutex.Unlock() - fake.GetArgsSliceStub = nil - fake.getArgsSliceReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetArgsSliceReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getArgsSliceMutex.Lock() - defer fake.getArgsSliceMutex.Unlock() - fake.GetArgsSliceStub = nil - if fake.getArgsSliceReturnsOnCall == nil { - fake.getArgsSliceReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getArgsSliceReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetBinding() ([]byte, error) { - fake.getBindingMutex.Lock() - ret, specificReturn := fake.getBindingReturnsOnCall[len(fake.getBindingArgsForCall)] - fake.getBindingArgsForCall = append(fake.getBindingArgsForCall, struct { - }{}) - stub := fake.GetBindingStub - fakeReturns := fake.getBindingReturns - fake.recordInvocation("GetBinding", []interface{}{}) - fake.getBindingMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetBindingCallCount() int { - fake.getBindingMutex.RLock() - defer fake.getBindingMutex.RUnlock() - return len(fake.getBindingArgsForCall) -} - -func (fake *ChaincodeStub) GetBindingCalls(stub func() ([]byte, error)) { - fake.getBindingMutex.Lock() - defer fake.getBindingMutex.Unlock() - fake.GetBindingStub = stub -} - -func (fake *ChaincodeStub) GetBindingReturns(result1 []byte, result2 error) { - fake.getBindingMutex.Lock() - defer fake.getBindingMutex.Unlock() - fake.GetBindingStub = nil - fake.getBindingReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetBindingReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getBindingMutex.Lock() - defer fake.getBindingMutex.Unlock() - fake.GetBindingStub = nil - if fake.getBindingReturnsOnCall == nil { - fake.getBindingReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getBindingReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetChannelID() string { - fake.getChannelIDMutex.Lock() - ret, specificReturn := fake.getChannelIDReturnsOnCall[len(fake.getChannelIDArgsForCall)] - fake.getChannelIDArgsForCall = append(fake.getChannelIDArgsForCall, struct { - }{}) - stub := fake.GetChannelIDStub - fakeReturns := fake.getChannelIDReturns - fake.recordInvocation("GetChannelID", []interface{}{}) - fake.getChannelIDMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) GetChannelIDCallCount() int { - fake.getChannelIDMutex.RLock() - defer fake.getChannelIDMutex.RUnlock() - return len(fake.getChannelIDArgsForCall) -} - -func (fake *ChaincodeStub) GetChannelIDCalls(stub func() string) { - fake.getChannelIDMutex.Lock() - defer fake.getChannelIDMutex.Unlock() - fake.GetChannelIDStub = stub -} - -func (fake *ChaincodeStub) GetChannelIDReturns(result1 string) { - fake.getChannelIDMutex.Lock() - defer fake.getChannelIDMutex.Unlock() - fake.GetChannelIDStub = nil - fake.getChannelIDReturns = struct { - result1 string - }{result1} -} - -func (fake *ChaincodeStub) GetChannelIDReturnsOnCall(i int, result1 string) { - fake.getChannelIDMutex.Lock() - defer fake.getChannelIDMutex.Unlock() - fake.GetChannelIDStub = nil - if fake.getChannelIDReturnsOnCall == nil { - fake.getChannelIDReturnsOnCall = make(map[int]struct { - result1 string - }) - } - fake.getChannelIDReturnsOnCall[i] = struct { - result1 string - }{result1} -} - -func (fake *ChaincodeStub) GetCreator() ([]byte, error) { - fake.getCreatorMutex.Lock() - ret, specificReturn := fake.getCreatorReturnsOnCall[len(fake.getCreatorArgsForCall)] - fake.getCreatorArgsForCall = append(fake.getCreatorArgsForCall, struct { - }{}) - stub := fake.GetCreatorStub - fakeReturns := fake.getCreatorReturns - fake.recordInvocation("GetCreator", []interface{}{}) - fake.getCreatorMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetCreatorCallCount() int { - fake.getCreatorMutex.RLock() - defer fake.getCreatorMutex.RUnlock() - return len(fake.getCreatorArgsForCall) -} - -func (fake *ChaincodeStub) GetCreatorCalls(stub func() ([]byte, error)) { - fake.getCreatorMutex.Lock() - defer fake.getCreatorMutex.Unlock() - fake.GetCreatorStub = stub -} - -func (fake *ChaincodeStub) GetCreatorReturns(result1 []byte, result2 error) { - fake.getCreatorMutex.Lock() - defer fake.getCreatorMutex.Unlock() - fake.GetCreatorStub = nil - fake.getCreatorReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetCreatorReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getCreatorMutex.Lock() - defer fake.getCreatorMutex.Unlock() - fake.GetCreatorStub = nil - if fake.getCreatorReturnsOnCall == nil { - fake.getCreatorReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getCreatorReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetDecorations() map[string][]byte { - fake.getDecorationsMutex.Lock() - ret, specificReturn := fake.getDecorationsReturnsOnCall[len(fake.getDecorationsArgsForCall)] - fake.getDecorationsArgsForCall = append(fake.getDecorationsArgsForCall, struct { - }{}) - stub := fake.GetDecorationsStub - fakeReturns := fake.getDecorationsReturns - fake.recordInvocation("GetDecorations", []interface{}{}) - fake.getDecorationsMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) GetDecorationsCallCount() int { - fake.getDecorationsMutex.RLock() - defer fake.getDecorationsMutex.RUnlock() - return len(fake.getDecorationsArgsForCall) -} - -func (fake *ChaincodeStub) GetDecorationsCalls(stub func() map[string][]byte) { - fake.getDecorationsMutex.Lock() - defer fake.getDecorationsMutex.Unlock() - fake.GetDecorationsStub = stub -} - -func (fake *ChaincodeStub) GetDecorationsReturns(result1 map[string][]byte) { - fake.getDecorationsMutex.Lock() - defer fake.getDecorationsMutex.Unlock() - fake.GetDecorationsStub = nil - fake.getDecorationsReturns = struct { - result1 map[string][]byte - }{result1} -} - -func (fake *ChaincodeStub) GetDecorationsReturnsOnCall(i int, result1 map[string][]byte) { - fake.getDecorationsMutex.Lock() - defer fake.getDecorationsMutex.Unlock() - fake.GetDecorationsStub = nil - if fake.getDecorationsReturnsOnCall == nil { - fake.getDecorationsReturnsOnCall = make(map[int]struct { - result1 map[string][]byte - }) - } - fake.getDecorationsReturnsOnCall[i] = struct { - result1 map[string][]byte - }{result1} -} - -func (fake *ChaincodeStub) GetFunctionAndParameters() (string, []string) { - fake.getFunctionAndParametersMutex.Lock() - ret, specificReturn := fake.getFunctionAndParametersReturnsOnCall[len(fake.getFunctionAndParametersArgsForCall)] - fake.getFunctionAndParametersArgsForCall = append(fake.getFunctionAndParametersArgsForCall, struct { - }{}) - stub := fake.GetFunctionAndParametersStub - fakeReturns := fake.getFunctionAndParametersReturns - fake.recordInvocation("GetFunctionAndParameters", []interface{}{}) - fake.getFunctionAndParametersMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetFunctionAndParametersCallCount() int { - fake.getFunctionAndParametersMutex.RLock() - defer fake.getFunctionAndParametersMutex.RUnlock() - return len(fake.getFunctionAndParametersArgsForCall) -} - -func (fake *ChaincodeStub) GetFunctionAndParametersCalls(stub func() (string, []string)) { - fake.getFunctionAndParametersMutex.Lock() - defer fake.getFunctionAndParametersMutex.Unlock() - fake.GetFunctionAndParametersStub = stub -} - -func (fake *ChaincodeStub) GetFunctionAndParametersReturns(result1 string, result2 []string) { - fake.getFunctionAndParametersMutex.Lock() - defer fake.getFunctionAndParametersMutex.Unlock() - fake.GetFunctionAndParametersStub = nil - fake.getFunctionAndParametersReturns = struct { - result1 string - result2 []string - }{result1, result2} -} - -func (fake *ChaincodeStub) GetFunctionAndParametersReturnsOnCall(i int, result1 string, result2 []string) { - fake.getFunctionAndParametersMutex.Lock() - defer fake.getFunctionAndParametersMutex.Unlock() - fake.GetFunctionAndParametersStub = nil - if fake.getFunctionAndParametersReturnsOnCall == nil { - fake.getFunctionAndParametersReturnsOnCall = make(map[int]struct { - result1 string - result2 []string - }) - } - fake.getFunctionAndParametersReturnsOnCall[i] = struct { - result1 string - result2 []string - }{result1, result2} -} - -func (fake *ChaincodeStub) GetHistoryForKey(arg1 string) (shim.HistoryQueryIteratorInterface, error) { - fake.getHistoryForKeyMutex.Lock() - ret, specificReturn := fake.getHistoryForKeyReturnsOnCall[len(fake.getHistoryForKeyArgsForCall)] - fake.getHistoryForKeyArgsForCall = append(fake.getHistoryForKeyArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.GetHistoryForKeyStub - fakeReturns := fake.getHistoryForKeyReturns - fake.recordInvocation("GetHistoryForKey", []interface{}{arg1}) - fake.getHistoryForKeyMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetHistoryForKeyCallCount() int { - fake.getHistoryForKeyMutex.RLock() - defer fake.getHistoryForKeyMutex.RUnlock() - return len(fake.getHistoryForKeyArgsForCall) -} - -func (fake *ChaincodeStub) GetHistoryForKeyCalls(stub func(string) (shim.HistoryQueryIteratorInterface, error)) { - fake.getHistoryForKeyMutex.Lock() - defer fake.getHistoryForKeyMutex.Unlock() - fake.GetHistoryForKeyStub = stub -} - -func (fake *ChaincodeStub) GetHistoryForKeyArgsForCall(i int) string { - fake.getHistoryForKeyMutex.RLock() - defer fake.getHistoryForKeyMutex.RUnlock() - argsForCall := fake.getHistoryForKeyArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ChaincodeStub) GetHistoryForKeyReturns(result1 shim.HistoryQueryIteratorInterface, result2 error) { - fake.getHistoryForKeyMutex.Lock() - defer fake.getHistoryForKeyMutex.Unlock() - fake.GetHistoryForKeyStub = nil - fake.getHistoryForKeyReturns = struct { - result1 shim.HistoryQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetHistoryForKeyReturnsOnCall(i int, result1 shim.HistoryQueryIteratorInterface, result2 error) { - fake.getHistoryForKeyMutex.Lock() - defer fake.getHistoryForKeyMutex.Unlock() - fake.GetHistoryForKeyStub = nil - if fake.getHistoryForKeyReturnsOnCall == nil { - fake.getHistoryForKeyReturnsOnCall = make(map[int]struct { - result1 shim.HistoryQueryIteratorInterface - result2 error - }) - } - fake.getHistoryForKeyReturnsOnCall[i] = struct { - result1 shim.HistoryQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateData(arg1 string, arg2 string) ([]byte, error) { - fake.getPrivateDataMutex.Lock() - ret, specificReturn := fake.getPrivateDataReturnsOnCall[len(fake.getPrivateDataArgsForCall)] - fake.getPrivateDataArgsForCall = append(fake.getPrivateDataArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.GetPrivateDataStub - fakeReturns := fake.getPrivateDataReturns - fake.recordInvocation("GetPrivateData", []interface{}{arg1, arg2}) - fake.getPrivateDataMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetPrivateDataCallCount() int { - fake.getPrivateDataMutex.RLock() - defer fake.getPrivateDataMutex.RUnlock() - return len(fake.getPrivateDataArgsForCall) -} - -func (fake *ChaincodeStub) GetPrivateDataCalls(stub func(string, string) ([]byte, error)) { - fake.getPrivateDataMutex.Lock() - defer fake.getPrivateDataMutex.Unlock() - fake.GetPrivateDataStub = stub -} - -func (fake *ChaincodeStub) GetPrivateDataArgsForCall(i int) (string, string) { - fake.getPrivateDataMutex.RLock() - defer fake.getPrivateDataMutex.RUnlock() - argsForCall := fake.getPrivateDataArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) GetPrivateDataReturns(result1 []byte, result2 error) { - fake.getPrivateDataMutex.Lock() - defer fake.getPrivateDataMutex.Unlock() - fake.GetPrivateDataStub = nil - fake.getPrivateDataReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getPrivateDataMutex.Lock() - defer fake.getPrivateDataMutex.Unlock() - fake.GetPrivateDataStub = nil - if fake.getPrivateDataReturnsOnCall == nil { - fake.getPrivateDataReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getPrivateDataReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataByPartialCompositeKey(arg1 string, arg2 string, arg3 []string) (shim.StateQueryIteratorInterface, error) { - var arg3Copy []string - if arg3 != nil { - arg3Copy = make([]string, len(arg3)) - copy(arg3Copy, arg3) - } - fake.getPrivateDataByPartialCompositeKeyMutex.Lock() - ret, specificReturn := fake.getPrivateDataByPartialCompositeKeyReturnsOnCall[len(fake.getPrivateDataByPartialCompositeKeyArgsForCall)] - fake.getPrivateDataByPartialCompositeKeyArgsForCall = append(fake.getPrivateDataByPartialCompositeKeyArgsForCall, struct { - arg1 string - arg2 string - arg3 []string - }{arg1, arg2, arg3Copy}) - stub := fake.GetPrivateDataByPartialCompositeKeyStub - fakeReturns := fake.getPrivateDataByPartialCompositeKeyReturns - fake.recordInvocation("GetPrivateDataByPartialCompositeKey", []interface{}{arg1, arg2, arg3Copy}) - fake.getPrivateDataByPartialCompositeKeyMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetPrivateDataByPartialCompositeKeyCallCount() int { - fake.getPrivateDataByPartialCompositeKeyMutex.RLock() - defer fake.getPrivateDataByPartialCompositeKeyMutex.RUnlock() - return len(fake.getPrivateDataByPartialCompositeKeyArgsForCall) -} - -func (fake *ChaincodeStub) GetPrivateDataByPartialCompositeKeyCalls(stub func(string, string, []string) (shim.StateQueryIteratorInterface, error)) { - fake.getPrivateDataByPartialCompositeKeyMutex.Lock() - defer fake.getPrivateDataByPartialCompositeKeyMutex.Unlock() - fake.GetPrivateDataByPartialCompositeKeyStub = stub -} - -func (fake *ChaincodeStub) GetPrivateDataByPartialCompositeKeyArgsForCall(i int) (string, string, []string) { - fake.getPrivateDataByPartialCompositeKeyMutex.RLock() - defer fake.getPrivateDataByPartialCompositeKeyMutex.RUnlock() - argsForCall := fake.getPrivateDataByPartialCompositeKeyArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *ChaincodeStub) GetPrivateDataByPartialCompositeKeyReturns(result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getPrivateDataByPartialCompositeKeyMutex.Lock() - defer fake.getPrivateDataByPartialCompositeKeyMutex.Unlock() - fake.GetPrivateDataByPartialCompositeKeyStub = nil - fake.getPrivateDataByPartialCompositeKeyReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataByPartialCompositeKeyReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getPrivateDataByPartialCompositeKeyMutex.Lock() - defer fake.getPrivateDataByPartialCompositeKeyMutex.Unlock() - fake.GetPrivateDataByPartialCompositeKeyStub = nil - if fake.getPrivateDataByPartialCompositeKeyReturnsOnCall == nil { - fake.getPrivateDataByPartialCompositeKeyReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - }) - } - fake.getPrivateDataByPartialCompositeKeyReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataByRange(arg1 string, arg2 string, arg3 string) (shim.StateQueryIteratorInterface, error) { - fake.getPrivateDataByRangeMutex.Lock() - ret, specificReturn := fake.getPrivateDataByRangeReturnsOnCall[len(fake.getPrivateDataByRangeArgsForCall)] - fake.getPrivateDataByRangeArgsForCall = append(fake.getPrivateDataByRangeArgsForCall, struct { - arg1 string - arg2 string - arg3 string - }{arg1, arg2, arg3}) - stub := fake.GetPrivateDataByRangeStub - fakeReturns := fake.getPrivateDataByRangeReturns - fake.recordInvocation("GetPrivateDataByRange", []interface{}{arg1, arg2, arg3}) - fake.getPrivateDataByRangeMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetPrivateDataByRangeCallCount() int { - fake.getPrivateDataByRangeMutex.RLock() - defer fake.getPrivateDataByRangeMutex.RUnlock() - return len(fake.getPrivateDataByRangeArgsForCall) -} - -func (fake *ChaincodeStub) GetPrivateDataByRangeCalls(stub func(string, string, string) (shim.StateQueryIteratorInterface, error)) { - fake.getPrivateDataByRangeMutex.Lock() - defer fake.getPrivateDataByRangeMutex.Unlock() - fake.GetPrivateDataByRangeStub = stub -} - -func (fake *ChaincodeStub) GetPrivateDataByRangeArgsForCall(i int) (string, string, string) { - fake.getPrivateDataByRangeMutex.RLock() - defer fake.getPrivateDataByRangeMutex.RUnlock() - argsForCall := fake.getPrivateDataByRangeArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *ChaincodeStub) GetPrivateDataByRangeReturns(result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getPrivateDataByRangeMutex.Lock() - defer fake.getPrivateDataByRangeMutex.Unlock() - fake.GetPrivateDataByRangeStub = nil - fake.getPrivateDataByRangeReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataByRangeReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getPrivateDataByRangeMutex.Lock() - defer fake.getPrivateDataByRangeMutex.Unlock() - fake.GetPrivateDataByRangeStub = nil - if fake.getPrivateDataByRangeReturnsOnCall == nil { - fake.getPrivateDataByRangeReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - }) - } - fake.getPrivateDataByRangeReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataHash(arg1 string, arg2 string) ([]byte, error) { - fake.getPrivateDataHashMutex.Lock() - ret, specificReturn := fake.getPrivateDataHashReturnsOnCall[len(fake.getPrivateDataHashArgsForCall)] - fake.getPrivateDataHashArgsForCall = append(fake.getPrivateDataHashArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.GetPrivateDataHashStub - fakeReturns := fake.getPrivateDataHashReturns - fake.recordInvocation("GetPrivateDataHash", []interface{}{arg1, arg2}) - fake.getPrivateDataHashMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetPrivateDataHashCallCount() int { - fake.getPrivateDataHashMutex.RLock() - defer fake.getPrivateDataHashMutex.RUnlock() - return len(fake.getPrivateDataHashArgsForCall) -} - -func (fake *ChaincodeStub) GetPrivateDataHashCalls(stub func(string, string) ([]byte, error)) { - fake.getPrivateDataHashMutex.Lock() - defer fake.getPrivateDataHashMutex.Unlock() - fake.GetPrivateDataHashStub = stub -} - -func (fake *ChaincodeStub) GetPrivateDataHashArgsForCall(i int) (string, string) { - fake.getPrivateDataHashMutex.RLock() - defer fake.getPrivateDataHashMutex.RUnlock() - argsForCall := fake.getPrivateDataHashArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) GetPrivateDataHashReturns(result1 []byte, result2 error) { - fake.getPrivateDataHashMutex.Lock() - defer fake.getPrivateDataHashMutex.Unlock() - fake.GetPrivateDataHashStub = nil - fake.getPrivateDataHashReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataHashReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getPrivateDataHashMutex.Lock() - defer fake.getPrivateDataHashMutex.Unlock() - fake.GetPrivateDataHashStub = nil - if fake.getPrivateDataHashReturnsOnCall == nil { - fake.getPrivateDataHashReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getPrivateDataHashReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataQueryResult(arg1 string, arg2 string) (shim.StateQueryIteratorInterface, error) { - fake.getPrivateDataQueryResultMutex.Lock() - ret, specificReturn := fake.getPrivateDataQueryResultReturnsOnCall[len(fake.getPrivateDataQueryResultArgsForCall)] - fake.getPrivateDataQueryResultArgsForCall = append(fake.getPrivateDataQueryResultArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.GetPrivateDataQueryResultStub - fakeReturns := fake.getPrivateDataQueryResultReturns - fake.recordInvocation("GetPrivateDataQueryResult", []interface{}{arg1, arg2}) - fake.getPrivateDataQueryResultMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetPrivateDataQueryResultCallCount() int { - fake.getPrivateDataQueryResultMutex.RLock() - defer fake.getPrivateDataQueryResultMutex.RUnlock() - return len(fake.getPrivateDataQueryResultArgsForCall) -} - -func (fake *ChaincodeStub) GetPrivateDataQueryResultCalls(stub func(string, string) (shim.StateQueryIteratorInterface, error)) { - fake.getPrivateDataQueryResultMutex.Lock() - defer fake.getPrivateDataQueryResultMutex.Unlock() - fake.GetPrivateDataQueryResultStub = stub -} - -func (fake *ChaincodeStub) GetPrivateDataQueryResultArgsForCall(i int) (string, string) { - fake.getPrivateDataQueryResultMutex.RLock() - defer fake.getPrivateDataQueryResultMutex.RUnlock() - argsForCall := fake.getPrivateDataQueryResultArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) GetPrivateDataQueryResultReturns(result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getPrivateDataQueryResultMutex.Lock() - defer fake.getPrivateDataQueryResultMutex.Unlock() - fake.GetPrivateDataQueryResultStub = nil - fake.getPrivateDataQueryResultReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataQueryResultReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getPrivateDataQueryResultMutex.Lock() - defer fake.getPrivateDataQueryResultMutex.Unlock() - fake.GetPrivateDataQueryResultStub = nil - if fake.getPrivateDataQueryResultReturnsOnCall == nil { - fake.getPrivateDataQueryResultReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - }) - } - fake.getPrivateDataQueryResultReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataValidationParameter(arg1 string, arg2 string) ([]byte, error) { - fake.getPrivateDataValidationParameterMutex.Lock() - ret, specificReturn := fake.getPrivateDataValidationParameterReturnsOnCall[len(fake.getPrivateDataValidationParameterArgsForCall)] - fake.getPrivateDataValidationParameterArgsForCall = append(fake.getPrivateDataValidationParameterArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.GetPrivateDataValidationParameterStub - fakeReturns := fake.getPrivateDataValidationParameterReturns - fake.recordInvocation("GetPrivateDataValidationParameter", []interface{}{arg1, arg2}) - fake.getPrivateDataValidationParameterMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetPrivateDataValidationParameterCallCount() int { - fake.getPrivateDataValidationParameterMutex.RLock() - defer fake.getPrivateDataValidationParameterMutex.RUnlock() - return len(fake.getPrivateDataValidationParameterArgsForCall) -} - -func (fake *ChaincodeStub) GetPrivateDataValidationParameterCalls(stub func(string, string) ([]byte, error)) { - fake.getPrivateDataValidationParameterMutex.Lock() - defer fake.getPrivateDataValidationParameterMutex.Unlock() - fake.GetPrivateDataValidationParameterStub = stub -} - -func (fake *ChaincodeStub) GetPrivateDataValidationParameterArgsForCall(i int) (string, string) { - fake.getPrivateDataValidationParameterMutex.RLock() - defer fake.getPrivateDataValidationParameterMutex.RUnlock() - argsForCall := fake.getPrivateDataValidationParameterArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) GetPrivateDataValidationParameterReturns(result1 []byte, result2 error) { - fake.getPrivateDataValidationParameterMutex.Lock() - defer fake.getPrivateDataValidationParameterMutex.Unlock() - fake.GetPrivateDataValidationParameterStub = nil - fake.getPrivateDataValidationParameterReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataValidationParameterReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getPrivateDataValidationParameterMutex.Lock() - defer fake.getPrivateDataValidationParameterMutex.Unlock() - fake.GetPrivateDataValidationParameterStub = nil - if fake.getPrivateDataValidationParameterReturnsOnCall == nil { - fake.getPrivateDataValidationParameterReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getPrivateDataValidationParameterReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetQueryResult(arg1 string) (shim.StateQueryIteratorInterface, error) { - fake.getQueryResultMutex.Lock() - ret, specificReturn := fake.getQueryResultReturnsOnCall[len(fake.getQueryResultArgsForCall)] - fake.getQueryResultArgsForCall = append(fake.getQueryResultArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.GetQueryResultStub - fakeReturns := fake.getQueryResultReturns - fake.recordInvocation("GetQueryResult", []interface{}{arg1}) - fake.getQueryResultMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetQueryResultCallCount() int { - fake.getQueryResultMutex.RLock() - defer fake.getQueryResultMutex.RUnlock() - return len(fake.getQueryResultArgsForCall) -} - -func (fake *ChaincodeStub) GetQueryResultCalls(stub func(string) (shim.StateQueryIteratorInterface, error)) { - fake.getQueryResultMutex.Lock() - defer fake.getQueryResultMutex.Unlock() - fake.GetQueryResultStub = stub -} - -func (fake *ChaincodeStub) GetQueryResultArgsForCall(i int) string { - fake.getQueryResultMutex.RLock() - defer fake.getQueryResultMutex.RUnlock() - argsForCall := fake.getQueryResultArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ChaincodeStub) GetQueryResultReturns(result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getQueryResultMutex.Lock() - defer fake.getQueryResultMutex.Unlock() - fake.GetQueryResultStub = nil - fake.getQueryResultReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetQueryResultReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getQueryResultMutex.Lock() - defer fake.getQueryResultMutex.Unlock() - fake.GetQueryResultStub = nil - if fake.getQueryResultReturnsOnCall == nil { - fake.getQueryResultReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - }) - } - fake.getQueryResultReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetQueryResultWithPagination(arg1 string, arg2 int32, arg3 string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error) { - fake.getQueryResultWithPaginationMutex.Lock() - ret, specificReturn := fake.getQueryResultWithPaginationReturnsOnCall[len(fake.getQueryResultWithPaginationArgsForCall)] - fake.getQueryResultWithPaginationArgsForCall = append(fake.getQueryResultWithPaginationArgsForCall, struct { - arg1 string - arg2 int32 - arg3 string - }{arg1, arg2, arg3}) - stub := fake.GetQueryResultWithPaginationStub - fakeReturns := fake.getQueryResultWithPaginationReturns - fake.recordInvocation("GetQueryResultWithPagination", []interface{}{arg1, arg2, arg3}) - fake.getQueryResultWithPaginationMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *ChaincodeStub) GetQueryResultWithPaginationCallCount() int { - fake.getQueryResultWithPaginationMutex.RLock() - defer fake.getQueryResultWithPaginationMutex.RUnlock() - return len(fake.getQueryResultWithPaginationArgsForCall) -} - -func (fake *ChaincodeStub) GetQueryResultWithPaginationCalls(stub func(string, int32, string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error)) { - fake.getQueryResultWithPaginationMutex.Lock() - defer fake.getQueryResultWithPaginationMutex.Unlock() - fake.GetQueryResultWithPaginationStub = stub -} - -func (fake *ChaincodeStub) GetQueryResultWithPaginationArgsForCall(i int) (string, int32, string) { - fake.getQueryResultWithPaginationMutex.RLock() - defer fake.getQueryResultWithPaginationMutex.RUnlock() - argsForCall := fake.getQueryResultWithPaginationArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *ChaincodeStub) GetQueryResultWithPaginationReturns(result1 shim.StateQueryIteratorInterface, result2 *peer.QueryResponseMetadata, result3 error) { - fake.getQueryResultWithPaginationMutex.Lock() - defer fake.getQueryResultWithPaginationMutex.Unlock() - fake.GetQueryResultWithPaginationStub = nil - fake.getQueryResultWithPaginationReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) GetQueryResultWithPaginationReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 *peer.QueryResponseMetadata, result3 error) { - fake.getQueryResultWithPaginationMutex.Lock() - defer fake.getQueryResultWithPaginationMutex.Unlock() - fake.GetQueryResultWithPaginationStub = nil - if fake.getQueryResultWithPaginationReturnsOnCall == nil { - fake.getQueryResultWithPaginationReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }) - } - fake.getQueryResultWithPaginationReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) GetSignedProposal() (*peer.SignedProposal, error) { - fake.getSignedProposalMutex.Lock() - ret, specificReturn := fake.getSignedProposalReturnsOnCall[len(fake.getSignedProposalArgsForCall)] - fake.getSignedProposalArgsForCall = append(fake.getSignedProposalArgsForCall, struct { - }{}) - stub := fake.GetSignedProposalStub - fakeReturns := fake.getSignedProposalReturns - fake.recordInvocation("GetSignedProposal", []interface{}{}) - fake.getSignedProposalMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetSignedProposalCallCount() int { - fake.getSignedProposalMutex.RLock() - defer fake.getSignedProposalMutex.RUnlock() - return len(fake.getSignedProposalArgsForCall) -} - -func (fake *ChaincodeStub) GetSignedProposalCalls(stub func() (*peer.SignedProposal, error)) { - fake.getSignedProposalMutex.Lock() - defer fake.getSignedProposalMutex.Unlock() - fake.GetSignedProposalStub = stub -} - -func (fake *ChaincodeStub) GetSignedProposalReturns(result1 *peer.SignedProposal, result2 error) { - fake.getSignedProposalMutex.Lock() - defer fake.getSignedProposalMutex.Unlock() - fake.GetSignedProposalStub = nil - fake.getSignedProposalReturns = struct { - result1 *peer.SignedProposal - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetSignedProposalReturnsOnCall(i int, result1 *peer.SignedProposal, result2 error) { - fake.getSignedProposalMutex.Lock() - defer fake.getSignedProposalMutex.Unlock() - fake.GetSignedProposalStub = nil - if fake.getSignedProposalReturnsOnCall == nil { - fake.getSignedProposalReturnsOnCall = make(map[int]struct { - result1 *peer.SignedProposal - result2 error - }) - } - fake.getSignedProposalReturnsOnCall[i] = struct { - result1 *peer.SignedProposal - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetState(arg1 string) ([]byte, error) { - fake.getStateMutex.Lock() - ret, specificReturn := fake.getStateReturnsOnCall[len(fake.getStateArgsForCall)] - fake.getStateArgsForCall = append(fake.getStateArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.GetStateStub - fakeReturns := fake.getStateReturns - fake.recordInvocation("GetState", []interface{}{arg1}) - fake.getStateMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetStateCallCount() int { - fake.getStateMutex.RLock() - defer fake.getStateMutex.RUnlock() - return len(fake.getStateArgsForCall) -} - -func (fake *ChaincodeStub) GetStateCalls(stub func(string) ([]byte, error)) { - fake.getStateMutex.Lock() - defer fake.getStateMutex.Unlock() - fake.GetStateStub = stub -} - -func (fake *ChaincodeStub) GetStateArgsForCall(i int) string { - fake.getStateMutex.RLock() - defer fake.getStateMutex.RUnlock() - argsForCall := fake.getStateArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ChaincodeStub) GetStateReturns(result1 []byte, result2 error) { - fake.getStateMutex.Lock() - defer fake.getStateMutex.Unlock() - fake.GetStateStub = nil - fake.getStateReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getStateMutex.Lock() - defer fake.getStateMutex.Unlock() - fake.GetStateStub = nil - if fake.getStateReturnsOnCall == nil { - fake.getStateReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getStateReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKey(arg1 string, arg2 []string) (shim.StateQueryIteratorInterface, error) { - var arg2Copy []string - if arg2 != nil { - arg2Copy = make([]string, len(arg2)) - copy(arg2Copy, arg2) - } - fake.getStateByPartialCompositeKeyMutex.Lock() - ret, specificReturn := fake.getStateByPartialCompositeKeyReturnsOnCall[len(fake.getStateByPartialCompositeKeyArgsForCall)] - fake.getStateByPartialCompositeKeyArgsForCall = append(fake.getStateByPartialCompositeKeyArgsForCall, struct { - arg1 string - arg2 []string - }{arg1, arg2Copy}) - stub := fake.GetStateByPartialCompositeKeyStub - fakeReturns := fake.getStateByPartialCompositeKeyReturns - fake.recordInvocation("GetStateByPartialCompositeKey", []interface{}{arg1, arg2Copy}) - fake.getStateByPartialCompositeKeyMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyCallCount() int { - fake.getStateByPartialCompositeKeyMutex.RLock() - defer fake.getStateByPartialCompositeKeyMutex.RUnlock() - return len(fake.getStateByPartialCompositeKeyArgsForCall) -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyCalls(stub func(string, []string) (shim.StateQueryIteratorInterface, error)) { - fake.getStateByPartialCompositeKeyMutex.Lock() - defer fake.getStateByPartialCompositeKeyMutex.Unlock() - fake.GetStateByPartialCompositeKeyStub = stub -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyArgsForCall(i int) (string, []string) { - fake.getStateByPartialCompositeKeyMutex.RLock() - defer fake.getStateByPartialCompositeKeyMutex.RUnlock() - argsForCall := fake.getStateByPartialCompositeKeyArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyReturns(result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getStateByPartialCompositeKeyMutex.Lock() - defer fake.getStateByPartialCompositeKeyMutex.Unlock() - fake.GetStateByPartialCompositeKeyStub = nil - fake.getStateByPartialCompositeKeyReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getStateByPartialCompositeKeyMutex.Lock() - defer fake.getStateByPartialCompositeKeyMutex.Unlock() - fake.GetStateByPartialCompositeKeyStub = nil - if fake.getStateByPartialCompositeKeyReturnsOnCall == nil { - fake.getStateByPartialCompositeKeyReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - }) - } - fake.getStateByPartialCompositeKeyReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyWithPagination(arg1 string, arg2 []string, arg3 int32, arg4 string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error) { - var arg2Copy []string - if arg2 != nil { - arg2Copy = make([]string, len(arg2)) - copy(arg2Copy, arg2) - } - fake.getStateByPartialCompositeKeyWithPaginationMutex.Lock() - ret, specificReturn := fake.getStateByPartialCompositeKeyWithPaginationReturnsOnCall[len(fake.getStateByPartialCompositeKeyWithPaginationArgsForCall)] - fake.getStateByPartialCompositeKeyWithPaginationArgsForCall = append(fake.getStateByPartialCompositeKeyWithPaginationArgsForCall, struct { - arg1 string - arg2 []string - arg3 int32 - arg4 string - }{arg1, arg2Copy, arg3, arg4}) - stub := fake.GetStateByPartialCompositeKeyWithPaginationStub - fakeReturns := fake.getStateByPartialCompositeKeyWithPaginationReturns - fake.recordInvocation("GetStateByPartialCompositeKeyWithPagination", []interface{}{arg1, arg2Copy, arg3, arg4}) - fake.getStateByPartialCompositeKeyWithPaginationMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyWithPaginationCallCount() int { - fake.getStateByPartialCompositeKeyWithPaginationMutex.RLock() - defer fake.getStateByPartialCompositeKeyWithPaginationMutex.RUnlock() - return len(fake.getStateByPartialCompositeKeyWithPaginationArgsForCall) -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyWithPaginationCalls(stub func(string, []string, int32, string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error)) { - fake.getStateByPartialCompositeKeyWithPaginationMutex.Lock() - defer fake.getStateByPartialCompositeKeyWithPaginationMutex.Unlock() - fake.GetStateByPartialCompositeKeyWithPaginationStub = stub -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyWithPaginationArgsForCall(i int) (string, []string, int32, string) { - fake.getStateByPartialCompositeKeyWithPaginationMutex.RLock() - defer fake.getStateByPartialCompositeKeyWithPaginationMutex.RUnlock() - argsForCall := fake.getStateByPartialCompositeKeyWithPaginationArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyWithPaginationReturns(result1 shim.StateQueryIteratorInterface, result2 *peer.QueryResponseMetadata, result3 error) { - fake.getStateByPartialCompositeKeyWithPaginationMutex.Lock() - defer fake.getStateByPartialCompositeKeyWithPaginationMutex.Unlock() - fake.GetStateByPartialCompositeKeyWithPaginationStub = nil - fake.getStateByPartialCompositeKeyWithPaginationReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyWithPaginationReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 *peer.QueryResponseMetadata, result3 error) { - fake.getStateByPartialCompositeKeyWithPaginationMutex.Lock() - defer fake.getStateByPartialCompositeKeyWithPaginationMutex.Unlock() - fake.GetStateByPartialCompositeKeyWithPaginationStub = nil - if fake.getStateByPartialCompositeKeyWithPaginationReturnsOnCall == nil { - fake.getStateByPartialCompositeKeyWithPaginationReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }) - } - fake.getStateByPartialCompositeKeyWithPaginationReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) GetStateByRange(arg1 string, arg2 string) (shim.StateQueryIteratorInterface, error) { - fake.getStateByRangeMutex.Lock() - ret, specificReturn := fake.getStateByRangeReturnsOnCall[len(fake.getStateByRangeArgsForCall)] - fake.getStateByRangeArgsForCall = append(fake.getStateByRangeArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.GetStateByRangeStub - fakeReturns := fake.getStateByRangeReturns - fake.recordInvocation("GetStateByRange", []interface{}{arg1, arg2}) - fake.getStateByRangeMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetStateByRangeCallCount() int { - fake.getStateByRangeMutex.RLock() - defer fake.getStateByRangeMutex.RUnlock() - return len(fake.getStateByRangeArgsForCall) -} - -func (fake *ChaincodeStub) GetStateByRangeCalls(stub func(string, string) (shim.StateQueryIteratorInterface, error)) { - fake.getStateByRangeMutex.Lock() - defer fake.getStateByRangeMutex.Unlock() - fake.GetStateByRangeStub = stub -} - -func (fake *ChaincodeStub) GetStateByRangeArgsForCall(i int) (string, string) { - fake.getStateByRangeMutex.RLock() - defer fake.getStateByRangeMutex.RUnlock() - argsForCall := fake.getStateByRangeArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) GetStateByRangeReturns(result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getStateByRangeMutex.Lock() - defer fake.getStateByRangeMutex.Unlock() - fake.GetStateByRangeStub = nil - fake.getStateByRangeReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateByRangeReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getStateByRangeMutex.Lock() - defer fake.getStateByRangeMutex.Unlock() - fake.GetStateByRangeStub = nil - if fake.getStateByRangeReturnsOnCall == nil { - fake.getStateByRangeReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - }) - } - fake.getStateByRangeReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateByRangeWithPagination(arg1 string, arg2 string, arg3 int32, arg4 string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error) { - fake.getStateByRangeWithPaginationMutex.Lock() - ret, specificReturn := fake.getStateByRangeWithPaginationReturnsOnCall[len(fake.getStateByRangeWithPaginationArgsForCall)] - fake.getStateByRangeWithPaginationArgsForCall = append(fake.getStateByRangeWithPaginationArgsForCall, struct { - arg1 string - arg2 string - arg3 int32 - arg4 string - }{arg1, arg2, arg3, arg4}) - stub := fake.GetStateByRangeWithPaginationStub - fakeReturns := fake.getStateByRangeWithPaginationReturns - fake.recordInvocation("GetStateByRangeWithPagination", []interface{}{arg1, arg2, arg3, arg4}) - fake.getStateByRangeWithPaginationMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *ChaincodeStub) GetStateByRangeWithPaginationCallCount() int { - fake.getStateByRangeWithPaginationMutex.RLock() - defer fake.getStateByRangeWithPaginationMutex.RUnlock() - return len(fake.getStateByRangeWithPaginationArgsForCall) -} - -func (fake *ChaincodeStub) GetStateByRangeWithPaginationCalls(stub func(string, string, int32, string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error)) { - fake.getStateByRangeWithPaginationMutex.Lock() - defer fake.getStateByRangeWithPaginationMutex.Unlock() - fake.GetStateByRangeWithPaginationStub = stub -} - -func (fake *ChaincodeStub) GetStateByRangeWithPaginationArgsForCall(i int) (string, string, int32, string) { - fake.getStateByRangeWithPaginationMutex.RLock() - defer fake.getStateByRangeWithPaginationMutex.RUnlock() - argsForCall := fake.getStateByRangeWithPaginationArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *ChaincodeStub) GetStateByRangeWithPaginationReturns(result1 shim.StateQueryIteratorInterface, result2 *peer.QueryResponseMetadata, result3 error) { - fake.getStateByRangeWithPaginationMutex.Lock() - defer fake.getStateByRangeWithPaginationMutex.Unlock() - fake.GetStateByRangeWithPaginationStub = nil - fake.getStateByRangeWithPaginationReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) GetStateByRangeWithPaginationReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 *peer.QueryResponseMetadata, result3 error) { - fake.getStateByRangeWithPaginationMutex.Lock() - defer fake.getStateByRangeWithPaginationMutex.Unlock() - fake.GetStateByRangeWithPaginationStub = nil - if fake.getStateByRangeWithPaginationReturnsOnCall == nil { - fake.getStateByRangeWithPaginationReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }) - } - fake.getStateByRangeWithPaginationReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) GetStateValidationParameter(arg1 string) ([]byte, error) { - fake.getStateValidationParameterMutex.Lock() - ret, specificReturn := fake.getStateValidationParameterReturnsOnCall[len(fake.getStateValidationParameterArgsForCall)] - fake.getStateValidationParameterArgsForCall = append(fake.getStateValidationParameterArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.GetStateValidationParameterStub - fakeReturns := fake.getStateValidationParameterReturns - fake.recordInvocation("GetStateValidationParameter", []interface{}{arg1}) - fake.getStateValidationParameterMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetStateValidationParameterCallCount() int { - fake.getStateValidationParameterMutex.RLock() - defer fake.getStateValidationParameterMutex.RUnlock() - return len(fake.getStateValidationParameterArgsForCall) -} - -func (fake *ChaincodeStub) GetStateValidationParameterCalls(stub func(string) ([]byte, error)) { - fake.getStateValidationParameterMutex.Lock() - defer fake.getStateValidationParameterMutex.Unlock() - fake.GetStateValidationParameterStub = stub -} - -func (fake *ChaincodeStub) GetStateValidationParameterArgsForCall(i int) string { - fake.getStateValidationParameterMutex.RLock() - defer fake.getStateValidationParameterMutex.RUnlock() - argsForCall := fake.getStateValidationParameterArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ChaincodeStub) GetStateValidationParameterReturns(result1 []byte, result2 error) { - fake.getStateValidationParameterMutex.Lock() - defer fake.getStateValidationParameterMutex.Unlock() - fake.GetStateValidationParameterStub = nil - fake.getStateValidationParameterReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateValidationParameterReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getStateValidationParameterMutex.Lock() - defer fake.getStateValidationParameterMutex.Unlock() - fake.GetStateValidationParameterStub = nil - if fake.getStateValidationParameterReturnsOnCall == nil { - fake.getStateValidationParameterReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getStateValidationParameterReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStringArgs() []string { - fake.getStringArgsMutex.Lock() - ret, specificReturn := fake.getStringArgsReturnsOnCall[len(fake.getStringArgsArgsForCall)] - fake.getStringArgsArgsForCall = append(fake.getStringArgsArgsForCall, struct { - }{}) - stub := fake.GetStringArgsStub - fakeReturns := fake.getStringArgsReturns - fake.recordInvocation("GetStringArgs", []interface{}{}) - fake.getStringArgsMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) GetStringArgsCallCount() int { - fake.getStringArgsMutex.RLock() - defer fake.getStringArgsMutex.RUnlock() - return len(fake.getStringArgsArgsForCall) -} - -func (fake *ChaincodeStub) GetStringArgsCalls(stub func() []string) { - fake.getStringArgsMutex.Lock() - defer fake.getStringArgsMutex.Unlock() - fake.GetStringArgsStub = stub -} - -func (fake *ChaincodeStub) GetStringArgsReturns(result1 []string) { - fake.getStringArgsMutex.Lock() - defer fake.getStringArgsMutex.Unlock() - fake.GetStringArgsStub = nil - fake.getStringArgsReturns = struct { - result1 []string - }{result1} -} - -func (fake *ChaincodeStub) GetStringArgsReturnsOnCall(i int, result1 []string) { - fake.getStringArgsMutex.Lock() - defer fake.getStringArgsMutex.Unlock() - fake.GetStringArgsStub = nil - if fake.getStringArgsReturnsOnCall == nil { - fake.getStringArgsReturnsOnCall = make(map[int]struct { - result1 []string - }) - } - fake.getStringArgsReturnsOnCall[i] = struct { - result1 []string - }{result1} -} - -func (fake *ChaincodeStub) GetTransient() (map[string][]byte, error) { - fake.getTransientMutex.Lock() - ret, specificReturn := fake.getTransientReturnsOnCall[len(fake.getTransientArgsForCall)] - fake.getTransientArgsForCall = append(fake.getTransientArgsForCall, struct { - }{}) - stub := fake.GetTransientStub - fakeReturns := fake.getTransientReturns - fake.recordInvocation("GetTransient", []interface{}{}) - fake.getTransientMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetTransientCallCount() int { - fake.getTransientMutex.RLock() - defer fake.getTransientMutex.RUnlock() - return len(fake.getTransientArgsForCall) -} - -func (fake *ChaincodeStub) GetTransientCalls(stub func() (map[string][]byte, error)) { - fake.getTransientMutex.Lock() - defer fake.getTransientMutex.Unlock() - fake.GetTransientStub = stub -} - -func (fake *ChaincodeStub) GetTransientReturns(result1 map[string][]byte, result2 error) { - fake.getTransientMutex.Lock() - defer fake.getTransientMutex.Unlock() - fake.GetTransientStub = nil - fake.getTransientReturns = struct { - result1 map[string][]byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetTransientReturnsOnCall(i int, result1 map[string][]byte, result2 error) { - fake.getTransientMutex.Lock() - defer fake.getTransientMutex.Unlock() - fake.GetTransientStub = nil - if fake.getTransientReturnsOnCall == nil { - fake.getTransientReturnsOnCall = make(map[int]struct { - result1 map[string][]byte - result2 error - }) - } - fake.getTransientReturnsOnCall[i] = struct { - result1 map[string][]byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetTxID() string { - fake.getTxIDMutex.Lock() - ret, specificReturn := fake.getTxIDReturnsOnCall[len(fake.getTxIDArgsForCall)] - fake.getTxIDArgsForCall = append(fake.getTxIDArgsForCall, struct { - }{}) - stub := fake.GetTxIDStub - fakeReturns := fake.getTxIDReturns - fake.recordInvocation("GetTxID", []interface{}{}) - fake.getTxIDMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) GetTxIDCallCount() int { - fake.getTxIDMutex.RLock() - defer fake.getTxIDMutex.RUnlock() - return len(fake.getTxIDArgsForCall) -} - -func (fake *ChaincodeStub) GetTxIDCalls(stub func() string) { - fake.getTxIDMutex.Lock() - defer fake.getTxIDMutex.Unlock() - fake.GetTxIDStub = stub -} - -func (fake *ChaincodeStub) GetTxIDReturns(result1 string) { - fake.getTxIDMutex.Lock() - defer fake.getTxIDMutex.Unlock() - fake.GetTxIDStub = nil - fake.getTxIDReturns = struct { - result1 string - }{result1} -} - -func (fake *ChaincodeStub) GetTxIDReturnsOnCall(i int, result1 string) { - fake.getTxIDMutex.Lock() - defer fake.getTxIDMutex.Unlock() - fake.GetTxIDStub = nil - if fake.getTxIDReturnsOnCall == nil { - fake.getTxIDReturnsOnCall = make(map[int]struct { - result1 string - }) - } - fake.getTxIDReturnsOnCall[i] = struct { - result1 string - }{result1} -} - -func (fake *ChaincodeStub) GetTxTimestamp() (*timestamppb.Timestamp, error) { - fake.getTxTimestampMutex.Lock() - ret, specificReturn := fake.getTxTimestampReturnsOnCall[len(fake.getTxTimestampArgsForCall)] - fake.getTxTimestampArgsForCall = append(fake.getTxTimestampArgsForCall, struct { - }{}) - stub := fake.GetTxTimestampStub - fakeReturns := fake.getTxTimestampReturns - fake.recordInvocation("GetTxTimestamp", []interface{}{}) - fake.getTxTimestampMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetTxTimestampCallCount() int { - fake.getTxTimestampMutex.RLock() - defer fake.getTxTimestampMutex.RUnlock() - return len(fake.getTxTimestampArgsForCall) -} - -func (fake *ChaincodeStub) GetTxTimestampCalls(stub func() (*timestamppb.Timestamp, error)) { - fake.getTxTimestampMutex.Lock() - defer fake.getTxTimestampMutex.Unlock() - fake.GetTxTimestampStub = stub -} - -func (fake *ChaincodeStub) GetTxTimestampReturns(result1 *timestamppb.Timestamp, result2 error) { - fake.getTxTimestampMutex.Lock() - defer fake.getTxTimestampMutex.Unlock() - fake.GetTxTimestampStub = nil - fake.getTxTimestampReturns = struct { - result1 *timestamppb.Timestamp - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetTxTimestampReturnsOnCall(i int, result1 *timestamppb.Timestamp, result2 error) { - fake.getTxTimestampMutex.Lock() - defer fake.getTxTimestampMutex.Unlock() - fake.GetTxTimestampStub = nil - if fake.getTxTimestampReturnsOnCall == nil { - fake.getTxTimestampReturnsOnCall = make(map[int]struct { - result1 *timestamppb.Timestamp - result2 error - }) - } - fake.getTxTimestampReturnsOnCall[i] = struct { - result1 *timestamppb.Timestamp - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) InvokeChaincode(arg1 string, arg2 [][]byte, arg3 string) *peer.Response { - var arg2Copy [][]byte - if arg2 != nil { - arg2Copy = make([][]byte, len(arg2)) - copy(arg2Copy, arg2) - } - fake.invokeChaincodeMutex.Lock() - ret, specificReturn := fake.invokeChaincodeReturnsOnCall[len(fake.invokeChaincodeArgsForCall)] - fake.invokeChaincodeArgsForCall = append(fake.invokeChaincodeArgsForCall, struct { - arg1 string - arg2 [][]byte - arg3 string - }{arg1, arg2Copy, arg3}) - stub := fake.InvokeChaincodeStub - fakeReturns := fake.invokeChaincodeReturns - fake.recordInvocation("InvokeChaincode", []interface{}{arg1, arg2Copy, arg3}) - fake.invokeChaincodeMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) InvokeChaincodeCallCount() int { - fake.invokeChaincodeMutex.RLock() - defer fake.invokeChaincodeMutex.RUnlock() - return len(fake.invokeChaincodeArgsForCall) -} - -func (fake *ChaincodeStub) InvokeChaincodeCalls(stub func(string, [][]byte, string) *peer.Response) { - fake.invokeChaincodeMutex.Lock() - defer fake.invokeChaincodeMutex.Unlock() - fake.InvokeChaincodeStub = stub -} - -func (fake *ChaincodeStub) InvokeChaincodeArgsForCall(i int) (string, [][]byte, string) { - fake.invokeChaincodeMutex.RLock() - defer fake.invokeChaincodeMutex.RUnlock() - argsForCall := fake.invokeChaincodeArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *ChaincodeStub) InvokeChaincodeReturns(result1 *peer.Response) { - fake.invokeChaincodeMutex.Lock() - defer fake.invokeChaincodeMutex.Unlock() - fake.InvokeChaincodeStub = nil - fake.invokeChaincodeReturns = struct { - result1 *peer.Response - }{result1} -} - -func (fake *ChaincodeStub) InvokeChaincodeReturnsOnCall(i int, result1 *peer.Response) { - fake.invokeChaincodeMutex.Lock() - defer fake.invokeChaincodeMutex.Unlock() - fake.InvokeChaincodeStub = nil - if fake.invokeChaincodeReturnsOnCall == nil { - fake.invokeChaincodeReturnsOnCall = make(map[int]struct { - result1 *peer.Response - }) - } - fake.invokeChaincodeReturnsOnCall[i] = struct { - result1 *peer.Response - }{result1} -} - -func (fake *ChaincodeStub) PurgePrivateData(arg1 string, arg2 string) error { - fake.purgePrivateDataMutex.Lock() - ret, specificReturn := fake.purgePrivateDataReturnsOnCall[len(fake.purgePrivateDataArgsForCall)] - fake.purgePrivateDataArgsForCall = append(fake.purgePrivateDataArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.PurgePrivateDataStub - fakeReturns := fake.purgePrivateDataReturns - fake.recordInvocation("PurgePrivateData", []interface{}{arg1, arg2}) - fake.purgePrivateDataMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) PurgePrivateDataCallCount() int { - fake.purgePrivateDataMutex.RLock() - defer fake.purgePrivateDataMutex.RUnlock() - return len(fake.purgePrivateDataArgsForCall) -} - -func (fake *ChaincodeStub) PurgePrivateDataCalls(stub func(string, string) error) { - fake.purgePrivateDataMutex.Lock() - defer fake.purgePrivateDataMutex.Unlock() - fake.PurgePrivateDataStub = stub -} - -func (fake *ChaincodeStub) PurgePrivateDataArgsForCall(i int) (string, string) { - fake.purgePrivateDataMutex.RLock() - defer fake.purgePrivateDataMutex.RUnlock() - argsForCall := fake.purgePrivateDataArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) PurgePrivateDataReturns(result1 error) { - fake.purgePrivateDataMutex.Lock() - defer fake.purgePrivateDataMutex.Unlock() - fake.PurgePrivateDataStub = nil - fake.purgePrivateDataReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) PurgePrivateDataReturnsOnCall(i int, result1 error) { - fake.purgePrivateDataMutex.Lock() - defer fake.purgePrivateDataMutex.Unlock() - fake.PurgePrivateDataStub = nil - if fake.purgePrivateDataReturnsOnCall == nil { - fake.purgePrivateDataReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.purgePrivateDataReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) PutPrivateData(arg1 string, arg2 string, arg3 []byte) error { - var arg3Copy []byte - if arg3 != nil { - arg3Copy = make([]byte, len(arg3)) - copy(arg3Copy, arg3) - } - fake.putPrivateDataMutex.Lock() - ret, specificReturn := fake.putPrivateDataReturnsOnCall[len(fake.putPrivateDataArgsForCall)] - fake.putPrivateDataArgsForCall = append(fake.putPrivateDataArgsForCall, struct { - arg1 string - arg2 string - arg3 []byte - }{arg1, arg2, arg3Copy}) - stub := fake.PutPrivateDataStub - fakeReturns := fake.putPrivateDataReturns - fake.recordInvocation("PutPrivateData", []interface{}{arg1, arg2, arg3Copy}) - fake.putPrivateDataMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) PutPrivateDataCallCount() int { - fake.putPrivateDataMutex.RLock() - defer fake.putPrivateDataMutex.RUnlock() - return len(fake.putPrivateDataArgsForCall) -} - -func (fake *ChaincodeStub) PutPrivateDataCalls(stub func(string, string, []byte) error) { - fake.putPrivateDataMutex.Lock() - defer fake.putPrivateDataMutex.Unlock() - fake.PutPrivateDataStub = stub -} - -func (fake *ChaincodeStub) PutPrivateDataArgsForCall(i int) (string, string, []byte) { - fake.putPrivateDataMutex.RLock() - defer fake.putPrivateDataMutex.RUnlock() - argsForCall := fake.putPrivateDataArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *ChaincodeStub) PutPrivateDataReturns(result1 error) { - fake.putPrivateDataMutex.Lock() - defer fake.putPrivateDataMutex.Unlock() - fake.PutPrivateDataStub = nil - fake.putPrivateDataReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) PutPrivateDataReturnsOnCall(i int, result1 error) { - fake.putPrivateDataMutex.Lock() - defer fake.putPrivateDataMutex.Unlock() - fake.PutPrivateDataStub = nil - if fake.putPrivateDataReturnsOnCall == nil { - fake.putPrivateDataReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.putPrivateDataReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) PutState(arg1 string, arg2 []byte) error { - var arg2Copy []byte - if arg2 != nil { - arg2Copy = make([]byte, len(arg2)) - copy(arg2Copy, arg2) - } - fake.putStateMutex.Lock() - ret, specificReturn := fake.putStateReturnsOnCall[len(fake.putStateArgsForCall)] - fake.putStateArgsForCall = append(fake.putStateArgsForCall, struct { - arg1 string - arg2 []byte - }{arg1, arg2Copy}) - stub := fake.PutStateStub - fakeReturns := fake.putStateReturns - fake.recordInvocation("PutState", []interface{}{arg1, arg2Copy}) - fake.putStateMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) PutStateCallCount() int { - fake.putStateMutex.RLock() - defer fake.putStateMutex.RUnlock() - return len(fake.putStateArgsForCall) -} - -func (fake *ChaincodeStub) PutStateCalls(stub func(string, []byte) error) { - fake.putStateMutex.Lock() - defer fake.putStateMutex.Unlock() - fake.PutStateStub = stub -} - -func (fake *ChaincodeStub) PutStateArgsForCall(i int) (string, []byte) { - fake.putStateMutex.RLock() - defer fake.putStateMutex.RUnlock() - argsForCall := fake.putStateArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) PutStateReturns(result1 error) { - fake.putStateMutex.Lock() - defer fake.putStateMutex.Unlock() - fake.PutStateStub = nil - fake.putStateReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) PutStateReturnsOnCall(i int, result1 error) { - fake.putStateMutex.Lock() - defer fake.putStateMutex.Unlock() - fake.PutStateStub = nil - if fake.putStateReturnsOnCall == nil { - fake.putStateReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.putStateReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SetEvent(arg1 string, arg2 []byte) error { - var arg2Copy []byte - if arg2 != nil { - arg2Copy = make([]byte, len(arg2)) - copy(arg2Copy, arg2) - } - fake.setEventMutex.Lock() - ret, specificReturn := fake.setEventReturnsOnCall[len(fake.setEventArgsForCall)] - fake.setEventArgsForCall = append(fake.setEventArgsForCall, struct { - arg1 string - arg2 []byte - }{arg1, arg2Copy}) - stub := fake.SetEventStub - fakeReturns := fake.setEventReturns - fake.recordInvocation("SetEvent", []interface{}{arg1, arg2Copy}) - fake.setEventMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) SetEventCallCount() int { - fake.setEventMutex.RLock() - defer fake.setEventMutex.RUnlock() - return len(fake.setEventArgsForCall) -} - -func (fake *ChaincodeStub) SetEventCalls(stub func(string, []byte) error) { - fake.setEventMutex.Lock() - defer fake.setEventMutex.Unlock() - fake.SetEventStub = stub -} - -func (fake *ChaincodeStub) SetEventArgsForCall(i int) (string, []byte) { - fake.setEventMutex.RLock() - defer fake.setEventMutex.RUnlock() - argsForCall := fake.setEventArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) SetEventReturns(result1 error) { - fake.setEventMutex.Lock() - defer fake.setEventMutex.Unlock() - fake.SetEventStub = nil - fake.setEventReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SetEventReturnsOnCall(i int, result1 error) { - fake.setEventMutex.Lock() - defer fake.setEventMutex.Unlock() - fake.SetEventStub = nil - if fake.setEventReturnsOnCall == nil { - fake.setEventReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.setEventReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SetPrivateDataValidationParameter(arg1 string, arg2 string, arg3 []byte) error { - var arg3Copy []byte - if arg3 != nil { - arg3Copy = make([]byte, len(arg3)) - copy(arg3Copy, arg3) - } - fake.setPrivateDataValidationParameterMutex.Lock() - ret, specificReturn := fake.setPrivateDataValidationParameterReturnsOnCall[len(fake.setPrivateDataValidationParameterArgsForCall)] - fake.setPrivateDataValidationParameterArgsForCall = append(fake.setPrivateDataValidationParameterArgsForCall, struct { - arg1 string - arg2 string - arg3 []byte - }{arg1, arg2, arg3Copy}) - stub := fake.SetPrivateDataValidationParameterStub - fakeReturns := fake.setPrivateDataValidationParameterReturns - fake.recordInvocation("SetPrivateDataValidationParameter", []interface{}{arg1, arg2, arg3Copy}) - fake.setPrivateDataValidationParameterMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) SetPrivateDataValidationParameterCallCount() int { - fake.setPrivateDataValidationParameterMutex.RLock() - defer fake.setPrivateDataValidationParameterMutex.RUnlock() - return len(fake.setPrivateDataValidationParameterArgsForCall) -} - -func (fake *ChaincodeStub) SetPrivateDataValidationParameterCalls(stub func(string, string, []byte) error) { - fake.setPrivateDataValidationParameterMutex.Lock() - defer fake.setPrivateDataValidationParameterMutex.Unlock() - fake.SetPrivateDataValidationParameterStub = stub -} - -func (fake *ChaincodeStub) SetPrivateDataValidationParameterArgsForCall(i int) (string, string, []byte) { - fake.setPrivateDataValidationParameterMutex.RLock() - defer fake.setPrivateDataValidationParameterMutex.RUnlock() - argsForCall := fake.setPrivateDataValidationParameterArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *ChaincodeStub) SetPrivateDataValidationParameterReturns(result1 error) { - fake.setPrivateDataValidationParameterMutex.Lock() - defer fake.setPrivateDataValidationParameterMutex.Unlock() - fake.SetPrivateDataValidationParameterStub = nil - fake.setPrivateDataValidationParameterReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SetPrivateDataValidationParameterReturnsOnCall(i int, result1 error) { - fake.setPrivateDataValidationParameterMutex.Lock() - defer fake.setPrivateDataValidationParameterMutex.Unlock() - fake.SetPrivateDataValidationParameterStub = nil - if fake.setPrivateDataValidationParameterReturnsOnCall == nil { - fake.setPrivateDataValidationParameterReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.setPrivateDataValidationParameterReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SetStateValidationParameter(arg1 string, arg2 []byte) error { - var arg2Copy []byte - if arg2 != nil { - arg2Copy = make([]byte, len(arg2)) - copy(arg2Copy, arg2) - } - fake.setStateValidationParameterMutex.Lock() - ret, specificReturn := fake.setStateValidationParameterReturnsOnCall[len(fake.setStateValidationParameterArgsForCall)] - fake.setStateValidationParameterArgsForCall = append(fake.setStateValidationParameterArgsForCall, struct { - arg1 string - arg2 []byte - }{arg1, arg2Copy}) - stub := fake.SetStateValidationParameterStub - fakeReturns := fake.setStateValidationParameterReturns - fake.recordInvocation("SetStateValidationParameter", []interface{}{arg1, arg2Copy}) - fake.setStateValidationParameterMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) SetStateValidationParameterCallCount() int { - fake.setStateValidationParameterMutex.RLock() - defer fake.setStateValidationParameterMutex.RUnlock() - return len(fake.setStateValidationParameterArgsForCall) -} - -func (fake *ChaincodeStub) SetStateValidationParameterCalls(stub func(string, []byte) error) { - fake.setStateValidationParameterMutex.Lock() - defer fake.setStateValidationParameterMutex.Unlock() - fake.SetStateValidationParameterStub = stub -} - -func (fake *ChaincodeStub) SetStateValidationParameterArgsForCall(i int) (string, []byte) { - fake.setStateValidationParameterMutex.RLock() - defer fake.setStateValidationParameterMutex.RUnlock() - argsForCall := fake.setStateValidationParameterArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) SetStateValidationParameterReturns(result1 error) { - fake.setStateValidationParameterMutex.Lock() - defer fake.setStateValidationParameterMutex.Unlock() - fake.SetStateValidationParameterStub = nil - fake.setStateValidationParameterReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SetStateValidationParameterReturnsOnCall(i int, result1 error) { - fake.setStateValidationParameterMutex.Lock() - defer fake.setStateValidationParameterMutex.Unlock() - fake.SetStateValidationParameterStub = nil - if fake.setStateValidationParameterReturnsOnCall == nil { - fake.setStateValidationParameterReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.setStateValidationParameterReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SplitCompositeKey(arg1 string) (string, []string, error) { - fake.splitCompositeKeyMutex.Lock() - ret, specificReturn := fake.splitCompositeKeyReturnsOnCall[len(fake.splitCompositeKeyArgsForCall)] - fake.splitCompositeKeyArgsForCall = append(fake.splitCompositeKeyArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.SplitCompositeKeyStub - fakeReturns := fake.splitCompositeKeyReturns - fake.recordInvocation("SplitCompositeKey", []interface{}{arg1}) - fake.splitCompositeKeyMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *ChaincodeStub) SplitCompositeKeyCallCount() int { - fake.splitCompositeKeyMutex.RLock() - defer fake.splitCompositeKeyMutex.RUnlock() - return len(fake.splitCompositeKeyArgsForCall) -} - -func (fake *ChaincodeStub) SplitCompositeKeyCalls(stub func(string) (string, []string, error)) { - fake.splitCompositeKeyMutex.Lock() - defer fake.splitCompositeKeyMutex.Unlock() - fake.SplitCompositeKeyStub = stub -} - -func (fake *ChaincodeStub) SplitCompositeKeyArgsForCall(i int) string { - fake.splitCompositeKeyMutex.RLock() - defer fake.splitCompositeKeyMutex.RUnlock() - argsForCall := fake.splitCompositeKeyArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ChaincodeStub) SplitCompositeKeyReturns(result1 string, result2 []string, result3 error) { - fake.splitCompositeKeyMutex.Lock() - defer fake.splitCompositeKeyMutex.Unlock() - fake.SplitCompositeKeyStub = nil - fake.splitCompositeKeyReturns = struct { - result1 string - result2 []string - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) SplitCompositeKeyReturnsOnCall(i int, result1 string, result2 []string, result3 error) { - fake.splitCompositeKeyMutex.Lock() - defer fake.splitCompositeKeyMutex.Unlock() - fake.SplitCompositeKeyStub = nil - if fake.splitCompositeKeyReturnsOnCall == nil { - fake.splitCompositeKeyReturnsOnCall = make(map[int]struct { - result1 string - result2 []string - result3 error - }) - } - fake.splitCompositeKeyReturnsOnCall[i] = struct { - result1 string - result2 []string - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.createCompositeKeyMutex.RLock() - defer fake.createCompositeKeyMutex.RUnlock() - fake.delPrivateDataMutex.RLock() - defer fake.delPrivateDataMutex.RUnlock() - fake.delStateMutex.RLock() - defer fake.delStateMutex.RUnlock() - fake.getArgsMutex.RLock() - defer fake.getArgsMutex.RUnlock() - fake.getArgsSliceMutex.RLock() - defer fake.getArgsSliceMutex.RUnlock() - fake.getBindingMutex.RLock() - defer fake.getBindingMutex.RUnlock() - fake.getChannelIDMutex.RLock() - defer fake.getChannelIDMutex.RUnlock() - fake.getCreatorMutex.RLock() - defer fake.getCreatorMutex.RUnlock() - fake.getDecorationsMutex.RLock() - defer fake.getDecorationsMutex.RUnlock() - fake.getFunctionAndParametersMutex.RLock() - defer fake.getFunctionAndParametersMutex.RUnlock() - fake.getHistoryForKeyMutex.RLock() - defer fake.getHistoryForKeyMutex.RUnlock() - fake.getPrivateDataMutex.RLock() - defer fake.getPrivateDataMutex.RUnlock() - fake.getPrivateDataByPartialCompositeKeyMutex.RLock() - defer fake.getPrivateDataByPartialCompositeKeyMutex.RUnlock() - fake.getPrivateDataByRangeMutex.RLock() - defer fake.getPrivateDataByRangeMutex.RUnlock() - fake.getPrivateDataHashMutex.RLock() - defer fake.getPrivateDataHashMutex.RUnlock() - fake.getPrivateDataQueryResultMutex.RLock() - defer fake.getPrivateDataQueryResultMutex.RUnlock() - fake.getPrivateDataValidationParameterMutex.RLock() - defer fake.getPrivateDataValidationParameterMutex.RUnlock() - fake.getQueryResultMutex.RLock() - defer fake.getQueryResultMutex.RUnlock() - fake.getQueryResultWithPaginationMutex.RLock() - defer fake.getQueryResultWithPaginationMutex.RUnlock() - fake.getSignedProposalMutex.RLock() - defer fake.getSignedProposalMutex.RUnlock() - fake.getStateMutex.RLock() - defer fake.getStateMutex.RUnlock() - fake.getStateByPartialCompositeKeyMutex.RLock() - defer fake.getStateByPartialCompositeKeyMutex.RUnlock() - fake.getStateByPartialCompositeKeyWithPaginationMutex.RLock() - defer fake.getStateByPartialCompositeKeyWithPaginationMutex.RUnlock() - fake.getStateByRangeMutex.RLock() - defer fake.getStateByRangeMutex.RUnlock() - fake.getStateByRangeWithPaginationMutex.RLock() - defer fake.getStateByRangeWithPaginationMutex.RUnlock() - fake.getStateValidationParameterMutex.RLock() - defer fake.getStateValidationParameterMutex.RUnlock() - fake.getStringArgsMutex.RLock() - defer fake.getStringArgsMutex.RUnlock() - fake.getTransientMutex.RLock() - defer fake.getTransientMutex.RUnlock() - fake.getTxIDMutex.RLock() - defer fake.getTxIDMutex.RUnlock() - fake.getTxTimestampMutex.RLock() - defer fake.getTxTimestampMutex.RUnlock() - fake.invokeChaincodeMutex.RLock() - defer fake.invokeChaincodeMutex.RUnlock() - fake.purgePrivateDataMutex.RLock() - defer fake.purgePrivateDataMutex.RUnlock() - fake.putPrivateDataMutex.RLock() - defer fake.putPrivateDataMutex.RUnlock() - fake.putStateMutex.RLock() - defer fake.putStateMutex.RUnlock() - fake.setEventMutex.RLock() - defer fake.setEventMutex.RUnlock() - fake.setPrivateDataValidationParameterMutex.RLock() - defer fake.setPrivateDataValidationParameterMutex.RUnlock() - fake.setStateValidationParameterMutex.RLock() - defer fake.setStateValidationParameterMutex.RUnlock() - fake.splitCompositeKeyMutex.RLock() - defer fake.splitCompositeKeyMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *ChaincodeStub) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} diff --git a/asset-transfer-basic/chaincode-go/chaincode/mocks/statequeryiterator.go b/asset-transfer-basic/chaincode-go/chaincode/mocks/statequeryiterator.go deleted file mode 100644 index 76cdcaa1..00000000 --- a/asset-transfer-basic/chaincode-go/chaincode/mocks/statequeryiterator.go +++ /dev/null @@ -1,235 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package mocks - -import ( - "sync" - - "github.com/hyperledger/fabric-protos-go-apiv2/ledger/queryresult" -) - -type StateQueryIterator struct { - CloseStub func() error - closeMutex sync.RWMutex - closeArgsForCall []struct { - } - closeReturns struct { - result1 error - } - closeReturnsOnCall map[int]struct { - result1 error - } - HasNextStub func() bool - hasNextMutex sync.RWMutex - hasNextArgsForCall []struct { - } - hasNextReturns struct { - result1 bool - } - hasNextReturnsOnCall map[int]struct { - result1 bool - } - NextStub func() (*queryresult.KV, error) - nextMutex sync.RWMutex - nextArgsForCall []struct { - } - nextReturns struct { - result1 *queryresult.KV - result2 error - } - nextReturnsOnCall map[int]struct { - result1 *queryresult.KV - result2 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *StateQueryIterator) Close() error { - fake.closeMutex.Lock() - ret, specificReturn := fake.closeReturnsOnCall[len(fake.closeArgsForCall)] - fake.closeArgsForCall = append(fake.closeArgsForCall, struct { - }{}) - stub := fake.CloseStub - fakeReturns := fake.closeReturns - fake.recordInvocation("Close", []interface{}{}) - fake.closeMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *StateQueryIterator) CloseCallCount() int { - fake.closeMutex.RLock() - defer fake.closeMutex.RUnlock() - return len(fake.closeArgsForCall) -} - -func (fake *StateQueryIterator) CloseCalls(stub func() error) { - fake.closeMutex.Lock() - defer fake.closeMutex.Unlock() - fake.CloseStub = stub -} - -func (fake *StateQueryIterator) CloseReturns(result1 error) { - fake.closeMutex.Lock() - defer fake.closeMutex.Unlock() - fake.CloseStub = nil - fake.closeReturns = struct { - result1 error - }{result1} -} - -func (fake *StateQueryIterator) CloseReturnsOnCall(i int, result1 error) { - fake.closeMutex.Lock() - defer fake.closeMutex.Unlock() - fake.CloseStub = nil - if fake.closeReturnsOnCall == nil { - fake.closeReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.closeReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *StateQueryIterator) HasNext() bool { - fake.hasNextMutex.Lock() - ret, specificReturn := fake.hasNextReturnsOnCall[len(fake.hasNextArgsForCall)] - fake.hasNextArgsForCall = append(fake.hasNextArgsForCall, struct { - }{}) - stub := fake.HasNextStub - fakeReturns := fake.hasNextReturns - fake.recordInvocation("HasNext", []interface{}{}) - fake.hasNextMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *StateQueryIterator) HasNextCallCount() int { - fake.hasNextMutex.RLock() - defer fake.hasNextMutex.RUnlock() - return len(fake.hasNextArgsForCall) -} - -func (fake *StateQueryIterator) HasNextCalls(stub func() bool) { - fake.hasNextMutex.Lock() - defer fake.hasNextMutex.Unlock() - fake.HasNextStub = stub -} - -func (fake *StateQueryIterator) HasNextReturns(result1 bool) { - fake.hasNextMutex.Lock() - defer fake.hasNextMutex.Unlock() - fake.HasNextStub = nil - fake.hasNextReturns = struct { - result1 bool - }{result1} -} - -func (fake *StateQueryIterator) HasNextReturnsOnCall(i int, result1 bool) { - fake.hasNextMutex.Lock() - defer fake.hasNextMutex.Unlock() - fake.HasNextStub = nil - if fake.hasNextReturnsOnCall == nil { - fake.hasNextReturnsOnCall = make(map[int]struct { - result1 bool - }) - } - fake.hasNextReturnsOnCall[i] = struct { - result1 bool - }{result1} -} - -func (fake *StateQueryIterator) Next() (*queryresult.KV, error) { - fake.nextMutex.Lock() - ret, specificReturn := fake.nextReturnsOnCall[len(fake.nextArgsForCall)] - fake.nextArgsForCall = append(fake.nextArgsForCall, struct { - }{}) - stub := fake.NextStub - fakeReturns := fake.nextReturns - fake.recordInvocation("Next", []interface{}{}) - fake.nextMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *StateQueryIterator) NextCallCount() int { - fake.nextMutex.RLock() - defer fake.nextMutex.RUnlock() - return len(fake.nextArgsForCall) -} - -func (fake *StateQueryIterator) NextCalls(stub func() (*queryresult.KV, error)) { - fake.nextMutex.Lock() - defer fake.nextMutex.Unlock() - fake.NextStub = stub -} - -func (fake *StateQueryIterator) NextReturns(result1 *queryresult.KV, result2 error) { - fake.nextMutex.Lock() - defer fake.nextMutex.Unlock() - fake.NextStub = nil - fake.nextReturns = struct { - result1 *queryresult.KV - result2 error - }{result1, result2} -} - -func (fake *StateQueryIterator) NextReturnsOnCall(i int, result1 *queryresult.KV, result2 error) { - fake.nextMutex.Lock() - defer fake.nextMutex.Unlock() - fake.NextStub = nil - if fake.nextReturnsOnCall == nil { - fake.nextReturnsOnCall = make(map[int]struct { - result1 *queryresult.KV - result2 error - }) - } - fake.nextReturnsOnCall[i] = struct { - result1 *queryresult.KV - result2 error - }{result1, result2} -} - -func (fake *StateQueryIterator) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.closeMutex.RLock() - defer fake.closeMutex.RUnlock() - fake.hasNextMutex.RLock() - defer fake.hasNextMutex.RUnlock() - fake.nextMutex.RLock() - defer fake.nextMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *StateQueryIterator) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} diff --git a/asset-transfer-basic/chaincode-go/chaincode/mocks/transaction.go b/asset-transfer-basic/chaincode-go/chaincode/mocks/transaction.go deleted file mode 100644 index 5e98d069..00000000 --- a/asset-transfer-basic/chaincode-go/chaincode/mocks/transaction.go +++ /dev/null @@ -1,166 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package mocks - -import ( - "sync" - - "github.com/hyperledger/fabric-chaincode-go/v2/pkg/cid" - "github.com/hyperledger/fabric-chaincode-go/v2/shim" -) - -type TransactionContext struct { - GetClientIdentityStub func() cid.ClientIdentity - getClientIdentityMutex sync.RWMutex - getClientIdentityArgsForCall []struct { - } - getClientIdentityReturns struct { - result1 cid.ClientIdentity - } - getClientIdentityReturnsOnCall map[int]struct { - result1 cid.ClientIdentity - } - GetStubStub func() shim.ChaincodeStubInterface - getStubMutex sync.RWMutex - getStubArgsForCall []struct { - } - getStubReturns struct { - result1 shim.ChaincodeStubInterface - } - getStubReturnsOnCall map[int]struct { - result1 shim.ChaincodeStubInterface - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *TransactionContext) GetClientIdentity() cid.ClientIdentity { - fake.getClientIdentityMutex.Lock() - ret, specificReturn := fake.getClientIdentityReturnsOnCall[len(fake.getClientIdentityArgsForCall)] - fake.getClientIdentityArgsForCall = append(fake.getClientIdentityArgsForCall, struct { - }{}) - stub := fake.GetClientIdentityStub - fakeReturns := fake.getClientIdentityReturns - fake.recordInvocation("GetClientIdentity", []interface{}{}) - fake.getClientIdentityMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *TransactionContext) GetClientIdentityCallCount() int { - fake.getClientIdentityMutex.RLock() - defer fake.getClientIdentityMutex.RUnlock() - return len(fake.getClientIdentityArgsForCall) -} - -func (fake *TransactionContext) GetClientIdentityCalls(stub func() cid.ClientIdentity) { - fake.getClientIdentityMutex.Lock() - defer fake.getClientIdentityMutex.Unlock() - fake.GetClientIdentityStub = stub -} - -func (fake *TransactionContext) GetClientIdentityReturns(result1 cid.ClientIdentity) { - fake.getClientIdentityMutex.Lock() - defer fake.getClientIdentityMutex.Unlock() - fake.GetClientIdentityStub = nil - fake.getClientIdentityReturns = struct { - result1 cid.ClientIdentity - }{result1} -} - -func (fake *TransactionContext) GetClientIdentityReturnsOnCall(i int, result1 cid.ClientIdentity) { - fake.getClientIdentityMutex.Lock() - defer fake.getClientIdentityMutex.Unlock() - fake.GetClientIdentityStub = nil - if fake.getClientIdentityReturnsOnCall == nil { - fake.getClientIdentityReturnsOnCall = make(map[int]struct { - result1 cid.ClientIdentity - }) - } - fake.getClientIdentityReturnsOnCall[i] = struct { - result1 cid.ClientIdentity - }{result1} -} - -func (fake *TransactionContext) GetStub() shim.ChaincodeStubInterface { - fake.getStubMutex.Lock() - ret, specificReturn := fake.getStubReturnsOnCall[len(fake.getStubArgsForCall)] - fake.getStubArgsForCall = append(fake.getStubArgsForCall, struct { - }{}) - stub := fake.GetStubStub - fakeReturns := fake.getStubReturns - fake.recordInvocation("GetStub", []interface{}{}) - fake.getStubMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *TransactionContext) GetStubCallCount() int { - fake.getStubMutex.RLock() - defer fake.getStubMutex.RUnlock() - return len(fake.getStubArgsForCall) -} - -func (fake *TransactionContext) GetStubCalls(stub func() shim.ChaincodeStubInterface) { - fake.getStubMutex.Lock() - defer fake.getStubMutex.Unlock() - fake.GetStubStub = stub -} - -func (fake *TransactionContext) GetStubReturns(result1 shim.ChaincodeStubInterface) { - fake.getStubMutex.Lock() - defer fake.getStubMutex.Unlock() - fake.GetStubStub = nil - fake.getStubReturns = struct { - result1 shim.ChaincodeStubInterface - }{result1} -} - -func (fake *TransactionContext) GetStubReturnsOnCall(i int, result1 shim.ChaincodeStubInterface) { - fake.getStubMutex.Lock() - defer fake.getStubMutex.Unlock() - fake.GetStubStub = nil - if fake.getStubReturnsOnCall == nil { - fake.getStubReturnsOnCall = make(map[int]struct { - result1 shim.ChaincodeStubInterface - }) - } - fake.getStubReturnsOnCall[i] = struct { - result1 shim.ChaincodeStubInterface - }{result1} -} - -func (fake *TransactionContext) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.getClientIdentityMutex.RLock() - defer fake.getClientIdentityMutex.RUnlock() - fake.getStubMutex.RLock() - defer fake.getStubMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *TransactionContext) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} diff --git a/asset-transfer-basic/chaincode-go/chaincode/smartcontract.go b/asset-transfer-basic/chaincode-go/chaincode/smartcontract.go deleted file mode 100644 index 567067e0..00000000 --- a/asset-transfer-basic/chaincode-go/chaincode/smartcontract.go +++ /dev/null @@ -1,194 +0,0 @@ -package chaincode - -import ( - "encoding/json" - "fmt" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -// SmartContract provides functions for managing an Asset -type SmartContract struct { - contractapi.Contract -} - -// Asset describes basic details of what makes up a simple asset -// Insert struct field in alphabetic order => to achieve determinism across languages -// golang keeps the order when marshal to json but doesn't order automatically -type Asset struct { - AppraisedValue int `json:"AppraisedValue"` - Color string `json:"Color"` - ID string `json:"ID"` - Owner string `json:"Owner"` - Size int `json:"Size"` -} - -// InitLedger adds a base set of assets to the ledger -func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error { - assets := []Asset{ - {ID: "asset1", Color: "blue", Size: 5, Owner: "Tomoko", AppraisedValue: 300}, - {ID: "asset2", Color: "red", Size: 5, Owner: "Brad", AppraisedValue: 400}, - {ID: "asset3", Color: "green", Size: 10, Owner: "Jin Soo", AppraisedValue: 500}, - {ID: "asset4", Color: "yellow", Size: 10, Owner: "Max", AppraisedValue: 600}, - {ID: "asset5", Color: "black", Size: 15, Owner: "Adriana", AppraisedValue: 700}, - {ID: "asset6", Color: "white", Size: 15, Owner: "Michel", AppraisedValue: 800}, - } - - for _, asset := range assets { - assetJSON, err := json.Marshal(asset) - if err != nil { - return err - } - - err = ctx.GetStub().PutState(asset.ID, assetJSON) - if err != nil { - return fmt.Errorf("failed to put to world state. %v", err) - } - } - - return nil -} - -// CreateAsset issues a new asset to the world state with given details. -func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue int) error { - exists, err := s.AssetExists(ctx, id) - if err != nil { - return err - } - if exists { - return fmt.Errorf("the asset %s already exists", id) - } - - asset := Asset{ - ID: id, - Color: color, - Size: size, - Owner: owner, - AppraisedValue: appraisedValue, - } - assetJSON, err := json.Marshal(asset) - if err != nil { - return err - } - - return ctx.GetStub().PutState(id, assetJSON) -} - -// ReadAsset returns the asset stored in the world state with given id. -func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, id string) (*Asset, error) { - assetJSON, err := ctx.GetStub().GetState(id) - if err != nil { - return nil, fmt.Errorf("failed to read from world state: %v", err) - } - if assetJSON == nil { - return nil, fmt.Errorf("the asset %s does not exist", id) - } - - var asset Asset - err = json.Unmarshal(assetJSON, &asset) - if err != nil { - return nil, err - } - - return &asset, nil -} - -// UpdateAsset updates an existing asset in the world state with provided parameters. -func (s *SmartContract) UpdateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue int) error { - exists, err := s.AssetExists(ctx, id) - if err != nil { - return err - } - if !exists { - return fmt.Errorf("the asset %s does not exist", id) - } - - // overwriting original asset with new asset - asset := Asset{ - ID: id, - Color: color, - Size: size, - Owner: owner, - AppraisedValue: appraisedValue, - } - assetJSON, err := json.Marshal(asset) - if err != nil { - return err - } - - return ctx.GetStub().PutState(id, assetJSON) -} - -// DeleteAsset deletes an given asset from the world state. -func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface, id string) error { - exists, err := s.AssetExists(ctx, id) - if err != nil { - return err - } - if !exists { - return fmt.Errorf("the asset %s does not exist", id) - } - - return ctx.GetStub().DelState(id) -} - -// AssetExists returns true when asset with given ID exists in world state -func (s *SmartContract) AssetExists(ctx contractapi.TransactionContextInterface, id string) (bool, error) { - assetJSON, err := ctx.GetStub().GetState(id) - if err != nil { - return false, fmt.Errorf("failed to read from world state: %v", err) - } - - return assetJSON != nil, nil -} - -// TransferAsset updates the owner field of asset with given id in world state, and returns the old owner. -func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface, id string, newOwner string) (string, error) { - asset, err := s.ReadAsset(ctx, id) - if err != nil { - return "", err - } - - oldOwner := asset.Owner - asset.Owner = newOwner - - assetJSON, err := json.Marshal(asset) - if err != nil { - return "", err - } - - err = ctx.GetStub().PutState(id, assetJSON) - if err != nil { - return "", err - } - - return oldOwner, nil -} - -// GetAllAssets returns all assets found in world state -func (s *SmartContract) GetAllAssets(ctx contractapi.TransactionContextInterface) ([]*Asset, error) { - // range query with empty string for startKey and endKey does an - // open-ended query of all assets in the chaincode namespace. - resultsIterator, err := ctx.GetStub().GetStateByRange("", "") - if err != nil { - return nil, err - } - defer resultsIterator.Close() - - var assets []*Asset - for resultsIterator.HasNext() { - queryResponse, err := resultsIterator.Next() - if err != nil { - return nil, err - } - - var asset Asset - err = json.Unmarshal(queryResponse.Value, &asset) - if err != nil { - return nil, err - } - assets = append(assets, &asset) - } - - return assets, nil -} diff --git a/asset-transfer-basic/chaincode-go/chaincode/smartcontract_test.go b/asset-transfer-basic/chaincode-go/chaincode/smartcontract_test.go deleted file mode 100644 index 801611f4..00000000 --- a/asset-transfer-basic/chaincode-go/chaincode/smartcontract_test.go +++ /dev/null @@ -1,184 +0,0 @@ -package chaincode_test - -import ( - "encoding/json" - "fmt" - "testing" - - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" - "github.com/hyperledger/fabric-protos-go-apiv2/ledger/queryresult" - "github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-go/chaincode" - "github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-go/chaincode/mocks" - "github.com/stretchr/testify/require" -) - -//go:generate counterfeiter -o mocks/transaction.go -fake-name TransactionContext . transactionContext -type transactionContext interface { - contractapi.TransactionContextInterface -} - -//go:generate counterfeiter -o mocks/chaincodestub.go -fake-name ChaincodeStub . chaincodeStub -type chaincodeStub interface { - shim.ChaincodeStubInterface -} - -//go:generate counterfeiter -o mocks/statequeryiterator.go -fake-name StateQueryIterator . stateQueryIterator -type stateQueryIterator interface { - shim.StateQueryIteratorInterface -} - -func TestInitLedger(t *testing.T) { - chaincodeStub := &mocks.ChaincodeStub{} - transactionContext := &mocks.TransactionContext{} - transactionContext.GetStubReturns(chaincodeStub) - - assetTransfer := chaincode.SmartContract{} - err := assetTransfer.InitLedger(transactionContext) - require.NoError(t, err) - - chaincodeStub.PutStateReturns(fmt.Errorf("failed inserting key")) - err = assetTransfer.InitLedger(transactionContext) - require.EqualError(t, err, "failed to put to world state. failed inserting key") -} - -func TestCreateAsset(t *testing.T) { - chaincodeStub := &mocks.ChaincodeStub{} - transactionContext := &mocks.TransactionContext{} - transactionContext.GetStubReturns(chaincodeStub) - - assetTransfer := chaincode.SmartContract{} - err := assetTransfer.CreateAsset(transactionContext, "", "", 0, "", 0) - require.NoError(t, err) - - chaincodeStub.GetStateReturns([]byte{}, nil) - err = assetTransfer.CreateAsset(transactionContext, "asset1", "", 0, "", 0) - require.EqualError(t, err, "the asset asset1 already exists") - - chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve asset")) - err = assetTransfer.CreateAsset(transactionContext, "asset1", "", 0, "", 0) - require.EqualError(t, err, "failed to read from world state: unable to retrieve asset") -} - -func TestReadAsset(t *testing.T) { - chaincodeStub := &mocks.ChaincodeStub{} - transactionContext := &mocks.TransactionContext{} - transactionContext.GetStubReturns(chaincodeStub) - - expectedAsset := &chaincode.Asset{ID: "asset1"} - bytes, err := json.Marshal(expectedAsset) - require.NoError(t, err) - - chaincodeStub.GetStateReturns(bytes, nil) - assetTransfer := chaincode.SmartContract{} - asset, err := assetTransfer.ReadAsset(transactionContext, "") - require.NoError(t, err) - require.Equal(t, expectedAsset, asset) - - chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve asset")) - _, err = assetTransfer.ReadAsset(transactionContext, "") - require.EqualError(t, err, "failed to read from world state: unable to retrieve asset") - - chaincodeStub.GetStateReturns(nil, nil) - asset, err = assetTransfer.ReadAsset(transactionContext, "asset1") - require.EqualError(t, err, "the asset asset1 does not exist") - require.Nil(t, asset) -} - -func TestUpdateAsset(t *testing.T) { - chaincodeStub := &mocks.ChaincodeStub{} - transactionContext := &mocks.TransactionContext{} - transactionContext.GetStubReturns(chaincodeStub) - - expectedAsset := &chaincode.Asset{ID: "asset1"} - bytes, err := json.Marshal(expectedAsset) - require.NoError(t, err) - - chaincodeStub.GetStateReturns(bytes, nil) - assetTransfer := chaincode.SmartContract{} - err = assetTransfer.UpdateAsset(transactionContext, "", "", 0, "", 0) - require.NoError(t, err) - - chaincodeStub.GetStateReturns(nil, nil) - err = assetTransfer.UpdateAsset(transactionContext, "asset1", "", 0, "", 0) - require.EqualError(t, err, "the asset asset1 does not exist") - - chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve asset")) - err = assetTransfer.UpdateAsset(transactionContext, "asset1", "", 0, "", 0) - require.EqualError(t, err, "failed to read from world state: unable to retrieve asset") -} - -func TestDeleteAsset(t *testing.T) { - chaincodeStub := &mocks.ChaincodeStub{} - transactionContext := &mocks.TransactionContext{} - transactionContext.GetStubReturns(chaincodeStub) - - asset := &chaincode.Asset{ID: "asset1"} - bytes, err := json.Marshal(asset) - require.NoError(t, err) - - chaincodeStub.GetStateReturns(bytes, nil) - chaincodeStub.DelStateReturns(nil) - assetTransfer := chaincode.SmartContract{} - err = assetTransfer.DeleteAsset(transactionContext, "") - require.NoError(t, err) - - chaincodeStub.GetStateReturns(nil, nil) - err = assetTransfer.DeleteAsset(transactionContext, "asset1") - require.EqualError(t, err, "the asset asset1 does not exist") - - chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve asset")) - err = assetTransfer.DeleteAsset(transactionContext, "") - require.EqualError(t, err, "failed to read from world state: unable to retrieve asset") -} - -func TestTransferAsset(t *testing.T) { - chaincodeStub := &mocks.ChaincodeStub{} - transactionContext := &mocks.TransactionContext{} - transactionContext.GetStubReturns(chaincodeStub) - - asset := &chaincode.Asset{ID: "asset1"} - bytes, err := json.Marshal(asset) - require.NoError(t, err) - - chaincodeStub.GetStateReturns(bytes, nil) - assetTransfer := chaincode.SmartContract{} - _, err = assetTransfer.TransferAsset(transactionContext, "", "") - require.NoError(t, err) - - chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve asset")) - _, err = assetTransfer.TransferAsset(transactionContext, "", "") - require.EqualError(t, err, "failed to read from world state: unable to retrieve asset") -} - -func TestGetAllAssets(t *testing.T) { - asset := &chaincode.Asset{ID: "asset1"} - bytes, err := json.Marshal(asset) - require.NoError(t, err) - - iterator := &mocks.StateQueryIterator{} - iterator.HasNextReturnsOnCall(0, true) - iterator.HasNextReturnsOnCall(1, false) - iterator.NextReturns(&queryresult.KV{Value: bytes}, nil) - - chaincodeStub := &mocks.ChaincodeStub{} - transactionContext := &mocks.TransactionContext{} - transactionContext.GetStubReturns(chaincodeStub) - - chaincodeStub.GetStateByRangeReturns(iterator, nil) - assetTransfer := &chaincode.SmartContract{} - assets, err := assetTransfer.GetAllAssets(transactionContext) - require.NoError(t, err) - require.Equal(t, []*chaincode.Asset{asset}, assets) - - iterator.HasNextReturns(true) - iterator.NextReturns(nil, fmt.Errorf("failed retrieving next item")) - assets, err = assetTransfer.GetAllAssets(transactionContext) - require.EqualError(t, err, "failed retrieving next item") - require.Nil(t, assets) - - chaincodeStub.GetStateByRangeReturns(nil, fmt.Errorf("failed retrieving all assets")) - assets, err = assetTransfer.GetAllAssets(transactionContext) - require.EqualError(t, err, "failed retrieving all assets") - require.Nil(t, assets) -} diff --git a/asset-transfer-basic/chaincode-go/go.mod b/asset-transfer-basic/chaincode-go/go.mod deleted file mode 100644 index 4eb2ca43..00000000 --- a/asset-transfer-basic/chaincode-go/go.mod +++ /dev/null @@ -1,31 +0,0 @@ -module github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-go - -go 1.22.0 - -require ( - github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 - github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 - github.com/stretchr/testify v1.10.0 - google.golang.org/protobuf v1.36.1 -) - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/asset-transfer-basic/chaincode-go/go.sum b/asset-transfer-basic/chaincode-go/go.sum deleted file mode 100644 index 4e0be676..00000000 --- a/asset-transfer-basic/chaincode-go/go.sum +++ /dev/null @@ -1,61 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 h1:IhkHfrl5X/fVnmB6pWeCYCdIJRi9bxj+WTnVN8DtW3c= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0/go.mod h1:PHHaFffjw7p7n9bmCfcm7RqDqYdivNEsJdiNIKZo5Lk= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 h1:rmUoBmciB0GL/miqcbJmJbgp5QTWoJUrZo+CNxrNLF4= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0/go.mod h1:FeWeO/jwGjiME7ak3GufqKIcwkejtzrDG4QxbfKydWs= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/asset-transfer-basic/chaincode-java/.gitattributes b/asset-transfer-basic/chaincode-java/.gitattributes deleted file mode 100644 index 00a51aff..00000000 --- a/asset-transfer-basic/chaincode-java/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# These are explicitly windows files and should use crlf -*.bat text eol=crlf - diff --git a/asset-transfer-basic/chaincode-java/.gitignore b/asset-transfer-basic/chaincode-java/.gitignore deleted file mode 100644 index bd6fd304..00000000 --- a/asset-transfer-basic/chaincode-java/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.idea/ -.gradle/ diff --git a/asset-transfer-basic/chaincode-java/Dockerfile b/asset-transfer-basic/chaincode-java/Dockerfile deleted file mode 100755 index c42f3051..00000000 --- a/asset-transfer-basic/chaincode-java/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -# the first stage -FROM gradle:8.6-jdk11 AS GRADLE_BUILD - -# copy the build.gradle and src code to the container -COPY src/ src/ -COPY build.gradle ./ - -# Build and package our code -RUN gradle --no-daemon build shadowJar -x checkstyleMain -x checkstyleTest - - -# the second stage of our build just needs the compiled files -FROM openjdk:11-jre -ARG CC_SERVER_PORT=9999 - -# Setup tini to work better handle signals -ENV TINI_VERSION v0.19.0 -ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini -RUN chmod +x /tini - -RUN addgroup --system javauser && useradd -g javauser javauser - -# copy only the artifacts we need from the first stage and discard the rest -COPY --chown=javauser:javauser --from=GRADLE_BUILD /home/gradle/build/libs/chaincode.jar /chaincode.jar -COPY --chown=javauser:javauser docker/docker-entrypoint.sh /docker-entrypoint.sh - -ENV PORT $CC_SERVER_PORT -EXPOSE $CC_SERVER_PORT - -USER javauser -ENTRYPOINT [ "/tini", "--", "/docker-entrypoint.sh" ] diff --git a/asset-transfer-basic/chaincode-java/README.md b/asset-transfer-basic/chaincode-java/README.md deleted file mode 100644 index e069f568..00000000 --- a/asset-transfer-basic/chaincode-java/README.md +++ /dev/null @@ -1,10 +0,0 @@ - -## Basic Asset Transfer - -This sample implements the basic asset transfer scenario, illustrating the use of the Java Contract SDKs to provide a -smart contract as a service. - -To run this chaincode contract locally on a development network, see: - -- [Debugging chaincode as a service](../../test-network-k8s/docs/CHAINCODE_AS_A_SERVICE.md) (Kube test network) -- [End-to-end with the test-network](../../test-network/CHAINCODE_AS_A_SERVICE_TUTORIAL.md#end-to-end-with-the-the-test-network) (Docker compose) diff --git a/asset-transfer-basic/chaincode-java/build.gradle b/asset-transfer-basic/chaincode-java/build.gradle deleted file mode 100644 index d26c3b68..00000000 --- a/asset-transfer-basic/chaincode-java/build.gradle +++ /dev/null @@ -1,92 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -plugins { - id 'com.gradleup.shadow' version '8.3.5' - id 'application' - id 'checkstyle' - id 'jacoco' -} - -group 'org.hyperledger.fabric.samples' -version '1.0-SNAPSHOT' - -dependencies { - - implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.+' - implementation 'org.json:json:+' - implementation 'com.owlike:genson:1.6' - testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2' - testImplementation 'org.assertj:assertj-core:3.25.3' - testImplementation 'org.mockito:mockito-core:5.12.0' -} - -repositories { - mavenCentral() - maven { - url 'https://jitpack.io' - } -} - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(11) - } -} - -application { - mainClass = 'org.hyperledger.fabric.contract.ContractRouter' -} - -checkstyle { - toolVersion '8.21' - configFile file("config/checkstyle/checkstyle.xml") -} - -checkstyleMain { - source ='src/main/java' -} - -checkstyleTest { - source ='src/test/java' -} - -jacocoTestReport { - dependsOn test -} - -jacocoTestCoverageVerification { - violationRules { - rule { - limit { - minimum = 0.9 - } - } - } - - finalizedBy jacocoTestReport -} - -test { - useJUnitPlatform() - testLogging { - events "passed", "skipped", "failed" - } -} - -mainClassName = 'org.hyperledger.fabric.contract.ContractRouter' - -shadowJar { - archiveBaseName = 'chaincode' - archiveVersion = '' - archiveClassifier = '' - mergeServiceFiles() - - manifest { - attributes 'Main-Class': 'org.hyperledger.fabric.contract.ContractRouter' - } -} - -check.dependsOn jacocoTestCoverageVerification -installDist.dependsOn check diff --git a/asset-transfer-basic/chaincode-java/config/checkstyle/checkstyle.xml b/asset-transfer-basic/chaincode-java/config/checkstyle/checkstyle.xml deleted file mode 100644 index acd5df44..00000000 --- a/asset-transfer-basic/chaincode-java/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/asset-transfer-basic/chaincode-java/config/checkstyle/suppressions.xml b/asset-transfer-basic/chaincode-java/config/checkstyle/suppressions.xml deleted file mode 100644 index 8c44b0a0..00000000 --- a/asset-transfer-basic/chaincode-java/config/checkstyle/suppressions.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/asset-transfer-basic/chaincode-java/docker/docker-entrypoint.sh b/asset-transfer-basic/chaincode-java/docker/docker-entrypoint.sh deleted file mode 100755 index 1ff8e07e..00000000 --- a/asset-transfer-basic/chaincode-java/docker/docker-entrypoint.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -# -# SPDX-License-Identifier: Apache-2.0 -# -set -euo pipefail -: ${CORE_PEER_TLS_ENABLED:="false"} -: ${DEBUG:="false"} - -if [ "${DEBUG,,}" = "true" ]; then - exec java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:8000 -jar /chaincode.jar -elif [ "${CORE_PEER_TLS_ENABLED,,}" = "true" ]; then - exec java -jar /chaincode.jar # todo -else - exec java -jar /chaincode.jar -fi - diff --git a/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.jar b/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index d64cd491..00000000 Binary files a/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.properties b/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e2847c82..00000000 --- a/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/asset-transfer-basic/chaincode-java/gradlew b/asset-transfer-basic/chaincode-java/gradlew deleted file mode 100755 index 1aa94a42..00000000 --- a/asset-transfer-basic/chaincode-java/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/asset-transfer-basic/chaincode-java/gradlew.bat b/asset-transfer-basic/chaincode-java/gradlew.bat deleted file mode 100644 index 25da30db..00000000 --- a/asset-transfer-basic/chaincode-java/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/asset-transfer-basic/chaincode-java/settings.gradle b/asset-transfer-basic/chaincode-java/settings.gradle deleted file mode 100644 index b8074969..00000000 --- a/asset-transfer-basic/chaincode-java/settings.gradle +++ /dev/null @@ -1,4 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ -rootProject.name = System.getenv('CHAINCODE_NAME') ?: 'basic' \ No newline at end of file diff --git a/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/Asset.java b/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/Asset.java deleted file mode 100644 index 803f22fb..00000000 --- a/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/Asset.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.assettransfer; - -import java.util.Objects; - -import org.hyperledger.fabric.contract.annotation.DataType; -import org.hyperledger.fabric.contract.annotation.Property; - -import com.owlike.genson.annotation.JsonProperty; - -@DataType() -public final class Asset { - - @Property() - private final String assetID; - - @Property() - private final String color; - - @Property() - private final int size; - - @Property() - private final String owner; - - @Property() - private final int appraisedValue; - - public String getAssetID() { - return assetID; - } - - public String getColor() { - return color; - } - - public int getSize() { - return size; - } - - public String getOwner() { - return owner; - } - - public int getAppraisedValue() { - return appraisedValue; - } - - public Asset(@JsonProperty("assetID") final String assetID, @JsonProperty("color") final String color, - @JsonProperty("size") final int size, @JsonProperty("owner") final String owner, - @JsonProperty("appraisedValue") final int appraisedValue) { - this.assetID = assetID; - this.color = color; - this.size = size; - this.owner = owner; - this.appraisedValue = appraisedValue; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - - Asset other = (Asset) obj; - - return Objects.deepEquals( - new String[] {getAssetID(), getColor(), getOwner()}, - new String[] {other.getAssetID(), other.getColor(), other.getOwner()}) - && - Objects.deepEquals( - new int[] {getSize(), getAppraisedValue()}, - new int[] {other.getSize(), other.getAppraisedValue()}); - } - - @Override - public int hashCode() { - return Objects.hash(getAssetID(), getColor(), getSize(), getOwner(), getAppraisedValue()); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()) + " [assetID=" + assetID + ", color=" - + color + ", size=" + size + ", owner=" + owner + ", appraisedValue=" + appraisedValue + "]"; - } -} diff --git a/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.java b/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.java deleted file mode 100644 index 68e3b139..00000000 --- a/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.assettransfer; - -import java.util.ArrayList; -import java.util.List; - - -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.contract.ContractInterface; -import org.hyperledger.fabric.contract.annotation.Contact; -import org.hyperledger.fabric.contract.annotation.Contract; -import org.hyperledger.fabric.contract.annotation.Default; -import org.hyperledger.fabric.contract.annotation.Info; -import org.hyperledger.fabric.contract.annotation.License; -import org.hyperledger.fabric.contract.annotation.Transaction; -import org.hyperledger.fabric.shim.ChaincodeException; -import org.hyperledger.fabric.shim.ChaincodeStub; -import org.hyperledger.fabric.shim.ledger.KeyValue; -import org.hyperledger.fabric.shim.ledger.QueryResultsIterator; - -import com.owlike.genson.Genson; - -@Contract( - name = "basic", - info = @Info( - title = "Asset Transfer", - description = "The hyperlegendary asset transfer", - version = "0.0.1-SNAPSHOT", - license = @License( - name = "Apache 2.0 License", - url = "http://www.apache.org/licenses/LICENSE-2.0.html"), - contact = @Contact( - email = "a.transfer@example.com", - name = "Adrian Transfer", - url = "https://hyperledger.example.com"))) -@Default -public final class AssetTransfer implements ContractInterface { - - private final Genson genson = new Genson(); - - private enum AssetTransferErrors { - ASSET_NOT_FOUND, - ASSET_ALREADY_EXISTS - } - - /** - * Creates some initial assets on the ledger. - * - * @param ctx the transaction context - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public void InitLedger(final Context ctx) { - putAsset(ctx, new Asset("asset1", "blue", 5, "Tomoko", 300)); - putAsset(ctx, new Asset("asset2", "red", 5, "Brad", 400)); - putAsset(ctx, new Asset("asset3", "green", 10, "Jin Soo", 500)); - putAsset(ctx, new Asset("asset4", "yellow", 10, "Max", 600)); - putAsset(ctx, new Asset("asset5", "black", 15, "Adrian", 700)); - putAsset(ctx, new Asset("asset6", "white", 15, "Michel", 700)); - - } - - /** - * Creates a new asset on the ledger. - * - * @param ctx the transaction context - * @param assetID the ID of the new asset - * @param color the color of the new asset - * @param size the size for the new asset - * @param owner the owner of the new asset - * @param appraisedValue the appraisedValue of the new asset - * @return the created asset - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public Asset CreateAsset(final Context ctx, final String assetID, final String color, final int size, - final String owner, final int appraisedValue) { - - if (AssetExists(ctx, assetID)) { - String errorMessage = String.format("Asset %s already exists", assetID); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_ALREADY_EXISTS.toString()); - } - - return putAsset(ctx, new Asset(assetID, color, size, owner, appraisedValue)); - } - - private Asset putAsset(final Context ctx, final Asset asset) { - // Use Genson to convert the Asset into string, sort it alphabetically and serialize it into a json string - String sortedJson = genson.serialize(asset); - ctx.getStub().putStringState(asset.getAssetID(), sortedJson); - - return asset; - } - - /** - * Retrieves an asset with the specified ID from the ledger. - * - * @param ctx the transaction context - * @param assetID the ID of the asset - * @return the asset found on the ledger if there was one - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public Asset ReadAsset(final Context ctx, final String assetID) { - String assetJSON = ctx.getStub().getStringState(assetID); - - if (assetJSON == null || assetJSON.isEmpty()) { - String errorMessage = String.format("Asset %s does not exist", assetID); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - - return genson.deserialize(assetJSON, Asset.class); - } - - /** - * Updates the properties of an asset on the ledger. - * - * @param ctx the transaction context - * @param assetID the ID of the asset being updated - * @param color the color of the asset being updated - * @param size the size of the asset being updated - * @param owner the owner of the asset being updated - * @param appraisedValue the appraisedValue of the asset being updated - * @return the transferred asset - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public Asset UpdateAsset(final Context ctx, final String assetID, final String color, final int size, - final String owner, final int appraisedValue) { - - if (!AssetExists(ctx, assetID)) { - String errorMessage = String.format("Asset %s does not exist", assetID); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - - return putAsset(ctx, new Asset(assetID, color, size, owner, appraisedValue)); - } - - /** - * Deletes asset on the ledger. - * - * @param ctx the transaction context - * @param assetID the ID of the asset being deleted - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public void DeleteAsset(final Context ctx, final String assetID) { - if (!AssetExists(ctx, assetID)) { - String errorMessage = String.format("Asset %s does not exist", assetID); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - - ctx.getStub().delState(assetID); - } - - /** - * Checks the existence of the asset on the ledger - * - * @param ctx the transaction context - * @param assetID the ID of the asset - * @return boolean indicating the existence of the asset - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public boolean AssetExists(final Context ctx, final String assetID) { - String assetJSON = ctx.getStub().getStringState(assetID); - - return (assetJSON != null && !assetJSON.isEmpty()); - } - - /** - * Changes the owner of a asset on the ledger. - * - * @param ctx the transaction context - * @param assetID the ID of the asset being transferred - * @param newOwner the new owner - * @return the old owner - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public String TransferAsset(final Context ctx, final String assetID, final String newOwner) { - String assetJSON = ctx.getStub().getStringState(assetID); - - if (assetJSON == null || assetJSON.isEmpty()) { - String errorMessage = String.format("Asset %s does not exist", assetID); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - - Asset asset = genson.deserialize(assetJSON, Asset.class); - - putAsset(ctx, new Asset(asset.getAssetID(), asset.getColor(), asset.getSize(), newOwner, asset.getAppraisedValue())); - - return asset.getOwner(); - } - - /** - * Retrieves all assets from the ledger. - * - * @param ctx the transaction context - * @return array of assets found on the ledger - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public String GetAllAssets(final Context ctx) { - ChaincodeStub stub = ctx.getStub(); - - List queryResults = new ArrayList<>(); - - // To retrieve all assets from the ledger use getStateByRange with empty startKey & endKey. - // Giving empty startKey & endKey is interpreted as all the keys from beginning to end. - // As another example, if you use startKey = 'asset0', endKey = 'asset9' , - // then getStateByRange will retrieve asset with keys between asset0 (inclusive) and asset9 (exclusive) in lexical order. - QueryResultsIterator results = stub.getStateByRange("", ""); - - for (KeyValue result: results) { - Asset asset = genson.deserialize(result.getStringValue(), Asset.class); - System.out.println(asset); - queryResults.add(asset); - } - - return genson.serialize(queryResults); - } -} diff --git a/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTest.java b/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTest.java deleted file mode 100644 index 7da94caa..00000000 --- a/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.assettransfer; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -public final class AssetTest { - - @Nested - class Equality { - - @Test - public void isReflexive() { - Asset asset = new Asset("asset1", "Blue", 20, "Guy", 100); - - assertThat(asset).isEqualTo(asset); - } - - @Test - public void isSymmetric() { - Asset assetA = new Asset("asset1", "Blue", 20, "Guy", 100); - Asset assetB = new Asset("asset1", "Blue", 20, "Guy", 100); - - assertThat(assetA).isEqualTo(assetB); - assertThat(assetB).isEqualTo(assetA); - } - - @Test - public void isTransitive() { - Asset assetA = new Asset("asset1", "Blue", 20, "Guy", 100); - Asset assetB = new Asset("asset1", "Blue", 20, "Guy", 100); - Asset assetC = new Asset("asset1", "Blue", 20, "Guy", 100); - - assertThat(assetA).isEqualTo(assetB); - assertThat(assetB).isEqualTo(assetC); - assertThat(assetA).isEqualTo(assetC); - } - - @Test - public void handlesInequality() { - Asset assetA = new Asset("asset1", "Blue", 20, "Guy", 100); - Asset assetB = new Asset("asset2", "Red", 40, "Lady", 200); - - assertThat(assetA).isNotEqualTo(assetB); - } - - @Test - public void handlesOtherObjects() { - Asset assetA = new Asset("asset1", "Blue", 20, "Guy", 100); - String assetB = "not a asset"; - - assertThat(assetA).isNotEqualTo(assetB); - } - - @Test - public void handlesNull() { - Asset asset = new Asset("asset1", "Blue", 20, "Guy", 100); - - assertThat(asset).isNotEqualTo(null); - } - } - - @Test - public void toStringIdentifiesAsset() { - Asset asset = new Asset("asset1", "Blue", 20, "Guy", 100); - - assertThat(asset.toString()).isEqualTo("Asset@e04f6c53 [assetID=asset1, color=Blue, size=20, owner=Guy, appraisedValue=100]"); - } -} diff --git a/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTransferTest.java b/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTransferTest.java deleted file mode 100644 index f54f3b1d..00000000 --- a/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTransferTest.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.assettransfer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.ThrowableAssert.catchThrowable; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.when; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.shim.ChaincodeException; -import org.hyperledger.fabric.shim.ChaincodeStub; -import org.hyperledger.fabric.shim.ledger.KeyValue; -import org.hyperledger.fabric.shim.ledger.QueryResultsIterator; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.InOrder; - -public final class AssetTransferTest { - - private static final class MockKeyValue implements KeyValue { - - private final String key; - private final String value; - - MockKeyValue(final String key, final String value) { - super(); - this.key = key; - this.value = value; - } - - @Override - public String getKey() { - return this.key; - } - - @Override - public String getStringValue() { - return this.value; - } - - @Override - public byte[] getValue() { - return this.value.getBytes(); - } - - } - - private static final class MockAssetResultsIterator implements QueryResultsIterator { - - private final List assetList; - - MockAssetResultsIterator() { - super(); - - assetList = new ArrayList(); - - assetList.add(new MockKeyValue("asset1", - "{ \"assetID\": \"asset1\", \"color\": \"blue\", \"size\": 5, \"owner\": \"Tomoko\", \"appraisedValue\": 300 }")); - assetList.add(new MockKeyValue("asset2", - "{ \"assetID\": \"asset2\", \"color\": \"red\", \"size\": 5,\"owner\": \"Brad\", \"appraisedValue\": 400 }")); - assetList.add(new MockKeyValue("asset3", - "{ \"assetID\": \"asset3\", \"color\": \"green\", \"size\": 10,\"owner\": \"Jin Soo\", \"appraisedValue\": 500 }")); - assetList.add(new MockKeyValue("asset4", - "{ \"assetID\": \"asset4\", \"color\": \"yellow\", \"size\": 10,\"owner\": \"Max\", \"appraisedValue\": 600 }")); - assetList.add(new MockKeyValue("asset5", - "{ \"assetID\": \"asset5\", \"color\": \"black\", \"size\": 15,\"owner\": \"Adrian\", \"appraisedValue\": 700 }")); - assetList.add(new MockKeyValue("asset6", - "{ \"assetID\": \"asset6\", \"color\": \"white\", \"size\": 15,\"owner\": \"Michel\", \"appraisedValue\": 800 }")); - } - - @Override - public Iterator iterator() { - return assetList.iterator(); - } - - @Override - public void close() throws Exception { - // do nothing - } - - } - - @Test - public void invokeUnknownTransaction() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - - Throwable thrown = catchThrowable(() -> { - contract.unknownTransaction(ctx); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Undefined contract method called"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo(null); - - verifyNoInteractions(ctx); - } - - @Nested - class InvokeReadAssetTransaction { - - @Test - public void whenAssetExists() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")) - .thenReturn("{ \"assetID\": \"asset1\", \"color\": \"blue\", \"size\": 5, \"owner\": \"Tomoko\", \"appraisedValue\": 300 }"); - - Asset asset = contract.ReadAsset(ctx, "asset1"); - - assertThat(asset).isEqualTo(new Asset("asset1", "blue", 5, "Tomoko", 300)); - } - - @Test - public void whenAssetDoesNotExist() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")).thenReturn(""); - - Throwable thrown = catchThrowable(() -> { - contract.ReadAsset(ctx, "asset1"); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Asset asset1 does not exist"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("ASSET_NOT_FOUND".getBytes()); - } - } - - @Test - void invokeInitLedgerTransaction() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - - contract.InitLedger(ctx); - - InOrder inOrder = inOrder(stub); - inOrder.verify(stub).putStringState("asset1", "{\"appraisedValue\":300,\"assetID\":\"asset1\",\"color\":\"blue\",\"owner\":\"Tomoko\",\"size\":5}"); - inOrder.verify(stub).putStringState("asset2", "{\"appraisedValue\":400,\"assetID\":\"asset2\",\"color\":\"red\",\"owner\":\"Brad\",\"size\":5}"); - inOrder.verify(stub).putStringState("asset3", "{\"appraisedValue\":500,\"assetID\":\"asset3\",\"color\":\"green\",\"owner\":\"Jin Soo\",\"size\":10}"); - inOrder.verify(stub).putStringState("asset4", "{\"appraisedValue\":600,\"assetID\":\"asset4\",\"color\":\"yellow\",\"owner\":\"Max\",\"size\":10}"); - inOrder.verify(stub).putStringState("asset5", "{\"appraisedValue\":700,\"assetID\":\"asset5\",\"color\":\"black\",\"owner\":\"Adrian\",\"size\":15}"); - - } - - @Nested - class InvokeCreateAssetTransaction { - - @Test - public void whenAssetExists() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")) - .thenReturn("{ \"assetID\": \"asset1\", \"color\": \"blue\", \"size\": 5, \"owner\": \"Tomoko\", \"appraisedValue\": 300 }"); - - Throwable thrown = catchThrowable(() -> { - contract.CreateAsset(ctx, "asset1", "blue", 45, "Siobhán", 60); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Asset asset1 already exists"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("ASSET_ALREADY_EXISTS".getBytes()); - } - - @Test - public void whenAssetDoesNotExist() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")).thenReturn(""); - - Asset asset = contract.CreateAsset(ctx, "asset1", "blue", 45, "Siobhán", 60); - - assertThat(asset).isEqualTo(new Asset("asset1", "blue", 45, "Siobhán", 60)); - } - } - - @Test - void invokeGetAllAssetsTransaction() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStateByRange("", "")).thenReturn(new MockAssetResultsIterator()); - - String assets = contract.GetAllAssets(ctx); - - assertThat(assets).isEqualTo("[{\"appraisedValue\":300,\"assetID\":\"asset1\",\"color\":\"blue\",\"owner\":\"Tomoko\",\"size\":5}," - + "{\"appraisedValue\":400,\"assetID\":\"asset2\",\"color\":\"red\",\"owner\":\"Brad\",\"size\":5}," - + "{\"appraisedValue\":500,\"assetID\":\"asset3\",\"color\":\"green\",\"owner\":\"Jin Soo\",\"size\":10}," - + "{\"appraisedValue\":600,\"assetID\":\"asset4\",\"color\":\"yellow\",\"owner\":\"Max\",\"size\":10}," - + "{\"appraisedValue\":700,\"assetID\":\"asset5\",\"color\":\"black\",\"owner\":\"Adrian\",\"size\":15}," - + "{\"appraisedValue\":800,\"assetID\":\"asset6\",\"color\":\"white\",\"owner\":\"Michel\",\"size\":15}]"); - - } - - @Nested - class TransferAssetTransaction { - - @Test - public void whenAssetExists() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")) - .thenReturn("{ \"assetID\": \"asset1\", \"color\": \"blue\", \"size\": 5, \"owner\": \"Tomoko\", \"appraisedValue\": 300 }"); - - String oldOwner = contract.TransferAsset(ctx, "asset1", "Dr Evil"); - - assertThat(oldOwner).isEqualTo("Tomoko"); - } - - @Test - public void whenAssetDoesNotExist() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")).thenReturn(""); - - Throwable thrown = catchThrowable(() -> { - contract.TransferAsset(ctx, "asset1", "Dr Evil"); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Asset asset1 does not exist"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("ASSET_NOT_FOUND".getBytes()); - } - } - - @Nested - class UpdateAssetTransaction { - - @Test - public void whenAssetExists() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")) - .thenReturn("{ \"assetID\": \"asset1\", \"color\": \"blue\", \"size\": 45, \"owner\": \"Arturo\", \"appraisedValue\": 60 }"); - - Asset asset = contract.UpdateAsset(ctx, "asset1", "pink", 45, "Arturo", 600); - - assertThat(asset).isEqualTo(new Asset("asset1", "pink", 45, "Arturo", 600)); - } - - @Test - public void whenAssetDoesNotExist() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")).thenReturn(""); - - Throwable thrown = catchThrowable(() -> { - contract.TransferAsset(ctx, "asset1", "Alex"); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Asset asset1 does not exist"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("ASSET_NOT_FOUND".getBytes()); - } - } - - @Nested - class DeleteAssetTransaction { - - @Test - public void whenAssetDoesNotExist() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")).thenReturn(""); - - Throwable thrown = catchThrowable(() -> { - contract.DeleteAsset(ctx, "asset1"); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Asset asset1 does not exist"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("ASSET_NOT_FOUND".getBytes()); - } - } -} diff --git a/asset-transfer-basic/chaincode-javascript/.eslintignore b/asset-transfer-basic/chaincode-javascript/.eslintignore deleted file mode 100644 index 15958470..00000000 --- a/asset-transfer-basic/chaincode-javascript/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -coverage diff --git a/asset-transfer-basic/chaincode-javascript/.eslintrc.js b/asset-transfer-basic/chaincode-javascript/.eslintrc.js deleted file mode 100644 index 555c0cf5..00000000 --- a/asset-transfer-basic/chaincode-javascript/.eslintrc.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -module.exports = { - env: { - node: true, - mocha: true, - es6: true - }, - parserOptions: { - ecmaVersion: 8, - sourceType: 'script' - }, - extends: "eslint:recommended", - rules: { - indent: ['error', 4], - 'linebreak-style': ['error', 'unix'], - quotes: ['error', 'single'], - semi: ['error', 'always'], - 'no-unused-vars': ['error', { args: 'none' }], - 'no-console': 'off', - curly: 'error', - eqeqeq: 'error', - 'no-throw-literal': 'error', - strict: 'error', - 'no-var': 'error', - 'dot-notation': 'error', - 'no-tabs': 'error', - 'no-trailing-spaces': 'error', - 'no-use-before-define': 'error', - 'no-useless-call': 'error', - 'no-with': 'error', - 'operator-linebreak': 'error', - yoda: 'error', - 'quote-props': ['error', 'as-needed'], - 'no-constant-condition': ["error", { "checkLoops": false }] - } -}; diff --git a/asset-transfer-basic/chaincode-javascript/.gitignore b/asset-transfer-basic/chaincode-javascript/.gitignore deleted file mode 100644 index eeace290..00000000 --- a/asset-transfer-basic/chaincode-javascript/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -# Coverage directory used by tools like istanbul -coverage - -# Report cache used by istanbul -.nyc_output - -# Dependency directories -node_modules/ -jspm_packages/ - -package-lock.json diff --git a/asset-transfer-basic/chaincode-javascript/index.js b/asset-transfer-basic/chaincode-javascript/index.js deleted file mode 100644 index 55a0dcfb..00000000 --- a/asset-transfer-basic/chaincode-javascript/index.js +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const assetTransfer = require('./lib/assetTransfer'); - -module.exports.AssetTransfer = assetTransfer; -module.exports.contracts = [assetTransfer]; diff --git a/asset-transfer-basic/chaincode-javascript/lib/assetTransfer.js b/asset-transfer-basic/chaincode-javascript/lib/assetTransfer.js deleted file mode 100644 index a68b75c6..00000000 --- a/asset-transfer-basic/chaincode-javascript/lib/assetTransfer.js +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -// Deterministic JSON.stringify() -const stringify = require('json-stringify-deterministic'); -const sortKeysRecursive = require('sort-keys-recursive'); -const { Contract } = require('fabric-contract-api'); - -class AssetTransfer extends Contract { - - async InitLedger(ctx) { - const assets = [ - { - ID: 'asset1', - Color: 'blue', - Size: 5, - Owner: 'Tomoko', - AppraisedValue: 300, - }, - { - ID: 'asset2', - Color: 'red', - Size: 5, - Owner: 'Brad', - AppraisedValue: 400, - }, - { - ID: 'asset3', - Color: 'green', - Size: 10, - Owner: 'Jin Soo', - AppraisedValue: 500, - }, - { - ID: 'asset4', - Color: 'yellow', - Size: 10, - Owner: 'Max', - AppraisedValue: 600, - }, - { - ID: 'asset5', - Color: 'black', - Size: 15, - Owner: 'Adriana', - AppraisedValue: 700, - }, - { - ID: 'asset6', - Color: 'white', - Size: 15, - Owner: 'Michel', - AppraisedValue: 800, - }, - ]; - - for (const asset of assets) { - asset.docType = 'asset'; - // example of how to write to world state deterministically - // use convetion of alphabetic order - // we insert data in alphabetic order using 'json-stringify-deterministic' and 'sort-keys-recursive' - // when retrieving data, in any lang, the order of data will be the same and consequently also the corresonding hash - await ctx.stub.putState(asset.ID, Buffer.from(stringify(sortKeysRecursive(asset)))); - } - } - - // CreateAsset issues a new asset to the world state with given details. - async CreateAsset(ctx, id, color, size, owner, appraisedValue) { - const exists = await this.AssetExists(ctx, id); - if (exists) { - throw new Error(`The asset ${id} already exists`); - } - - const asset = { - ID: id, - Color: color, - Size: size, - Owner: owner, - AppraisedValue: appraisedValue, - }; - // we insert data in alphabetic order using 'json-stringify-deterministic' and 'sort-keys-recursive' - await ctx.stub.putState(id, Buffer.from(stringify(sortKeysRecursive(asset)))); - return JSON.stringify(asset); - } - - // ReadAsset returns the asset stored in the world state with given id. - async ReadAsset(ctx, id) { - const assetJSON = await ctx.stub.getState(id); // get the asset from chaincode state - if (!assetJSON || assetJSON.length === 0) { - throw new Error(`The asset ${id} does not exist`); - } - return assetJSON.toString(); - } - - // UpdateAsset updates an existing asset in the world state with provided parameters. - async UpdateAsset(ctx, id, color, size, owner, appraisedValue) { - const exists = await this.AssetExists(ctx, id); - if (!exists) { - throw new Error(`The asset ${id} does not exist`); - } - - // overwriting original asset with new asset - const updatedAsset = { - ID: id, - Color: color, - Size: size, - Owner: owner, - AppraisedValue: appraisedValue, - }; - // we insert data in alphabetic order using 'json-stringify-deterministic' and 'sort-keys-recursive' - return ctx.stub.putState(id, Buffer.from(stringify(sortKeysRecursive(updatedAsset)))); - } - - // DeleteAsset deletes an given asset from the world state. - async DeleteAsset(ctx, id) { - const exists = await this.AssetExists(ctx, id); - if (!exists) { - throw new Error(`The asset ${id} does not exist`); - } - return ctx.stub.deleteState(id); - } - - // AssetExists returns true when asset with given ID exists in world state. - async AssetExists(ctx, id) { - const assetJSON = await ctx.stub.getState(id); - return assetJSON && assetJSON.length > 0; - } - - // TransferAsset updates the owner field of asset with given id in the world state. - async TransferAsset(ctx, id, newOwner) { - const assetString = await this.ReadAsset(ctx, id); - const asset = JSON.parse(assetString); - const oldOwner = asset.Owner; - asset.Owner = newOwner; - // we insert data in alphabetic order using 'json-stringify-deterministic' and 'sort-keys-recursive' - await ctx.stub.putState(id, Buffer.from(stringify(sortKeysRecursive(asset)))); - return oldOwner; - } - - // GetAllAssets returns all assets found in the world state. - async GetAllAssets(ctx) { - const allResults = []; - // range query with empty string for startKey and endKey does an open-ended query of all assets in the chaincode namespace. - const iterator = await ctx.stub.getStateByRange('', ''); - let result = await iterator.next(); - while (!result.done) { - const strValue = Buffer.from(result.value.value.toString()).toString('utf8'); - let record; - try { - record = JSON.parse(strValue); - } catch (err) { - console.log(err); - record = strValue; - } - allResults.push(record); - result = await iterator.next(); - } - return JSON.stringify(allResults); - } -} - -module.exports = AssetTransfer; diff --git a/asset-transfer-basic/chaincode-javascript/npm-shrinkwrap.json b/asset-transfer-basic/chaincode-javascript/npm-shrinkwrap.json deleted file mode 100644 index ee1170c7..00000000 --- a/asset-transfer-basic/chaincode-javascript/npm-shrinkwrap.json +++ /dev/null @@ -1,4025 +0,0 @@ -{ - "name": "asset-transfer-basic", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "asset-transfer-basic", - "version": "1.0.0", - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "~2.5", - "fabric-shim": "~2.5", - "json-stringify-deterministic": "^1.0.0", - "sort-keys-recursive": "^2.1.0" - }, - "devDependencies": { - "chai": "^4.4.1", - "eslint": "^8.57.0", - "mocha": "^10.4.0", - "nyc": "^15.1.0", - "sinon": "^18.0.0", - "sinon-chai": "^3.7.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@fidm/asn1": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@fidm/asn1/-/asn1-1.0.4.tgz", - "integrity": "sha512-esd1jyNvRb2HVaQGq2Gg8Z0kbQPXzV9Tq5Z14KNIov6KfFD6PTaRIO8UpcsYiTNzOqJpmyzWgVTrUwFV3UF4TQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@fidm/x509": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@fidm/x509/-/x509-1.2.1.tgz", - "integrity": "sha512-nwc2iesjyc9hkuzcrMCBXQRn653XuAUKorfWM8PZyJawiy1QzLj4vahwzaI25+pfpwOLvMzbJ0uKpWLDNmo16w==", - "dependencies": { - "@fidm/asn1": "^1.0.4", - "tweetnacl": "^1.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.10.9", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.9.tgz", - "integrity": "sha512-5tcgUctCG0qoNyfChZifz2tJqbRbXVO9J7X6duFcOjY3HUNCxg5D0ZCK7EP9vIcZ0zRpLU9bWkyCqVCLZ46IbQ==", - "dependencies": { - "@grpc/proto-loader": "^0.7.13", - "@js-sdsl/ordered-map": "^4.4.2" - }, - "engines": { - "node": ">=12.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@hyperledger/fabric-protos": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@hyperledger/fabric-protos/-/fabric-protos-0.2.1.tgz", - "integrity": "sha512-qjm0vIQIfCall804tWDeA8p/mUfu14sl5Sj+PbOn2yDKJq+7ThoIhNsLAqf+BCxUfqsoqQq6AojhqQeTFyOOqg==", - "dependencies": { - "@grpc/grpc-js": "^1.9.0", - "google-protobuf": "^3.21.0" - }, - "engines": { - "node": ">=14.15.0" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "16.18.98", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.98.tgz", - "integrity": "sha512-fpiC20NvLpTLAzo3oVBKIqBGR6Fx/8oAK/SSf7G+fydnXMY1x4x9RZ6sBXhqKlCU21g2QapUsbLlhv3+a7wS+Q==" - }, - "node_modules/@types/triple-beam": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "dependencies": { - "default-require-extensions": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001633", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001633.tgz", - "integrity": "sha512-6sT0yf/z5jqf8tISAgpJDrmwOpLsrpnyCdD/lOZKvKkkJK4Dn0X5i7KF7THEZhOq+30bmhwBlNEaqPUiHiKtZg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/class-transformer": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", - "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==" - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-eql": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/default-require-extensions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", - "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", - "dev": true, - "dependencies": { - "strip-bom": "^4.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.802", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.802.tgz", - "integrity": "sha512-TnTMUATbgNdPXVSHsxvNVSG0uEd6cSZsANjm8c9HbvflZVVn1yTRcmVXYT1Ma95/ssB/Dcd30AHweH2TE+dNpA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fabric-contract-api": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-contract-api/-/fabric-contract-api-2.5.6.tgz", - "integrity": "sha512-AosGb8tA+Jgt+pqMEgYNB3/J/P5QuWOC7yhXbhDmAAwUzn4Sc7pdWDICH1YyrFGZNFxMGQmqJmLVWUX8BKHy0w==", - "dependencies": { - "class-transformer": "^0.4.0", - "fabric-shim-api": "2.5.6", - "fast-safe-stringify": "^2.1.1", - "get-params": "^0.1.2", - "reflect-metadata": "^0.1.13", - "winston": "^3.7.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fabric-shim": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-shim/-/fabric-shim-2.5.6.tgz", - "integrity": "sha512-4Y8WNFhYuQ9QYSEgPXWdlXnrXjwOlM10sQQzE4kJ7cDh8a4LX0rn44FxtxTCB18lnzrSLMZ8/8Cr5m0c9NeXWA==", - "dependencies": { - "@fidm/x509": "^1.2.1", - "@grpc/grpc-js": "~1.10.9", - "@hyperledger/fabric-protos": "~0.2.1", - "@types/node": "^16.11.1", - "ajv": "^6.12.2", - "fabric-contract-api": "2.5.6", - "fabric-shim-api": "2.5.6", - "fast-safe-stringify": "^2.1.1", - "long": "^5.2.3", - "reflect-metadata": "^0.1.13", - "winston": "^3.7.2", - "yargs": "^17.4.0", - "yargs-parser": "^21.0.1" - }, - "bin": { - "fabric-chaincode-node": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fabric-shim-api": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-shim-api/-/fabric-shim-api-2.5.6.tgz", - "integrity": "sha512-1L0nO7CJ31/gEOWKWHEeCqgB5HkqPVfRbpcS7L9eTscT7tffjg2OkZISvC+a7RiqihL0iyrXNBgBg5MwlSSN9g==", - "engines": { - "eslint": "^6.6.0", - "node": ">=18" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-params": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/get-params/-/get-params-0.1.2.tgz", - "integrity": "sha512-41eOxtlGgHQRbFyA8KTH+w+32Em3cRdfBud7j67ulzmIfmaHX9doq47s0fa4P5o9H64BZX9nrYI6sJvk46Op+Q==" - }, - "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/google-protobuf": { - "version": "3.21.2", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz", - "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==" - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasha/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "dependencies": { - "append-transform": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", - "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", - "dev": true, - "dependencies": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.3", - "istanbul-lib-coverage": "^3.2.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json-stringify-deterministic": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/json-stringify-deterministic/-/json-stringify-deterministic-1.0.12.tgz", - "integrity": "sha512-q3PN0lbUdv0pmurkBNdJH3pfFvOTL/Zp0lquqpvcjfKzt6Y0j49EPHAmVHCAS4Ceq/Y+PejWTzyiVpoY71+D6g==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/just-extend": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", - "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", - "dev": true - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" - }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/logform": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", - "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", - "dependencies": { - "@colors/colors": "1.6.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mocha": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", - "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", - "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "8.1.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/nise": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", - "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", - "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" - } - }, - "node_modules/node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "dependencies": { - "process-on-spawn": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/nyc/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/nyc/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/nyc/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nyc/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/nyc/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", - "dev": true - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "dependencies": { - "fromentries": "^1.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protobufjs": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.2.tgz", - "integrity": "sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reflect-metadata": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", - "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==" - }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", - "dev": true, - "dependencies": { - "es6-error": "^4.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/sinon": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", - "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.2.0", - "nise": "^6.0.0", - "supports-color": "^7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" - } - }, - "node_modules/sinon-chai": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", - "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", - "dev": true, - "peerDependencies": { - "chai": "^4.0.0", - "sinon": ">=4.0.0" - } - }, - "node_modules/sinon/node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/sort-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-4.2.0.tgz", - "integrity": "sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==", - "dependencies": { - "is-plain-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sort-keys-recursive": { - "version": "2.1.10", - "resolved": "https://registry.npmjs.org/sort-keys-recursive/-/sort-keys-recursive-2.1.10.tgz", - "integrity": "sha512-yRLJbEER/PjU7hSRwXvP+NyXiORufu8rbSbp+3wFRuJZXoi/AhuKczbjuipqn7Le0SsTXK4VUeri2+Ni6WS8Hg==", - "dependencies": { - "kind-of": "~6.0.2", - "sort-keys": "~4.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "dependencies": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "engines": { - "node": "*" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/triple-beam": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", - "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "node_modules/winston": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.0.tgz", - "integrity": "sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==", - "dependencies": { - "@colors/colors": "^1.6.0", - "@dabh/diagnostics": "^2.0.2", - "async": "^3.2.3", - "is-stream": "^2.0.0", - "logform": "^2.4.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "safe-stable-stringify": "^2.3.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/winston-transport": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", - "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", - "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/asset-transfer-basic/chaincode-javascript/package.json b/asset-transfer-basic/chaincode-javascript/package.json deleted file mode 100644 index b4ea1317..00000000 --- a/asset-transfer-basic/chaincode-javascript/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "asset-transfer-basic", - "version": "1.0.0", - "description": "Asset-Transfer-Basic contract implemented in JavaScript", - "main": "index.js", - "engines": { - "node": ">=18" - }, - "scripts": { - "lint": "eslint *.js */**.js", - "pretest": "npm run lint", - "test": "nyc mocha --recursive", - "start": "fabric-chaincode-node start" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "~2.5", - "fabric-shim": "~2.5", - "json-stringify-deterministic": "^1.0.0", - "sort-keys-recursive": "^2.1.0" - }, - "devDependencies": { - "chai": "^4.4.1", - "eslint": "^8.57.0", - "mocha": "^10.4.0", - "nyc": "^15.1.0", - "sinon": "^18.0.0", - "sinon-chai": "^3.7.0" - }, - "nyc": { - "exclude": [ - "coverage/**", - "test/**", - "index.js", - ".eslintrc.js" - ], - "reporter": [ - "text-summary", - "html" - ], - "all": true, - "check-coverage": true, - "statements": 100, - "branches": 100, - "functions": 100, - "lines": 100 - } -} diff --git a/asset-transfer-basic/chaincode-javascript/test/assetTransfer.test.js b/asset-transfer-basic/chaincode-javascript/test/assetTransfer.test.js deleted file mode 100644 index 906b5ff5..00000000 --- a/asset-transfer-basic/chaincode-javascript/test/assetTransfer.test.js +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; -const sinon = require('sinon'); -const chai = require('chai'); -const sinonChai = require('sinon-chai'); -const expect = chai.expect; - -const { Context } = require('fabric-contract-api'); -const { ChaincodeStub } = require('fabric-shim'); - -const AssetTransfer = require('../lib/assetTransfer.js'); - -let assert = sinon.assert; -chai.use(sinonChai); - -describe('Asset Transfer Basic Tests', () => { - let transactionContext, chaincodeStub, asset; - beforeEach(() => { - transactionContext = new Context(); - - chaincodeStub = sinon.createStubInstance(ChaincodeStub); - transactionContext.setChaincodeStub(chaincodeStub); - - chaincodeStub.putState.callsFake((key, value) => { - if (!chaincodeStub.states) { - chaincodeStub.states = {}; - } - chaincodeStub.states[key] = value; - }); - - chaincodeStub.getState.callsFake(async (key) => { - let ret; - if (chaincodeStub.states) { - ret = chaincodeStub.states[key]; - } - return Promise.resolve(ret); - }); - - chaincodeStub.deleteState.callsFake(async (key) => { - if (chaincodeStub.states) { - delete chaincodeStub.states[key]; - } - return Promise.resolve(key); - }); - - chaincodeStub.getStateByRange.callsFake(async () => { - function* internalGetStateByRange() { - if (chaincodeStub.states) { - // Shallow copy - const copied = Object.assign({}, chaincodeStub.states); - - for (let key in copied) { - yield {value: copied[key]}; - } - } - } - - return Promise.resolve(internalGetStateByRange()); - }); - - asset = { - ID: 'asset1', - Color: 'blue', - Size: 5, - Owner: 'Tomoko', - AppraisedValue: 300, - }; - }); - - describe('Test InitLedger', () => { - it('should return error on InitLedger', async () => { - chaincodeStub.putState.rejects('failed inserting key'); - let assetTransfer = new AssetTransfer(); - try { - await assetTransfer.InitLedger(transactionContext); - assert.fail('InitLedger should have failed'); - } catch (err) { - expect(err.name).to.equal('failed inserting key'); - } - }); - - it('should return success on InitLedger', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.InitLedger(transactionContext); - let ret = JSON.parse((await chaincodeStub.getState('asset1')).toString()); - expect(ret).to.eql(Object.assign({docType: 'asset'}, asset)); - }); - }); - - describe('Test CreateAsset', () => { - it('should return error on CreateAsset', async () => { - chaincodeStub.putState.rejects('failed inserting key'); - - let assetTransfer = new AssetTransfer(); - try { - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - assert.fail('CreateAsset should have failed'); - } catch(err) { - expect(err.name).to.equal('failed inserting key'); - } - }); - - it('should return success on CreateAsset', async () => { - let assetTransfer = new AssetTransfer(); - - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - let ret = JSON.parse((await chaincodeStub.getState(asset.ID)).toString()); - expect(ret).to.eql(asset); - }); - }); - - describe('Test ReadAsset', () => { - it('should return error on ReadAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - try { - await assetTransfer.ReadAsset(transactionContext, 'asset2'); - assert.fail('ReadAsset should have failed'); - } catch (err) { - expect(err.message).to.equal('The asset asset2 does not exist'); - } - }); - - it('should return success on ReadAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - let ret = JSON.parse(await chaincodeStub.getState(asset.ID)); - expect(ret).to.eql(asset); - }); - }); - - describe('Test UpdateAsset', () => { - it('should return error on UpdateAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - try { - await assetTransfer.UpdateAsset(transactionContext, 'asset2', 'orange', 10, 'Me', 500); - assert.fail('UpdateAsset should have failed'); - } catch (err) { - expect(err.message).to.equal('The asset asset2 does not exist'); - } - }); - - it('should return success on UpdateAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - await assetTransfer.UpdateAsset(transactionContext, 'asset1', 'orange', 10, 'Me', 500); - let ret = JSON.parse(await chaincodeStub.getState(asset.ID)); - let expected = { - ID: 'asset1', - Color: 'orange', - Size: 10, - Owner: 'Me', - AppraisedValue: 500 - }; - expect(ret).to.eql(expected); - }); - }); - - describe('Test DeleteAsset', () => { - it('should return error on DeleteAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - try { - await assetTransfer.DeleteAsset(transactionContext, 'asset2'); - assert.fail('DeleteAsset should have failed'); - } catch (err) { - expect(err.message).to.equal('The asset asset2 does not exist'); - } - }); - - it('should return success on DeleteAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - await assetTransfer.DeleteAsset(transactionContext, asset.ID); - let ret = await chaincodeStub.getState(asset.ID); - expect(ret).to.equal(undefined); - }); - }); - - describe('Test TransferAsset', () => { - it('should return error on TransferAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - try { - await assetTransfer.TransferAsset(transactionContext, 'asset2', 'Me'); - assert.fail('DeleteAsset should have failed'); - } catch (err) { - expect(err.message).to.equal('The asset asset2 does not exist'); - } - }); - - it('should return success on TransferAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - await assetTransfer.TransferAsset(transactionContext, asset.ID, 'Me'); - let ret = JSON.parse((await chaincodeStub.getState(asset.ID)).toString()); - expect(ret).to.eql(Object.assign({}, asset, {Owner: 'Me'})); - }); - }); - - describe('Test GetAllAssets', () => { - it('should return success on GetAllAssets', async () => { - let assetTransfer = new AssetTransfer(); - - await assetTransfer.CreateAsset(transactionContext, 'asset1', 'blue', 5, 'Robert', 100); - await assetTransfer.CreateAsset(transactionContext, 'asset2', 'orange', 10, 'Paul', 200); - await assetTransfer.CreateAsset(transactionContext, 'asset3', 'red', 15, 'Troy', 300); - await assetTransfer.CreateAsset(transactionContext, 'asset4', 'pink', 20, 'Van', 400); - - let ret = await assetTransfer.GetAllAssets(transactionContext); - ret = JSON.parse(ret); - expect(ret.length).to.equal(4); - - let expected = [ - {ID: 'asset1', Color: 'blue', Size: 5, Owner: 'Robert', AppraisedValue: 100}, - {ID: 'asset2', Color: 'orange', Size: 10, Owner: 'Paul', AppraisedValue: 200}, - {ID: 'asset3', Color: 'red', Size: 15, Owner: 'Troy', AppraisedValue: 300}, - {ID: 'asset4', Color: 'pink', Size: 20, Owner: 'Van', AppraisedValue: 400} - ]; - - expect(ret).to.eql(expected); - }); - - it('should return success on GetAllAssets for non JSON value', async () => { - let assetTransfer = new AssetTransfer(); - - chaincodeStub.putState.onFirstCall().callsFake((key, value) => { - if (!chaincodeStub.states) { - chaincodeStub.states = {}; - } - chaincodeStub.states[key] = 'non-json-value'; - }); - - await assetTransfer.CreateAsset(transactionContext, 'asset1', 'blue', 5, 'Robert', 100); - await assetTransfer.CreateAsset(transactionContext, 'asset2', 'orange', 10, 'Paul', 200); - await assetTransfer.CreateAsset(transactionContext, 'asset3', 'red', 15, 'Troy', 300); - await assetTransfer.CreateAsset(transactionContext, 'asset4', 'pink', 20, 'Van', 400); - - let ret = await assetTransfer.GetAllAssets(transactionContext); - ret = JSON.parse(ret); - expect(ret.length).to.equal(4); - - let expected = [ - 'non-json-value', - {ID: 'asset2', Color: 'orange', Size: 10, Owner: 'Paul', AppraisedValue: 200}, - {ID: 'asset3', Color: 'red', Size: 15, Owner: 'Troy', AppraisedValue: 300}, - {ID: 'asset4', Color: 'pink', Size: 20, Owner: 'Van', AppraisedValue: 400} - ]; - - expect(ret).to.eql(expected); - }); - }); -}); diff --git a/asset-transfer-basic/chaincode-typescript/src/asset.ts b/asset-transfer-basic/chaincode-typescript/src/asset.ts deleted file mode 100644 index 8845ab03..00000000 --- a/asset-transfer-basic/chaincode-typescript/src/asset.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - SPDX-License-Identifier: Apache-2.0 -*/ - -import {Object, Property} from 'fabric-contract-api'; - -@Object() -export class Asset { - @Property() - public docType?: string; - - @Property() - public ID: string = ''; - - @Property() - public Color: string = ''; - - @Property() - public Size: number = 0; - - @Property() - public Owner: string = ''; - - @Property() - public AppraisedValue: number = 0; -} diff --git a/asset-transfer-basic/chaincode-typescript/src/assetTransfer.ts b/asset-transfer-basic/chaincode-typescript/src/assetTransfer.ts deleted file mode 100644 index d3ed927a..00000000 --- a/asset-transfer-basic/chaincode-typescript/src/assetTransfer.ts +++ /dev/null @@ -1,173 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ -// Deterministic JSON.stringify() -import {Context, Contract, Info, Returns, Transaction} from 'fabric-contract-api'; -import stringify from 'json-stringify-deterministic'; -import sortKeysRecursive from 'sort-keys-recursive'; -import {Asset} from './asset'; - -@Info({title: 'AssetTransfer', description: 'Smart contract for trading assets'}) -export class AssetTransferContract extends Contract { - - @Transaction() - public async InitLedger(ctx: Context): Promise { - const assets: Asset[] = [ - { - ID: 'asset1', - Color: 'blue', - Size: 5, - Owner: 'Tomoko', - AppraisedValue: 300, - }, - { - ID: 'asset2', - Color: 'red', - Size: 5, - Owner: 'Brad', - AppraisedValue: 400, - }, - { - ID: 'asset3', - Color: 'green', - Size: 10, - Owner: 'Jin Soo', - AppraisedValue: 500, - }, - { - ID: 'asset4', - Color: 'yellow', - Size: 10, - Owner: 'Max', - AppraisedValue: 600, - }, - { - ID: 'asset5', - Color: 'black', - Size: 15, - Owner: 'Adriana', - AppraisedValue: 700, - }, - { - ID: 'asset6', - Color: 'white', - Size: 15, - Owner: 'Michel', - AppraisedValue: 800, - }, - ]; - - for (const asset of assets) { - asset.docType = 'asset'; - // example of how to write to world state deterministically - // use convetion of alphabetic order - // we insert data in alphabetic order using 'json-stringify-deterministic' and 'sort-keys-recursive' - // when retrieving data, in any lang, the order of data will be the same and consequently also the corresonding hash - await ctx.stub.putState(asset.ID, Buffer.from(stringify(sortKeysRecursive(asset)))); - console.info(`Asset ${asset.ID} initialized`); - } - } - - // CreateAsset issues a new asset to the world state with given details. - @Transaction() - public async CreateAsset(ctx: Context, id: string, color: string, size: number, owner: string, appraisedValue: number): Promise { - const exists = await this.AssetExists(ctx, id); - if (exists) { - throw new Error(`The asset ${id} already exists`); - } - - const asset = { - ID: id, - Color: color, - Size: size, - Owner: owner, - AppraisedValue: appraisedValue, - }; - // we insert data in alphabetic order using 'json-stringify-deterministic' and 'sort-keys-recursive' - await ctx.stub.putState(id, Buffer.from(stringify(sortKeysRecursive(asset)))); - } - - // ReadAsset returns the asset stored in the world state with given id. - @Transaction(false) - public async ReadAsset(ctx: Context, id: string): Promise { - const assetJSON = await ctx.stub.getState(id); // get the asset from chaincode state - if (assetJSON.length === 0) { - throw new Error(`The asset ${id} does not exist`); - } - return assetJSON.toString(); - } - - // UpdateAsset updates an existing asset in the world state with provided parameters. - @Transaction() - public async UpdateAsset(ctx: Context, id: string, color: string, size: number, owner: string, appraisedValue: number): Promise { - const exists = await this.AssetExists(ctx, id); - if (!exists) { - throw new Error(`The asset ${id} does not exist`); - } - - // overwriting original asset with new asset - const updatedAsset = { - ID: id, - Color: color, - Size: size, - Owner: owner, - AppraisedValue: appraisedValue, - }; - // we insert data in alphabetic order using 'json-stringify-deterministic' and 'sort-keys-recursive' - return ctx.stub.putState(id, Buffer.from(stringify(sortKeysRecursive(updatedAsset)))); - } - - // DeleteAsset deletes an given asset from the world state. - @Transaction() - public async DeleteAsset(ctx: Context, id: string): Promise { - const exists = await this.AssetExists(ctx, id); - if (!exists) { - throw new Error(`The asset ${id} does not exist`); - } - return ctx.stub.deleteState(id); - } - - // AssetExists returns true when asset with given ID exists in world state. - @Transaction(false) - @Returns('boolean') - public async AssetExists(ctx: Context, id: string): Promise { - const assetJSON = await ctx.stub.getState(id); - return assetJSON.length > 0; - } - - // TransferAsset updates the owner field of asset with given id in the world state, and returns the old owner. - @Transaction() - public async TransferAsset(ctx: Context, id: string, newOwner: string): Promise { - const assetString = await this.ReadAsset(ctx, id); - const asset = JSON.parse(assetString) as Asset; - const oldOwner = asset.Owner; - asset.Owner = newOwner; - // we insert data in alphabetic order using 'json-stringify-deterministic' and 'sort-keys-recursive' - await ctx.stub.putState(id, Buffer.from(stringify(sortKeysRecursive(asset)))); - return oldOwner; - } - - // GetAllAssets returns all assets found in the world state. - @Transaction(false) - @Returns('string') - public async GetAllAssets(ctx: Context): Promise { - const allResults = []; - // range query with empty string for startKey and endKey does an open-ended query of all assets in the chaincode namespace. - const iterator = await ctx.stub.getStateByRange('', ''); - let result = await iterator.next(); - while (!result.done) { - const strValue = Buffer.from(result.value.value.toString()).toString('utf8'); - let record; - try { - record = JSON.parse(strValue) as Asset; - } catch (err) { - console.log(err); - record = strValue; - } - allResults.push(record); - result = await iterator.next(); - } - return JSON.stringify(allResults); - } - -} diff --git a/asset-transfer-basic/chaincode-typescript/src/assetTransferCustom.ts b/asset-transfer-basic/chaincode-typescript/src/assetTransferCustom.ts new file mode 100644 index 00000000..40d8fcd9 --- /dev/null +++ b/asset-transfer-basic/chaincode-typescript/src/assetTransferCustom.ts @@ -0,0 +1,253 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ +// Deterministic JSON.stringify() +import {Context, Contract, Info, Returns, Transaction} from 'fabric-contract-api'; +import stringify from 'json-stringify-deterministic'; +import sortKeysRecursive from 'sort-keys-recursive'; +import {Asset, Student, Department, Certificate} from './customAsset'; +import { createHash } from 'node:crypto'; + +@Info({title: 'AssetTransfer', description: 'Smart contract for trading assets'}) +export class AssetTransferCustomContract extends Contract { + + @Transaction() + public async InitLedger(ctx: Context): Promise { + const assets: Student[] = []; + + for (const asset of assets) { + asset.docType = 'asset'; + // example of how to write to world state deterministically + // use convetion of alphabetic order + // we insert data in alphabetic order using 'json-stringify-deterministic' and 'sort-keys-recursive' + // when retrieving data, in any lang, the order of data will be the same and consequently also the corresonding hash + await ctx.stub.putState(asset.RollNo, Buffer.from(stringify(sortKeysRecursive(asset)))); + console.info(`Asset ${asset.RollNo} initialized`); + } + } + + // ReadAsset returns the asset stored in the world state with given id. + @Transaction(false) + public async ReadAsset(ctx: Context, id: string): Promise { + const assetJSON = await ctx.stub.getState(id); // get the asset from chaincode state + if (assetJSON.length === 0) { + throw new Error(`The asset ${id} does not exist`); + } + return assetJSON.toString(); + } + + + // DeleteAsset deletes an given asset from the world state. + @Transaction() + public async DeleteAsset(ctx: Context, id: string): Promise { + const exists = await this.AssetExists(ctx, id); + if (!exists) { + throw new Error(`The asset ${id} does not exist`); + } + return ctx.stub.deleteState(id); + } + + // AssetExists returns true when asset with given ID exists in world state. + @Transaction(false) + @Returns('boolean') + public async AssetExists(ctx: Context, id: string): Promise { + const assetJSON = await ctx.stub.getState(id); + return assetJSON.length > 0; + } + + // GetAllAssets returns all assets found in the world state. + @Transaction(false) + @Returns('string') + public async GetAllAssets(ctx: Context): Promise { + const allResults = []; + // range query with empty string for startKey and endKey does an open-ended query of all assets in the chaincode namespace. + const iterator = await ctx.stub.getStateByRange('', ''); + let result = await iterator.next(); + while (!result.done) { + const strValue = Buffer.from(result.value.value.toString()).toString('utf8'); + let record; + try { + record = JSON.parse(strValue) as Asset; + } catch (err) { + console.log(err); + record = strValue; + } + allResults.push(record); + result = await iterator.next(); + } + return JSON.stringify(allResults); + } + + @Transaction() + public async CreateStudentData(ctx: Context, rollNo:string, name:string): Promise { + const exists = await this.AssetExists(ctx, "Studenet"+rollNo); + if (exists) { + throw new Error(`The asset ${rollNo} already exists`); + } + + const asset: Student = { + ID: 'Student' + rollNo, + docType: 'Student', + RollNo: rollNo, + Name: name, + Marks: {}, + DepartmentID: '' + }; + + await ctx.stub.putState(asset.ID, Buffer.from(stringify(sortKeysRecursive(asset)))); + } + + @Transaction() + public async CreateDept(ctx: Context, deptName:string, year:number): Promise { + const exists = await this.AssetExists(ctx, 'Department'+deptName + year); + if (exists) { + throw new Error(`The asset ${deptName + year} already exists`); + } + + const department: Department = { + ID: 'Department' + deptName + year, + docType: 'Department', + DeptID: deptName + year, + DeptName: deptName, + Year: year, + Subject: [], + RollNos: [] + }; + + await ctx.stub.putState(department.ID, Buffer.from(stringify(sortKeysRecursive(department)))); + } + + @Transaction() + public async deptAddSubject(ctx: Context, deptID:string, subject:string): Promise { + const exists = await this.AssetExists(ctx,"Department"+ deptID); + if (!exists) { + throw new Error(`The asset ${deptID} already exists`); + } + + const dept: Department = JSON.parse(await this.ReadAsset(ctx,"Department"+ deptID)); + + const new_dept: Department = { + ID: dept.ID, + docType: dept.docType, + DeptID: dept.DeptID, + DeptName: dept.DeptName, + Subject: [...dept.Subject, subject], + RollNos: dept.RollNos, + Year: dept.Year + }; + + await ctx.stub.putState(new_dept.ID, Buffer.from(stringify(sortKeysRecursive(new_dept)))); + + } + + @Transaction() + public async deptAddStudent(ctx: Context, deptID:string, rollNo:string): Promise { + const exists = await this.AssetExists(ctx,"Department"+ deptID); + if (!exists) { + throw new Error(`The Department ${deptID} doesnt exists`); + } + + const dept: Department = JSON.parse(await this.ReadAsset(ctx,"Department"+deptID)); + const student: Student = JSON.parse(await this.ReadAsset(ctx, "Student"+rollNo)) + + const new_stud: Student = { + ID: student.ID, + docType: student.docType, + RollNo: student.RollNo, + Name: student.Name, + DepartmentID: deptID, + Marks: student.Marks + } + + const new_dept: Department = { + ID: dept.ID, + docType: dept.docType, + DeptID: dept.DeptID, + DeptName: dept.DeptName, + Subject: dept.Subject, + RollNos: [...dept.RollNos,rollNo], + Year: dept.Year + }; + + await ctx.stub.putState(new_stud.ID, Buffer.from(stringify(sortKeysRecursive(new_dept)))); + await ctx.stub.putState(new_dept.ID, Buffer.from(stringify(sortKeysRecursive(new_dept)))); + } + + @Transaction() + public async addStudentMark(ctx: Context, rollNo: string, subjectG: string, mark: number): Promise { + const exists = await this.AssetExists(ctx,"Student" + rollNo); + if (!exists) { + throw new Error(`The asset ${rollNo} already exists`); + } + + const student: Student = JSON.parse(await this.ReadAsset(ctx,"Student"+ rollNo)); + + ctx.clientIdentity.assertAttributeValue + + const newStudent: Student = { + ID: student.ID, + docType: student.docType, + RollNo: student.RollNo, + Name: student.Name, + Marks: {...student.Marks,[subjectG] : mark}, + DepartmentID: student.DepartmentID + }; + + await ctx.stub.putState(newStudent.ID, Buffer.from(stringify(sortKeysRecursive(newStudent)))); + } + + @Transaction(false) + public async getStudent(ctx: Context, rollNo: string) + { + const exists = await this.AssetExists(ctx, "Student"+rollNo); + if (!exists) { + throw new Error(`The asset doest exists`); + } + const student = await this.ReadAsset(ctx,"Student"+rollNo); + + return JSON.stringify(student) + + } + + @Transaction() + public async addCertificate(ctx: Context, name: string, event: string, links: string): Promise { + + const hash = createHash('sha256') + + hash.update(name+event+links) + + const hashStr: string = hash.copy().digest('hex'); + + const exists = await this.AssetExists(ctx,"Certificate" + hashStr); + if (exists) { + throw new Error(`The asset ${hashStr} already exists`); + } + + + const newCertificate: Certificate = { + ID: 'Certificate' + hashStr, + Name: name, + Event: event, + Links: links, + docType: 'Certificate' + } + + + await ctx.stub.putState(newCertificate.ID, Buffer.from(stringify(sortKeysRecursive(newCertificate)))); + + return hashStr; + } + + @Transaction(false) + public async validateCertificate(ctx: Context, hashStr: string): Promise { + const assetJSON = await ctx.stub.getState('Certificate'+hashStr); // get the asset from chaincode state + if (assetJSON.length === 0) { + throw new Error(`The Certificate does not exist`); + } + return assetJSON.toString(); + } + + + + +} diff --git a/asset-transfer-basic/chaincode-typescript/src/customAsset.ts b/asset-transfer-basic/chaincode-typescript/src/customAsset.ts new file mode 100644 index 00000000..cd60cae7 --- /dev/null +++ b/asset-transfer-basic/chaincode-typescript/src/customAsset.ts @@ -0,0 +1,90 @@ +/* + SPDX-License-Identifier: Apache-2.0 +*/ + +import {Object, Property} from 'fabric-contract-api'; + +@Object() +export class Asset { + @Property() + public docType?: string; + + @Property() + public ID: string = ''; + + @Property() + public Name:string = ''; + + @Property() + public DOB: string = ''; + + @Property() + public Marks: number = 0; +} + + +@Object() +export class Student{ + + @Property() + public ID: string = ''; + + @Property() + public docType:string = 'Student'; + + @Property() + public RollNo: string = ''; + + @Property() + public Name: string = ''; + + @Property() + public Marks: object = {}; + + @Property() + public DepartmentID:string = ''; +} + +@Object() +export class Department{ + + @Property() + public ID: string = ''; + + @Property() + public docType:string = 'Department'; + + @Property() + public DeptID: string = ''; + + @Property() + public DeptName: string = ''; + + @Property() + public Year: number = 0; + + @Property() + public Subject: string[] = []; + + @Property() + public RollNos: string[] = []; +} + +@Object() +export class Certificate{ + + @Property() + public ID: string = ''; + + @Property() + public docType:string = 'Certificate'; + + @Property() + public Name:string = ''; + + @Property() + public Event:string = ''; + + @Property() + public Links:string = ''; +} diff --git a/asset-transfer-basic/chaincode-typescript/src/index.ts b/asset-transfer-basic/chaincode-typescript/src/index.ts index 87166997..7d6a6914 100644 --- a/asset-transfer-basic/chaincode-typescript/src/index.ts +++ b/asset-transfer-basic/chaincode-typescript/src/index.ts @@ -3,6 +3,6 @@ */ import {type Contract} from 'fabric-contract-api'; -import {AssetTransferContract} from './assetTransfer'; +import {AssetTransferCustomContract} from './assetTransferCustom'; -export const contracts: typeof Contract[] = [AssetTransferContract]; +export const contracts: typeof Contract[] = [AssetTransferCustomContract]; diff --git a/asset-transfer-basic/rest-api-go/.gitignore b/asset-transfer-basic/rest-api-go/.gitignore deleted file mode 100644 index b264572c..00000000 --- a/asset-transfer-basic/rest-api-go/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -Requests.http -rest-api-go \ No newline at end of file diff --git a/asset-transfer-basic/rest-api-go/README.md b/asset-transfer-basic/rest-api-go/README.md deleted file mode 100644 index 331411b7..00000000 --- a/asset-transfer-basic/rest-api-go/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Asset Transfer REST API Sample - -This is a simple REST server written in golang with endpoints for chaincode invoke and query. - - -## Usage - -- Setup fabric test network and deploy the asset transfer chaincode by [following this instructions](https://hyperledger-fabric.readthedocs.io/en/release-2.4/test_network.html). - -- cd into rest-api-go directory -- Download required dependencies using `go mod download` -- Run `go run main.go` to run the REST server - -## Sending Requests - -Invoke endpoint accepts POST requests with chaincode function and arguments. Query endpoint accepts get requests with chaincode function and arguments. - -Sample chaincode invoke for the "createAsset" function. Response will contain transaction ID for a successful invoke. - -``` sh -curl --request POST \ - --url http://localhost:3000/invoke \ - --header 'content-type: application/x-www-form-urlencoded' \ - --data = \ - --data channelid=mychannel \ - --data chaincodeid=basic \ - --data function=createAsset \ - --data args=Asset123 \ - --data args=yellow \ - --data args=54 \ - --data args=Tom \ - --data args=13005 -``` -Sample chaincode query for getting asset details. - -``` sh -curl --request GET \ - --url 'http://localhost:3000/query?channelid=mychannel&chaincodeid=basic&function=ReadAsset&args=Asset123' - ``` diff --git a/asset-transfer-basic/rest-api-go/go.mod b/asset-transfer-basic/rest-api-go/go.mod deleted file mode 100644 index 8324149c..00000000 --- a/asset-transfer-basic/rest-api-go/go.mod +++ /dev/null @@ -1,19 +0,0 @@ -module rest-api-go - -go 1.22.0 - -require ( - github.com/hyperledger/fabric-gateway v1.7.0 - google.golang.org/grpc v1.67.1 -) - -require ( - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 // indirect - github.com/miekg/pkcs11 v1.1.1 // indirect - golang.org/x/crypto v0.28.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/protobuf v1.35.1 // indirect -) diff --git a/asset-transfer-basic/rest-api-go/go.sum b/asset-transfer-basic/rest-api-go/go.sum deleted file mode 100644 index 01eab6a8..00000000 --- a/asset-transfer-basic/rest-api-go/go.sum +++ /dev/null @@ -1,32 +0,0 @@ -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-gateway v1.7.0 h1:bd1quU8qYPYqYO69m1tPIDSjB+D+u/rBJfE1eWFcpjY= -github.com/hyperledger/fabric-gateway v1.7.0/go.mod h1:TItDGnq71eJcgz5TW+m5Sq3kWGp0AEI1HPCNxj0Eu7k= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= -github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/asset-transfer-basic/rest-api-go/main.go b/asset-transfer-basic/rest-api-go/main.go deleted file mode 100644 index ff349991..00000000 --- a/asset-transfer-basic/rest-api-go/main.go +++ /dev/null @@ -1,26 +0,0 @@ -package main - -import ( - "fmt" - "rest-api-go/web" -) - -func main() { - //Initialize setup for Org1 - cryptoPath := "../../test-network/organizations/peerOrganizations/org1.example.com" - orgConfig := web.OrgSetup{ - OrgName: "Org1", - MSPID: "Org1MSP", - CertPath: cryptoPath + "/users/User1@org1.example.com/msp/signcerts/cert.pem", - KeyPath: cryptoPath + "/users/User1@org1.example.com/msp/keystore/", - TLSCertPath: cryptoPath + "/peers/peer0.org1.example.com/tls/ca.crt", - PeerEndpoint: "dns:///localhost:7051", - GatewayPeer: "peer0.org1.example.com", - } - - orgSetup, err := web.Initialize(orgConfig) - if err != nil { - fmt.Println("Error initializing setup for Org1: ", err) - } - web.Serve(web.OrgSetup(*orgSetup)) -} diff --git a/asset-transfer-basic/rest-api-go/web/app.go b/asset-transfer-basic/rest-api-go/web/app.go deleted file mode 100644 index b8d8c1b3..00000000 --- a/asset-transfer-basic/rest-api-go/web/app.go +++ /dev/null @@ -1,31 +0,0 @@ -package web - -import ( - "fmt" - "net/http" - - "github.com/hyperledger/fabric-gateway/pkg/client" -) - -// OrgSetup contains organization's config to interact with the network. -type OrgSetup struct { - OrgName string - MSPID string - CryptoPath string - CertPath string - KeyPath string - TLSCertPath string - PeerEndpoint string - GatewayPeer string - Gateway client.Gateway -} - -// Serve starts http web server. -func Serve(setups OrgSetup) { - http.HandleFunc("/query", setups.Query) - http.HandleFunc("/invoke", setups.Invoke) - fmt.Println("Listening (http://localhost:3000/)...") - if err := http.ListenAndServe(":3000", nil); err != nil { - fmt.Println(err) - } -} diff --git a/asset-transfer-basic/rest-api-go/web/initialize.go b/asset-transfer-basic/rest-api-go/web/initialize.go deleted file mode 100644 index a14d1b15..00000000 --- a/asset-transfer-basic/rest-api-go/web/initialize.go +++ /dev/null @@ -1,108 +0,0 @@ -package web - -import ( - "crypto/x509" - "fmt" - "log" - "os" - "path" - "time" - - "github.com/hyperledger/fabric-gateway/pkg/client" - "github.com/hyperledger/fabric-gateway/pkg/hash" - "github.com/hyperledger/fabric-gateway/pkg/identity" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" -) - -// Initialize the setup for the organization. -func Initialize(setup OrgSetup) (*OrgSetup, error) { - log.Printf("Initializing connection for %s...\n", setup.OrgName) - clientConnection := setup.newGrpcConnection() - id := setup.newIdentity() - sign := setup.newSign() - - gateway, err := client.Connect( - id, - client.WithSign(sign), - client.WithHash(hash.SHA256), - client.WithClientConnection(clientConnection), - client.WithEvaluateTimeout(5*time.Second), - client.WithEndorseTimeout(15*time.Second), - client.WithSubmitTimeout(5*time.Second), - client.WithCommitStatusTimeout(1*time.Minute), - ) - if err != nil { - panic(err) - } - setup.Gateway = *gateway - log.Println("Initialization complete") - return &setup, nil -} - -// newGrpcConnection creates a gRPC connection to the Gateway server. -func (setup OrgSetup) newGrpcConnection() *grpc.ClientConn { - certificate, err := loadCertificate(setup.TLSCertPath) - if err != nil { - panic(err) - } - - certPool := x509.NewCertPool() - certPool.AddCert(certificate) - transportCredentials := credentials.NewClientTLSFromCert(certPool, setup.GatewayPeer) - - connection, err := grpc.NewClient(setup.PeerEndpoint, grpc.WithTransportCredentials(transportCredentials)) - if err != nil { - panic(fmt.Errorf("failed to create gRPC connection: %w", err)) - } - - return connection -} - -// newIdentity creates a client identity for this Gateway connection using an X.509 certificate. -func (setup OrgSetup) newIdentity() *identity.X509Identity { - certificate, err := loadCertificate(setup.CertPath) - if err != nil { - panic(err) - } - - id, err := identity.NewX509Identity(setup.MSPID, certificate) - if err != nil { - panic(err) - } - - return id -} - -// newSign creates a function that generates a digital signature from a message digest using a private key. -func (setup OrgSetup) newSign() identity.Sign { - files, err := os.ReadDir(setup.KeyPath) - if err != nil { - panic(fmt.Errorf("failed to read private key directory: %w", err)) - } - privateKeyPEM, err := os.ReadFile(path.Join(setup.KeyPath, files[0].Name())) - - if err != nil { - panic(fmt.Errorf("failed to read private key file: %w", err)) - } - - privateKey, err := identity.PrivateKeyFromPEM(privateKeyPEM) - if err != nil { - panic(err) - } - - sign, err := identity.NewPrivateKeySign(privateKey) - if err != nil { - panic(err) - } - - return sign -} - -func loadCertificate(filename string) (*x509.Certificate, error) { - certificatePEM, err := os.ReadFile(filename) - if err != nil { - return nil, fmt.Errorf("failed to read certificate file: %w", err) - } - return identity.CertificateFromPEM(certificatePEM) -} diff --git a/asset-transfer-basic/rest-api-go/web/invoke.go b/asset-transfer-basic/rest-api-go/web/invoke.go deleted file mode 100644 index f2907d58..00000000 --- a/asset-transfer-basic/rest-api-go/web/invoke.go +++ /dev/null @@ -1,40 +0,0 @@ -package web - -import ( - "fmt" - "net/http" - - "github.com/hyperledger/fabric-gateway/pkg/client" -) - -// Invoke handles chaincode invoke requests. -func (setup *OrgSetup) Invoke(w http.ResponseWriter, r *http.Request) { - fmt.Println("Received Invoke request") - if err := r.ParseForm(); err != nil { - fmt.Fprintf(w, "ParseForm() err: %s", err) - return - } - chainCodeName := r.FormValue("chaincodeid") - channelID := r.FormValue("channelid") - function := r.FormValue("function") - args := r.Form["args"] - fmt.Printf("channel: %s, chaincode: %s, function: %s, args: %s\n", channelID, chainCodeName, function, args) - network := setup.Gateway.GetNetwork(channelID) - contract := network.GetContract(chainCodeName) - txn_proposal, err := contract.NewProposal(function, client.WithArguments(args...)) - if err != nil { - fmt.Fprintf(w, "Error creating txn proposal: %s", err) - return - } - txn_endorsed, err := txn_proposal.Endorse() - if err != nil { - fmt.Fprintf(w, "Error endorsing txn: %s", err) - return - } - txn_committed, err := txn_endorsed.Submit() - if err != nil { - fmt.Fprintf(w, "Error submitting transaction: %s", err) - return - } - fmt.Fprintf(w, "Transaction ID : %s Response: %s", txn_committed.TransactionID(), txn_endorsed.Result()) -} diff --git a/asset-transfer-basic/rest-api-go/web/query.go b/asset-transfer-basic/rest-api-go/web/query.go deleted file mode 100644 index eff1a70a..00000000 --- a/asset-transfer-basic/rest-api-go/web/query.go +++ /dev/null @@ -1,25 +0,0 @@ -package web - -import ( - "fmt" - "net/http" -) - -// Query handles chaincode query requests. -func (setup OrgSetup) Query(w http.ResponseWriter, r *http.Request) { - fmt.Println("Received Query request") - queryParams := r.URL.Query() - chainCodeName := queryParams.Get("chaincodeid") - channelID := queryParams.Get("channelid") - function := queryParams.Get("function") - args := r.URL.Query()["args"] - fmt.Printf("channel: %s, chaincode: %s, function: %s, args: %s\n", channelID, chainCodeName, function, args) - network := setup.Gateway.GetNetwork(channelID) - contract := network.GetContract(chainCodeName) - evaluateResponse, err := contract.EvaluateTransaction(function, args...) - if err != nil { - fmt.Fprintf(w, "Error: %s", err) - return - } - fmt.Fprintf(w, "Response: %s", evaluateResponse) -} diff --git a/asset-transfer-basic/rest-api-typescript/README.md b/asset-transfer-basic/rest-api-typescript/README.md index f5e0953a..0c0a5544 100644 --- a/asset-transfer-basic/rest-api-typescript/README.md +++ b/asset-transfer-basic/rest-api-typescript/README.md @@ -113,7 +113,7 @@ npm run build Create a `.env` file to configure the server for the test network (make sure TEST_NETWORK_HOME is set to the fully qualified `test-network` directory) ```shell -TEST_NETWORK_HOME=$HOME/fabric-samples/test-network npm run generateEnv +TEST_NETWORK_HOME=/home/calvin/go/src/github.com/delete_me0/sandbx/fabric-samples/test-network npm run generateEnv ``` **Note:** see [src/config.ts](src/config.ts) for details of configuring the sample diff --git a/asset-transfer-basic/rest-api-typescript/scripts/generateEnv.sh b/asset-transfer-basic/rest-api-typescript/scripts/generateEnv.sh index 626f84b9..f2af8107 100755 --- a/asset-transfer-basic/rest-api-typescript/scripts/generateEnv.sh +++ b/asset-transfer-basic/rest-api-typescript/scripts/generateEnv.sh @@ -8,12 +8,12 @@ ${AS_LOCAL_HOST:=true} : "${TEST_NETWORK_HOME:=../..}" : "${CONNECTION_PROFILE_FILE_ORG1:=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org1.example.com/connection-org1.json}" -: "${CERTIFICATE_FILE_ORG1:=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/User1@org1.example.com-cert.pem}" -: "${PRIVATE_KEY_FILE_ORG1:=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/priv_sk}" +: "${CERTIFICATE_FILE_ORG1:=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/*.pem}" +: "${PRIVATE_KEY_FILE_ORG1:=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/*_sk}" : "${CONNECTION_PROFILE_FILE_ORG2:=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org2.example.com/connection-org2.json}" -: "${CERTIFICATE_FILE_ORG2:=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp/signcerts/User1@org2.example.com-cert.pem}" -: "${PRIVATE_KEY_FILE_ORG2:=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp/keystore/priv_sk}" +: "${CERTIFICATE_FILE_ORG2:=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp/signcerts/*.pem}" +: "${PRIVATE_KEY_FILE_ORG2:=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp/keystore/*_sk}" cat << ENV_END > .env diff --git a/asset-transfer-basic/rest-api-typescript/src/assets.router.ts b/asset-transfer-basic/rest-api-typescript/src/assets.router.ts index 39cf66dd..c0714b6c 100644 --- a/asset-transfer-basic/rest-api-typescript/src/assets.router.ts +++ b/asset-transfer-basic/rest-api-typescript/src/assets.router.ts @@ -27,6 +27,7 @@ import { AssetNotFoundError } from './errors'; import { evatuateTransaction } from './fabric'; import { addSubmitTransactionJob } from './jobs'; import { logger } from './logger'; +import { createHash } from 'crypto'; const { ACCEPTED, BAD_REQUEST, INTERNAL_SERVER_ERROR, NOT_FOUND, OK } = StatusCodes; @@ -54,15 +55,11 @@ assetsRouter.get('/', async (req: Request, res: Response) => { }); } }); - assetsRouter.post( - '/', + '/student', body().isObject().withMessage('body must contain an asset object'), - body('ID', 'must be a string').notEmpty(), - body('Color', 'must be a string').notEmpty(), - body('Size', 'must be a number').isNumeric(), - body('Owner', 'must be a string').notEmpty(), - body('AppraisedValue', 'must be a number').isNumeric(), + body('RollNo', 'must be a string').notEmpty(), + body('Name', 'must be a string').notEmpty(), async (req: Request, res: Response) => { logger.debug(req.body, 'Create asset request received'); @@ -78,19 +75,16 @@ assetsRouter.post( } const mspId = req.user as string; - const assetId = req.body.ID; + const rollNo = req.body.RollNo; try { const submitQueue = req.app.locals.jobq as Queue; const jobId = await addSubmitTransactionJob( submitQueue, mspId, - 'CreateAsset', - assetId, - req.body.Color, - req.body.Size, - req.body.Owner, - req.body.AppraisedValue + 'CreateStudentData', + rollNo, + req.body.Name ); return res.status(ACCEPTED).json({ @@ -102,7 +96,7 @@ assetsRouter.post( logger.error( { err }, 'Error processing create asset request for asset ID %s', - assetId + rollNo ); return res.status(INTERNAL_SERVER_ERROR).json({ @@ -113,50 +107,6 @@ assetsRouter.post( } ); -assetsRouter.options('/:assetId', async (req: Request, res: Response) => { - const assetId = req.params.assetId; - logger.debug('Asset options request received for asset ID %s', assetId); - - try { - const mspId = req.user as string; - const contract = req.app.locals[mspId]?.assetContract as Contract; - - const data = await evatuateTransaction( - contract, - 'AssetExists', - assetId - ); - const exists = data.toString() === 'true'; - - if (exists) { - return res - .status(OK) - .set({ - Allow: 'DELETE,GET,OPTIONS,PATCH,PUT', - }) - .json({ - status: getReasonPhrase(OK), - timestamp: new Date().toISOString(), - }); - } else { - return res.status(NOT_FOUND).json({ - status: getReasonPhrase(NOT_FOUND), - timestamp: new Date().toISOString(), - }); - } - } catch (err) { - logger.error( - { err }, - 'Error processing asset options request for asset ID %s', - assetId - ); - return res.status(INTERNAL_SERVER_ERROR).json({ - status: getReasonPhrase(INTERNAL_SERVER_ERROR), - timestamp: new Date().toISOString(), - }); - } -}); - assetsRouter.get('/:assetId', async (req: Request, res: Response) => { const assetId = req.params.assetId; logger.debug('Read asset request received for asset ID %s', assetId); @@ -190,134 +140,6 @@ assetsRouter.get('/:assetId', async (req: Request, res: Response) => { } }); -assetsRouter.put( - '/:assetId', - body().isObject().withMessage('body must contain an asset object'), - body('ID', 'must be a string').notEmpty(), - body('Color', 'must be a string').notEmpty(), - body('Size', 'must be a number').isNumeric(), - body('Owner', 'must be a string').notEmpty(), - body('AppraisedValue', 'must be a number').isNumeric(), - async (req: Request, res: Response) => { - logger.debug(req.body, 'Update asset request received'); - - const errors = validationResult(req); - if (!errors.isEmpty()) { - return res.status(BAD_REQUEST).json({ - status: getReasonPhrase(BAD_REQUEST), - reason: 'VALIDATION_ERROR', - message: 'Invalid request body', - timestamp: new Date().toISOString(), - errors: errors.array(), - }); - } - - if (req.params.assetId != req.body.ID) { - return res.status(BAD_REQUEST).json({ - status: getReasonPhrase(BAD_REQUEST), - reason: 'ASSET_ID_MISMATCH', - message: 'Asset IDs must match', - timestamp: new Date().toISOString(), - }); - } - - const mspId = req.user as string; - const assetId = req.params.assetId; - - try { - const submitQueue = req.app.locals.jobq as Queue; - const jobId = await addSubmitTransactionJob( - submitQueue, - mspId, - 'UpdateAsset', - assetId, - req.body.color, - req.body.size, - req.body.owner, - req.body.appraisedValue - ); - - return res.status(ACCEPTED).json({ - status: getReasonPhrase(ACCEPTED), - jobId: jobId, - timestamp: new Date().toISOString(), - }); - } catch (err) { - logger.error( - { err }, - 'Error processing update asset request for asset ID %s', - assetId - ); - - return res.status(INTERNAL_SERVER_ERROR).json({ - status: getReasonPhrase(INTERNAL_SERVER_ERROR), - timestamp: new Date().toISOString(), - }); - } - } -); - -assetsRouter.patch( - '/:assetId', - body() - .isArray({ - min: 1, - max: 1, - }) - .withMessage( - 'body must contain an array with a single patch operation' - ), - body('*.op', "operation must be 'replace'").equals('replace'), - body('*.path', "path must be '/Owner'").equals('/Owner'), - body('*.value', 'must be a string').isString(), - async (req: Request, res: Response) => { - logger.debug(req.body, 'Transfer asset request received'); - - const errors = validationResult(req); - if (!errors.isEmpty()) { - return res.status(BAD_REQUEST).json({ - status: getReasonPhrase(BAD_REQUEST), - reason: 'VALIDATION_ERROR', - message: 'Invalid request body', - timestamp: new Date().toISOString(), - errors: errors.array(), - }); - } - - const mspId = req.user as string; - const assetId = req.params.assetId; - const newOwner = req.body[0].value; - - try { - const submitQueue = req.app.locals.jobq as Queue; - const jobId = await addSubmitTransactionJob( - submitQueue, - mspId, - 'TransferAsset', - assetId, - newOwner - ); - - return res.status(ACCEPTED).json({ - status: getReasonPhrase(ACCEPTED), - jobId: jobId, - timestamp: new Date().toISOString(), - }); - } catch (err) { - logger.error( - { err }, - 'Error processing update asset request for asset ID %s', - req.params.assetId - ); - - return res.status(INTERNAL_SERVER_ERROR).json({ - status: getReasonPhrase(INTERNAL_SERVER_ERROR), - timestamp: new Date().toISOString(), - }); - } - } -); - assetsRouter.delete('/:assetId', async (req: Request, res: Response) => { logger.debug(req.body, 'Delete asset request received'); @@ -351,3 +173,344 @@ assetsRouter.delete('/:assetId', async (req: Request, res: Response) => { }); } }); + +assetsRouter.post( + '/dept', + body().isObject().withMessage('body must contain an asset object'), + body('DeptName', 'must be a string').notEmpty(), + body('Year', 'must be a number').isNumeric(), + async (req: Request, res: Response) => { + logger.debug(req.body, 'Create asset request received'); + + const errors = validationResult(req); + if (!errors.isEmpty()) { + return res.status(BAD_REQUEST).json({ + status: getReasonPhrase(BAD_REQUEST), + reason: 'VALIDATION_ERROR', + message: 'Invalid request body', + timestamp: new Date().toISOString(), + errors: errors.array(), + }); + } + + const mspId = req.user as string; + const assetId = req.body.DeptName; + + try { + const submitQueue = req.app.locals.jobq as Queue; + const jobId = await addSubmitTransactionJob( + submitQueue, + mspId, + 'CreateDept', + assetId, + req.body.Year + ); + + return res.status(ACCEPTED).json({ + status: getReasonPhrase(ACCEPTED), + jobId: jobId, + timestamp: new Date().toISOString(), + }); + } catch (err) { + logger.error( + { err }, + 'Error processing create asset request for asset ID %s', + assetId + ); + + return res.status(INTERNAL_SERVER_ERROR).json({ + status: getReasonPhrase(INTERNAL_SERVER_ERROR), + timestamp: new Date().toISOString(), + }); + } + } +); + +assetsRouter.post( + '/sub', + body().isObject().withMessage('body must contain an asset object'), + body('DeptID', 'must be a string').notEmpty(), + body('Subject', 'must be a string').notEmpty(), + async (req: Request, res: Response) => { + logger.debug(req.body, 'Create asset request received'); + + const errors = validationResult(req); + if (!errors.isEmpty()) { + return res.status(BAD_REQUEST).json({ + status: getReasonPhrase(BAD_REQUEST), + reason: 'VALIDATION_ERROR', + message: 'Invalid request body', + timestamp: new Date().toISOString(), + errors: errors.array(), + }); + } + + const mspId = req.user as string; + const assetId = req.body.DeptID; + + try { + const submitQueue = req.app.locals.jobq as Queue; + const jobId = await addSubmitTransactionJob( + submitQueue, + mspId, + 'deptAddSubject', + assetId, + req.body.Subject + ); + + return res.status(ACCEPTED).json({ + status: getReasonPhrase(ACCEPTED), + jobId: jobId, + timestamp: new Date().toISOString(), + }); + } catch (err) { + logger.error( + { err }, + 'Error processing create asset request for asset ID %s', + assetId + ); + + return res.status(INTERNAL_SERVER_ERROR).json({ + status: getReasonPhrase(INTERNAL_SERVER_ERROR), + timestamp: new Date().toISOString(), + }); + } + } +); + +assetsRouter.post( + '/addstu', + body().isObject().withMessage('body must contain an asset object'), + body('DeptID', 'must be a string').notEmpty(), + body('RollNo', 'must be a string').notEmpty(), + async (req: Request, res: Response) => { + logger.debug(req.body, 'Create asset request received'); + + const errors = validationResult(req); + if (!errors.isEmpty()) { + return res.status(BAD_REQUEST).json({ + status: getReasonPhrase(BAD_REQUEST), + reason: 'VALIDATION_ERROR', + message: 'Invalid request body', + timestamp: new Date().toISOString(), + errors: errors.array(), + }); + } + + const mspId = req.user as string; + const assetId = req.body.DeptID; + + try { + const submitQueue = req.app.locals.jobq as Queue; + const jobId = await addSubmitTransactionJob( + submitQueue, + mspId, + 'deptAddStudent', + assetId, + req.body.RollNo + ); + + return res.status(ACCEPTED).json({ + status: getReasonPhrase(ACCEPTED), + jobId: jobId, + timestamp: new Date().toISOString(), + }); + } catch (err) { + logger.error( + { err }, + 'Error processing create asset request for asset ID %s', + assetId + ); + + return res.status(INTERNAL_SERVER_ERROR).json({ + status: getReasonPhrase(INTERNAL_SERVER_ERROR), + timestamp: new Date().toISOString(), + }); + } + } +); + +assetsRouter.post( + '/stuaddsub', + body().isObject().withMessage('body must contain an asset object'), + body('RollNo', 'must be a string').notEmpty(), + body('Subject', 'must be a string').notEmpty(), + body('Mark', 'must be a number').isNumeric(), + async (req: Request, res: Response) => { + logger.debug(req.body, 'Create asset request received'); + const errors = validationResult(req); + if (!errors.isEmpty()) { + return res.status(BAD_REQUEST).json({ + status: getReasonPhrase(BAD_REQUEST), + reason: 'VALIDATION_ERROR', + message: 'Invalid request body', + timestamp: new Date().toISOString(), + errors: errors.array(), + }); + } + + const mspId = req.user as string; + const assetId = req.body.RollNo; + + try { + const submitQueue = req.app.locals.jobq as Queue; + const jobId = await addSubmitTransactionJob( + submitQueue, + mspId, + 'addStudentMark', + assetId, + req.body.Subject, + req.body.Mark + ); + + return res.status(ACCEPTED).json({ + status: getReasonPhrase(ACCEPTED), + jobId: jobId, + timestamp: new Date().toISOString(), + }); + } catch (err) { + logger.error( + { err }, + 'Error processing create asset request for asset ID %s', + assetId + ); + + return res.status(INTERNAL_SERVER_ERROR).json({ + status: getReasonPhrase(INTERNAL_SERVER_ERROR), + timestamp: new Date().toISOString(), + }); + } + } +); + +assetsRouter.get('/student/:assetId', async (req: Request, res: Response) => { + const rollNo = req.params.assetId; + logger.debug('Read asset request received for asset ID %s', rollNo); + + try { + const mspId = req.user as string; + const contract = req.app.locals[mspId]?.assetContract as Contract; + + const data = await evatuateTransaction(contract, 'getStudent', rollNo); + const asset = JSON.parse(data.toString()); + + return res.status(OK).json(asset); + } catch (err) { + logger.error( + { err }, + 'Error processing read asset request for asset ID %s', + rollNo + ); + + if (err instanceof AssetNotFoundError) { + return res.status(NOT_FOUND).json({ + status: getReasonPhrase(NOT_FOUND), + timestamp: new Date().toISOString(), + }); + } + + return res.status(INTERNAL_SERVER_ERROR).json({ + status: getReasonPhrase(INTERNAL_SERVER_ERROR), + timestamp: new Date().toISOString(), + }); + } +}); + +assetsRouter.post( + '/certificate', + body().isObject().withMessage('body must contain an asset object'), + body('Name', 'must be a string').notEmpty(), + body('Event', 'must be a string').notEmpty(), + body('Links', 'must be a string').notEmpty(), + async (req: Request, res: Response) => { + logger.debug(req.body, 'Create asset request received'); + const errors = validationResult(req); + if (!errors.isEmpty()) { + return res.status(BAD_REQUEST).json({ + status: getReasonPhrase(BAD_REQUEST), + reason: 'VALIDATION_ERROR', + message: 'Invalid request body', + timestamp: new Date().toISOString(), + errors: errors.array(), + }); + } + + const mspId = req.user as string; + + try { + const submitQueue = req.app.locals.jobq as Queue; + const jobId = await addSubmitTransactionJob( + submitQueue, + mspId, + 'addCertificate', + req.body.Name, + req.body.Event, + req.body.Links + ); + + const hash = createHash('sha256'); + + hash.update(req.body.Name + req.body.Event + req.body.Links); + + const hashStr: string = hash.digest('hex'); + + return res.status(ACCEPTED).json({ + certificate_hash: hashStr, + job_id: jobId, + }); + } catch (err) { + logger.error( + { err }, + 'Error processing create asset request for asset ID %s', + req.body.Name + ); + + return res.status(INTERNAL_SERVER_ERROR).json({ + status: getReasonPhrase(INTERNAL_SERVER_ERROR), + timestamp: new Date().toISOString(), + }); + } + } +); + +assetsRouter.get( + '/certificate', + body().isObject().withMessage('body must contain an asset object'), + body('Hash', 'must be a string').notEmpty(), + async (req: Request, res: Response) => { + const hashStr = req.body.Hash; + logger.debug('Read asset request received for asset ID %s', hashStr); + + try { + const mspId = req.user as string; + const contract = req.app.locals[mspId]?.assetContract as Contract; + + const data = await evatuateTransaction( + contract, + 'validateCertificate', + hashStr + ); + const asset = JSON.parse(data.toString()); + + return res.status(OK).json(asset); + } catch (err) { + logger.error( + { err }, + 'Error processing read asset request for asset ID %s', + hashStr + ); + + if (err instanceof AssetNotFoundError) { + return res.status(NOT_FOUND).json({ + status: getReasonPhrase(NOT_FOUND), + timestamp: new Date().toISOString(), + }); + } + + return res.status(INTERNAL_SERVER_ERROR).json({ + status: getReasonPhrase(INTERNAL_SERVER_ERROR), + timestamp: new Date().toISOString(), + }); + } + } +); diff --git a/asset-transfer-basic/rest-api-typescript/src/server.ts b/asset-transfer-basic/rest-api-typescript/src/server.ts index 2d7d31bf..ae72ebe5 100644 --- a/asset-transfer-basic/rest-api-typescript/src/server.ts +++ b/asset-transfer-basic/rest-api-typescript/src/server.ts @@ -54,12 +54,15 @@ export const createServer = async (): Promise => { } if (process.env.NODE_ENV === 'test') { + app.use(cors()); // TBC } if (process.env.NODE_ENV === 'production') { + app.use(cors()); app.use(helmet()); } + app.use(cors()); app.use('/', healthRouter); app.use('/api/assets', authenticateApiKey, assetsRouter); diff --git a/asset-transfer-events/README.md b/asset-transfer-events/README.md deleted file mode 100644 index edfd1148..00000000 --- a/asset-transfer-events/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# Asset transfer events sample - -The asset transfer events sample demonstrates: - -- Emitting chaincode events from smart contract transaction functions. -- Receiving chaincode events in a client application. -- Replaying previous chaincode events in a client application. - -Events are published when a block is committed to the ledger. - -For more information about event services on per-channel basis, visit the -[Channel-based event service](https://hyperledger-fabric.readthedocs.io/en/latest/peer_event_services.html) -page in the Fabric documentation. - - -## About the sample - -This sample includes smart contract and application code in multiple languages. In a use-case similar to basic asset transfer (see [asset-transfer-basic](../asset-transfer-basic) folder) this sample shows sending and receiving of events during create / update / delete of an asset, and during transfer of an asset to a new owner. - -### Application - -Follow the execution flow in the client application code, and corresponding output on running the application. Pay attention to the sequence of: - -- Transaction invocations (console output like "**--> Submit transaction**"). -- Events received by the application (console output like "**<-- Chaincode event received**"). - -Notice that events will be received by the listener after the application code submits the transaction and it is committed to the ledger, but during other application activity unrelated to the event. - -### Smart Contract - -The smart contract (in folder `chaincode-xyz`) implements the following functions to support the application: - -- CreateAsset -- ReadAsset -- UpdateAsset -- DeleteAsset -- TransferAsset - -Note that the asset transfer implemented by the smart contract is a simplified scenario, without ownership validation, meant only to demonstrate the use of sending and receiving events. - -## Running the sample - -Like other samples, the Fabric test network is used to deploy and run this sample. Follow these steps in order: - -1. Create the test network and a channel (from the `test-network` folder). - ``` - ./network.sh up createChannel -c mychannel -ca - ``` - -1. Deploy one of the smart contract implementations (from the `test-network` folder). - ``` - # To deploy the Go chaincode implementation - ./network.sh deployCC -ccn events -ccp ../asset-transfer-events/chaincode-go/ -ccl go -ccep "OR('Org1MSP.peer','Org2MSP.peer')" - - # To deploy the JavaScript chaincode implementation - ./network.sh deployCC -ccn events -ccp ../asset-transfer-events/chaincode-javascript/ -ccl javascript -ccep "OR('Org1MSP.peer','Org2MSP.peer')" - - # To deploy the Java chaincode implementation - ./network.sh deployCC -ccn events -ccp ../asset-transfer-events/chaincode-java/ -ccl java -ccep "OR('Org1MSP.peer','Org2MSP.peer')" - ``` - -1. Run the application (from the `asset-transfer-events` folder). - ``` - # To run the Go sample application - cd application-gateway-go - go run . - - # To run the TypeScript sample application - cd application-gateway-typescript - npm install - npm start - - # To run the Java sample application - cd application-gateway-java - ./gradlew run - ``` - -## Clean up - -When you are finished, you can bring down the test network (from the `test-network` folder). The command will remove all the nodes of the test network, and delete any ledger data that you created. - -``` -./network.sh down -``` \ No newline at end of file diff --git a/asset-transfer-events/application-gateway-go/app.go b/asset-transfer-events/application-gateway-go/app.go deleted file mode 100755 index f4fc7a58..00000000 --- a/asset-transfer-events/application-gateway-go/app.go +++ /dev/null @@ -1,172 +0,0 @@ -/* -Copyright 2022 IBM All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "time" - - "github.com/hyperledger/fabric-gateway/pkg/client" - "github.com/hyperledger/fabric-gateway/pkg/hash" -) - -const ( - channelName = "mychannel" - chaincodeName = "events" -) - -var now = time.Now() -var assetID = fmt.Sprintf("asset%d", now.Unix()*1e3+int64(now.Nanosecond())/1e6) - -func main() { - clientConnection := newGrpcConnection() - defer clientConnection.Close() - - id := newIdentity() - sign := newSign() - - gateway, err := client.Connect( - id, - client.WithSign(sign), - client.WithHash(hash.SHA256), - client.WithClientConnection(clientConnection), - client.WithEvaluateTimeout(5*time.Second), - client.WithEndorseTimeout(15*time.Second), - client.WithSubmitTimeout(5*time.Second), - client.WithCommitStatusTimeout(1*time.Minute), - ) - if err != nil { - panic(err) - } - defer gateway.Close() - - network := gateway.GetNetwork(channelName) - contract := network.GetContract(chaincodeName) - - // Context used for event listening - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - // Listen for events emitted by subsequent transactions - startChaincodeEventListening(ctx, network) - - firstBlockNumber := createAsset(contract) - updateAsset(contract) - transferAsset(contract) - deleteAsset(contract) - - // Replay events from the block containing the first transaction - replayChaincodeEvents(ctx, network, firstBlockNumber) -} - -func startChaincodeEventListening(ctx context.Context, network *client.Network) { - fmt.Println("\n*** Start chaincode event listening") - - events, err := network.ChaincodeEvents(ctx, chaincodeName) - if err != nil { - panic(fmt.Errorf("failed to start chaincode event listening: %w", err)) - } - - go func() { - for event := range events { - asset := formatJSON(event.Payload) - fmt.Printf("\n<-- Chaincode event received: %s - %s\n", event.EventName, asset) - } - }() -} - -func formatJSON(data []byte) string { - var result bytes.Buffer - if err := json.Indent(&result, data, "", " "); err != nil { - panic(fmt.Errorf("failed to parse JSON: %w", err)) - } - return result.String() -} - -func createAsset(contract *client.Contract) uint64 { - fmt.Printf("\n--> Submit transaction: CreateAsset, %s owned by Sam with appraised value 100\n", assetID) - - _, commit, err := contract.SubmitAsync("CreateAsset", client.WithArguments(assetID, "blue", "10", "Sam", "100")) - if err != nil { - panic(fmt.Errorf("failed to submit transaction: %w", err)) - } - - status, err := commit.Status() - if err != nil { - panic(fmt.Errorf("failed to get transaction commit status: %w", err)) - } - - if !status.Successful { - panic(fmt.Errorf("failed to commit transaction with status code %v", status.Code)) - } - - fmt.Println("\n*** CreateAsset committed successfully") - - return status.BlockNumber -} - -func updateAsset(contract *client.Contract) { - fmt.Printf("\n--> Submit transaction: UpdateAsset, %s update appraised value to 200\n", assetID) - - _, err := contract.SubmitTransaction("UpdateAsset", assetID, "blue", "10", "Sam", "200") - if err != nil { - panic(fmt.Errorf("failed to submit transaction: %w", err)) - } - - fmt.Println("\n*** UpdateAsset committed successfully") -} - -func transferAsset(contract *client.Contract) { - fmt.Printf("\n--> Submit transaction: TransferAsset, %s to Mary\n", assetID) - - _, err := contract.SubmitTransaction("TransferAsset", assetID, "Mary") - if err != nil { - panic(fmt.Errorf("failed to submit transaction: %w", err)) - } - - fmt.Println("\n*** TransferAsset committed successfully") -} - -func deleteAsset(contract *client.Contract) { - fmt.Printf("\n--> Submit transaction: DeleteAsset, %s\n", assetID) - - _, err := contract.SubmitTransaction("DeleteAsset", assetID) - if err != nil { - panic(fmt.Errorf("failed to submit transaction: %w", err)) - } - - fmt.Println("\n*** DeleteAsset committed successfully") -} - -func replayChaincodeEvents(ctx context.Context, network *client.Network, startBlock uint64) { - fmt.Println("\n*** Start chaincode event replay") - - events, err := network.ChaincodeEvents(ctx, chaincodeName, client.WithStartBlock(startBlock)) - if err != nil { - panic(fmt.Errorf("failed to start chaincode event listening: %w", err)) - } - - for { - select { - case <-time.After(10 * time.Second): - panic(errors.New("timeout waiting for event replay")) - - case event := <-events: - asset := formatJSON(event.Payload) - fmt.Printf("\n<-- Chaincode event replayed: %s - %s\n", event.EventName, asset) - - if event.EventName == "DeleteAsset" { - // Reached the last submitted transaction so return to stop listening for events - return - } - } - } -} diff --git a/asset-transfer-events/application-gateway-go/connect.go b/asset-transfer-events/application-gateway-go/connect.go deleted file mode 100755 index 7b21d8b1..00000000 --- a/asset-transfer-events/application-gateway-go/connect.go +++ /dev/null @@ -1,114 +0,0 @@ -/* -Copyright 2022 IBM All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "crypto/x509" - "fmt" - "os" - "path" - - "github.com/hyperledger/fabric-gateway/pkg/identity" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" -) - -const ( - mspID = "Org1MSP" - cryptoPath = "../../test-network/organizations/peerOrganizations/org1.example.com" - certPath = cryptoPath + "/users/User1@org1.example.com/msp/signcerts" - keyPath = cryptoPath + "/users/User1@org1.example.com/msp/keystore" - tlsCertPath = cryptoPath + "/peers/peer0.org1.example.com/tls/ca.crt" - peerEndpoint = "dns:///localhost:7051" - gatewayPeer = "peer0.org1.example.com" -) - -// newGrpcConnection creates a gRPC connection to the Gateway server. -func newGrpcConnection() *grpc.ClientConn { - certificatePEM, err := os.ReadFile(tlsCertPath) - if err != nil { - panic(fmt.Errorf("failed to read TLS certifcate file: %w", err)) - } - - certificate, err := identity.CertificateFromPEM(certificatePEM) - if err != nil { - panic(err) - } - - certPool := x509.NewCertPool() - certPool.AddCert(certificate) - transportCredentials := credentials.NewClientTLSFromCert(certPool, gatewayPeer) - - connection, err := grpc.NewClient(peerEndpoint, grpc.WithTransportCredentials(transportCredentials)) - if err != nil { - panic(fmt.Errorf("failed to create gRPC connection: %w", err)) - } - - return connection -} - -// newIdentity creates a client identity for this Gateway connection using an X.509 certificate. -func newIdentity() *identity.X509Identity { - certificatePEM, err := readFirstFile(certPath) - if err != nil { - panic(fmt.Errorf("failed to read certificate file: %w", err)) - } - - certificate, err := identity.CertificateFromPEM(certificatePEM) - if err != nil { - panic(err) - } - - id, err := identity.NewX509Identity(mspID, certificate) - if err != nil { - panic(err) - } - - return id -} - -func loadCertificate(filename string) (*x509.Certificate, error) { - certificatePEM, err := os.ReadFile(filename) - if err != nil { - return nil, fmt.Errorf("failed to read certificate file: %w", err) - } - return identity.CertificateFromPEM(certificatePEM) -} - -// newSign creates a function that generates a digital signature from a message digest using a private key. -func newSign() identity.Sign { - privateKeyPEM, err := readFirstFile(keyPath) - if err != nil { - panic(fmt.Errorf("failed to read private key file: %w", err)) - } - - privateKey, err := identity.PrivateKeyFromPEM(privateKeyPEM) - if err != nil { - panic(err) - } - - sign, err := identity.NewPrivateKeySign(privateKey) - if err != nil { - panic(err) - } - - return sign -} - -func readFirstFile(dirPath string) ([]byte, error) { - dir, err := os.Open(dirPath) - if err != nil { - return nil, err - } - - fileNames, err := dir.Readdirnames(1) - if err != nil { - return nil, err - } - - return os.ReadFile(path.Join(dirPath, fileNames[0])) -} diff --git a/asset-transfer-events/application-gateway-go/go.mod b/asset-transfer-events/application-gateway-go/go.mod deleted file mode 100644 index 65128cfd..00000000 --- a/asset-transfer-events/application-gateway-go/go.mod +++ /dev/null @@ -1,19 +0,0 @@ -module assetTransfer - -go 1.22.0 - -require ( - github.com/hyperledger/fabric-gateway v1.7.0 - google.golang.org/grpc v1.67.1 -) - -require ( - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 // indirect - github.com/miekg/pkcs11 v1.1.1 // indirect - golang.org/x/crypto v0.28.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/protobuf v1.35.1 // indirect -) diff --git a/asset-transfer-events/application-gateway-go/go.sum b/asset-transfer-events/application-gateway-go/go.sum deleted file mode 100644 index 01eab6a8..00000000 --- a/asset-transfer-events/application-gateway-go/go.sum +++ /dev/null @@ -1,32 +0,0 @@ -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-gateway v1.7.0 h1:bd1quU8qYPYqYO69m1tPIDSjB+D+u/rBJfE1eWFcpjY= -github.com/hyperledger/fabric-gateway v1.7.0/go.mod h1:TItDGnq71eJcgz5TW+m5Sq3kWGp0AEI1HPCNxj0Eu7k= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= -github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/asset-transfer-events/application-gateway-java/build.gradle b/asset-transfer-events/application-gateway-java/build.gradle deleted file mode 100644 index e0743122..00000000 --- a/asset-transfer-events/application-gateway-java/build.gradle +++ /dev/null @@ -1,28 +0,0 @@ -plugins { - // Apply the application plugin to add support for building a CLI application. - id 'application' -} - -repositories { - mavenCentral() -} - -dependencies { - implementation 'org.hyperledger.fabric:fabric-gateway:1.7.0' - implementation platform('com.google.protobuf:protobuf-bom:4.28.2') - implementation platform('io.grpc:grpc-bom:1.67.1') - compileOnly 'io.grpc:grpc-api' - runtimeOnly 'io.grpc:grpc-netty-shaded' - implementation 'com.google.code.gson:gson:2.11.0' -} - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(11) - } -} - -application { - // Define the main class for the application. - mainClass = 'App' -} diff --git a/asset-transfer-events/application-gateway-java/gradle/wrapper/gradle-wrapper.jar b/asset-transfer-events/application-gateway-java/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index d64cd491..00000000 Binary files a/asset-transfer-events/application-gateway-java/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/asset-transfer-events/application-gateway-java/gradle/wrapper/gradle-wrapper.properties b/asset-transfer-events/application-gateway-java/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e2847c82..00000000 --- a/asset-transfer-events/application-gateway-java/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/asset-transfer-events/application-gateway-java/gradlew b/asset-transfer-events/application-gateway-java/gradlew deleted file mode 100755 index 1aa94a42..00000000 --- a/asset-transfer-events/application-gateway-java/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/asset-transfer-events/application-gateway-java/gradlew.bat b/asset-transfer-events/application-gateway-java/gradlew.bat deleted file mode 100644 index 7101f8e4..00000000 --- a/asset-transfer-events/application-gateway-java/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/asset-transfer-events/application-gateway-java/pom.xml b/asset-transfer-events/application-gateway-java/pom.xml deleted file mode 100644 index e959e925..00000000 --- a/asset-transfer-events/application-gateway-java/pom.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - 4.0.0 - - org.hyperledger.fabric.example - asset-transfer-events - 1.0-SNAPSHOT - - - UTF-8 - 11 - - - - - - com.google.protobuf - protobuf-bom - 4.28.2 - pom - import - - - io.grpc - grpc-bom - 1.67.1 - pom - import - - - - - - - org.hyperledger.fabric - fabric-gateway - 1.7.0 - - - io.grpc - grpc-api - - - io.grpc - grpc-netty-shaded - runtime - - - com.google.code.gson - gson - 2.11.0 - - - - - - - - - maven-clean-plugin - 3.4.0 - - - - maven-resources-plugin - 3.3.1 - - - maven-compiler-plugin - 3.13.0 - - - maven-surefire-plugin - 3.3.0 - - - maven-jar-plugin - 3.4.2 - - - maven-install-plugin - 3.1.2 - - - maven-deploy-plugin - 3.1.2 - - - - maven-site-plugin - 3.12.1 - - - maven-project-info-reports-plugin - 3.6.1 - - - - - diff --git a/asset-transfer-events/application-gateway-java/settings.gradle b/asset-transfer-events/application-gateway-java/settings.gradle deleted file mode 100644 index acea186a..00000000 --- a/asset-transfer-events/application-gateway-java/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * The settings file is used to specify which projects to include in your build. - * - * Detailed information about configuring a multi-project build in Gradle can be found - * in the user manual at https://docs.gradle.org/6.5/userguide/multi_project_builds.html - */ - -rootProject.name = 'asset-transfer-events' diff --git a/asset-transfer-events/application-gateway-java/src/main/java/App.java b/asset-transfer-events/application-gateway-java/src/main/java/App.java deleted file mode 100644 index 1bdbeba9..00000000 --- a/asset-transfer-events/application-gateway-java/src/main/java/App.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonParser; -import io.grpc.Status; -import org.hyperledger.fabric.client.ChaincodeEvent; -import org.hyperledger.fabric.client.CloseableIterator; -import org.hyperledger.fabric.client.CommitException; -import org.hyperledger.fabric.client.CommitStatusException; -import org.hyperledger.fabric.client.Contract; -import org.hyperledger.fabric.client.EndorseException; -import org.hyperledger.fabric.client.Gateway; -import org.hyperledger.fabric.client.GatewayRuntimeException; -import org.hyperledger.fabric.client.Hash; -import org.hyperledger.fabric.client.Network; -import org.hyperledger.fabric.client.SubmitException; - -import java.nio.charset.StandardCharsets; -import java.time.Instant; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -public final class App implements AutoCloseable { - private static final String channelName = "mychannel"; - private static final String chaincodeName = "events"; - - private final Network network; - private final Contract contract; - private final String assetId = "asset" + Instant.now().toEpochMilli(); - private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - private final ExecutorService executor = Executors.newCachedThreadPool(); - - public static void main(final String[] args) throws Exception { - var grpcChannel = Connections.newGrpcConnection(); - var builder = Gateway.newInstance() - .identity(Connections.newIdentity()) - .signer(Connections.newSigner()) - .hash(Hash.SHA256) - .connection(grpcChannel) - .evaluateOptions(options -> options.withDeadlineAfter(5, TimeUnit.SECONDS)) - .endorseOptions(options -> options.withDeadlineAfter(15, TimeUnit.SECONDS)) - .submitOptions(options -> options.withDeadlineAfter(5, TimeUnit.SECONDS)) - .commitStatusOptions(options -> options.withDeadlineAfter(1, TimeUnit.MINUTES)); - - try (var gateway = builder.connect(); var app = new App(gateway)) { - app.run(); - } finally { - grpcChannel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); - } - } - - public App(final Gateway gateway) { - network = gateway.getNetwork(channelName); - contract = network.getContract(chaincodeName); - } - - public void run() throws EndorseException, SubmitException, CommitStatusException, CommitException { - // Listen for events emitted by subsequent transactions, stopping when the try-with-resources block exits - try (var eventSession = startChaincodeEventListening()) { - var firstBlockNumber = createAsset(); - updateAsset(); - transferAsset(); - deleteAsset(); - - // Replay events from the block containing the first transaction - replayChaincodeEvents(firstBlockNumber); - } - } - - private CloseableIterator startChaincodeEventListening() { - System.out.println("\n*** Start chaincode event listening"); - - var eventIter = network.getChaincodeEvents(chaincodeName); - executor.execute(() -> readEvents(eventIter)); - - return eventIter; - } - - private void readEvents(final CloseableIterator eventIter) { - try { - eventIter.forEachRemaining(event -> { - var payload = prettyJson(event.getPayload()); - System.out.println("\n<-- Chaincode event received: " + event.getEventName() + " - " + payload); - }); - } catch (GatewayRuntimeException e) { - if (e.getStatus().getCode() != Status.Code.CANCELLED) { - throw e; - } - } - } - - private String prettyJson(final byte[] json) { - return prettyJson(new String(json, StandardCharsets.UTF_8)); - } - - private String prettyJson(final String json) { - var parsedJson = JsonParser.parseString(json); - return gson.toJson(parsedJson); - } - - private long createAsset() throws EndorseException, SubmitException, CommitStatusException { - System.out.println("\n--> Submit transaction: CreateAsset, " + assetId + " owned by Sam with appraised value 100"); - - var commit = contract.newProposal("CreateAsset") - .addArguments(assetId, "blue", "10", "Sam", "100") - .build() - .endorse() - .submitAsync(); - - var status = commit.getStatus(); - if (!status.isSuccessful()) { - throw new RuntimeException("failed to commit transaction with status code " + status.getCode()); - } - - System.out.println("\n*** CreateAsset committed successfully"); - - return status.getBlockNumber(); - } - - private void updateAsset() throws EndorseException, SubmitException, CommitStatusException, CommitException { - System.out.println("\n--> Submit transaction: UpdateAsset, " + assetId + " update appraised value to 200"); - - contract.submitTransaction("UpdateAsset", assetId, "blue", "10", "Sam", "200"); - - System.out.println("\n*** UpdateAsset committed successfully"); - } - - private void transferAsset() throws EndorseException, SubmitException, CommitStatusException, CommitException { - System.out.println("\n--> Submit transaction: TransferAsset, " + assetId + " to Mary"); - - contract.submitTransaction("TransferAsset", assetId, "Mary"); - - System.out.println("\n*** TransferAsset committed successfully"); - } - - private void deleteAsset() throws EndorseException, SubmitException, CommitStatusException, CommitException { - System.out.println("\n--> Submit transaction: DeleteAsset, " + assetId); - - contract.submitTransaction("DeleteAsset", assetId); - - System.out.println("\n*** DeleteAsset committed successfully"); - } - - private void replayChaincodeEvents(final long startBlock) { - System.out.println("\n*** Start chaincode event replay"); - - var request = network.newChaincodeEventsRequest(chaincodeName) - .startBlock(startBlock) - .build(); - - try (var eventIter = request.getEvents()) { - while (eventIter.hasNext()) { - var event = eventIter.next(); - var payload = prettyJson(event.getPayload()); - System.out.println("\n<-- Chaincode event replayed: " + event.getEventName() + " - " + payload); - - if (event.getEventName().equals("DeleteAsset")) { - // Reached the last submitted transaction so break to close the iterator and stop listening for events - break; - } - } - } - } - - @Override - public void close() throws Exception { - executor.shutdownNow(); - } -} diff --git a/asset-transfer-events/application-gateway-java/src/main/java/Connections.java b/asset-transfer-events/application-gateway-java/src/main/java/Connections.java deleted file mode 100644 index 6902fc03..00000000 --- a/asset-transfer-events/application-gateway-java/src/main/java/Connections.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.grpc.Grpc; -import io.grpc.ManagedChannel; -import io.grpc.TlsChannelCredentials; -import org.hyperledger.fabric.client.identity.Identities; -import org.hyperledger.fabric.client.identity.Identity; -import org.hyperledger.fabric.client.identity.Signer; -import org.hyperledger.fabric.client.identity.Signers; -import org.hyperledger.fabric.client.identity.X509Identity; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.InvalidKeyException; -import java.security.cert.CertificateException; - -public final class Connections { - // Path to crypto materials. - private static final Path cryptoPath = Paths.get("..", "..", "test-network", "organizations", "peerOrganizations", "org1.example.com"); - // Path to user certificate. - private static final Path certDirPath = cryptoPath.resolve(Paths.get("users", "User1@org1.example.com", "msp", "signcerts")); - // Path to user private key directory. - private static final Path keyDirPath = cryptoPath.resolve(Paths.get("users", "User1@org1.example.com", "msp", "keystore")); - // Path to peer tls certificate. - private static final Path tlsCertPath = cryptoPath.resolve(Paths.get("peers", "peer0.org1.example.com", "tls", "ca.crt")); - - // Gateway peer end point. - private static final String peerEndpoint = "localhost:7051"; - private static final String overrideAuth = "peer0.org1.example.com"; - - private static final String mspID = "Org1MSP"; - - private Connections() { - // Private constructor to prevent instantiation - } - - public static ManagedChannel newGrpcConnection() throws IOException { - var credentials = TlsChannelCredentials.newBuilder() - .trustManager(tlsCertPath.toFile()) - .build(); - return Grpc.newChannelBuilder(peerEndpoint, credentials) - .overrideAuthority(overrideAuth) - .build(); - } - - public static Identity newIdentity() throws IOException, CertificateException { - try (var certReader = Files.newBufferedReader(getFirstFilePath(certDirPath))) { - var certificate = Identities.readX509Certificate(certReader); - return new X509Identity(mspID, certificate); - } - } - - public static Signer newSigner() throws IOException, InvalidKeyException { - try (var keyReader = Files.newBufferedReader(getFirstFilePath(keyDirPath))) { - var privateKey = Identities.readPrivateKey(keyReader); - return Signers.newPrivateKeySigner(privateKey); - } - } - - private static Path getFirstFilePath(Path dirPath) throws IOException { - try (var keyFiles = Files.list(dirPath)) { - return keyFiles.findFirst().orElseThrow(); - } - }} diff --git a/asset-transfer-events/application-gateway-typescript/.gitignore b/asset-transfer-events/application-gateway-typescript/.gitignore deleted file mode 100644 index 99e5af9f..00000000 --- a/asset-transfer-events/application-gateway-typescript/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - - -# Coverage directory used by tools like istanbul -coverage - -# Dependency directories -node_modules/ -jspm_packages/ - -# Compiled TypeScript files -dist diff --git a/asset-transfer-events/application-gateway-typescript/.npmrc b/asset-transfer-events/application-gateway-typescript/.npmrc deleted file mode 100644 index b6f27f13..00000000 --- a/asset-transfer-events/application-gateway-typescript/.npmrc +++ /dev/null @@ -1 +0,0 @@ -engine-strict=true diff --git a/asset-transfer-events/application-gateway-typescript/eslint.config.mjs b/asset-transfer-events/application-gateway-typescript/eslint.config.mjs deleted file mode 100644 index 9ef6b243..00000000 --- a/asset-transfer-events/application-gateway-typescript/eslint.config.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import js from '@eslint/js'; -import tseslint from 'typescript-eslint'; - -export default tseslint.config(js.configs.recommended, ...tseslint.configs.strictTypeChecked, { - languageOptions: { - ecmaVersion: 2023, - sourceType: 'module', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: import.meta.dirname, - }, - }, -}); diff --git a/asset-transfer-events/application-gateway-typescript/package.json b/asset-transfer-events/application-gateway-typescript/package.json deleted file mode 100755 index 24ca024e..00000000 --- a/asset-transfer-events/application-gateway-typescript/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "asset-transfer-events", - "version": "1.0.0", - "description": "Asset Transfer Events Application implemented in typeScript using fabric-gateway", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "engines": { - "node": ">=18" - }, - "scripts": { - "build": "tsc", - "build:watch": "tsc -w", - "lint": "eslint src", - "prepare": "npm run build", - "pretest": "npm run lint", - "start": "node dist/app.js" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "@grpc/grpc-js": "^1.12.2", - "@hyperledger/fabric-gateway": "^1.7.0" - }, - "devDependencies": { - "@eslint/js": "^9.3.0", - "@tsconfig/node18": "^18.2.2", - "@types/node": "^18.18.6", - "eslint": "^8.57.0", - "typescript": "~5.4", - "typescript-eslint": "^7.13.0" - } -} diff --git a/asset-transfer-events/application-gateway-typescript/src/app.ts b/asset-transfer-events/application-gateway-typescript/src/app.ts deleted file mode 100755 index 7db50116..00000000 --- a/asset-transfer-events/application-gateway-typescript/src/app.ts +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as grpc from '@grpc/grpc-js'; -import { ChaincodeEvent, CloseableAsyncIterable, connect, Contract, GatewayError, hash, Network } from '@hyperledger/fabric-gateway'; -import { TextDecoder } from 'util'; -import { newGrpcConnection, newIdentity, newSigner } from './connect'; - -const channelName = 'mychannel'; -const chaincodeName = 'events'; - -const utf8Decoder = new TextDecoder(); -const now = Date.now(); -const assetId = `asset${String(now)}`; - - -async function main(): Promise { - const client = await newGrpcConnection(); - const gateway = connect({ - client, - identity: await newIdentity(), - signer: await newSigner(), - hash: hash.sha256, - evaluateOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - endorseOptions: () => { - return { deadline: Date.now() + 15000 }; // 15 seconds - }, - submitOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - commitStatusOptions: () => { - return { deadline: Date.now() + 60000 }; // 1 minute - }, - }); - - let events: CloseableAsyncIterable | undefined; - - try { - const network = gateway.getNetwork(channelName); - const contract = network.getContract(chaincodeName); - - // Listen for events emitted by subsequent transactions - events = await startEventListening(network); - - const firstBlockNumber = await createAsset(contract); - await updateAsset(contract); - await transferAsset(contract); - await deleteAssetByID(contract); - - // Replay events from the block containing the first transaction - await replayChaincodeEvents(network,firstBlockNumber); - } finally { - events?.close(); - gateway.close(); - client.close(); - } -} - -main().catch((error: unknown) => { - console.error('******** FAILED to run the application:', error); - process.exitCode = 1; -}); - -async function startEventListening(network: Network): Promise> { - console.log('\n*** Start chaincode event listening'); - - const events = await network.getChaincodeEvents(chaincodeName); - - void readEvents(events); // Don't await - run asynchronously - return events; -} - -async function readEvents(events: CloseableAsyncIterable): Promise { - try { - for await (const event of events) { - const payload = parseJson(event.payload); - console.log(`\n<-- Chaincode event received: ${event.eventName} -`, payload); - } - } catch (error: unknown) { - // Ignore the read error when events.close() is called explicitly - if (!(error instanceof GatewayError) || error.code !== grpc.status.CANCELLED.valueOf()) { - throw error; - } - } -} - -function parseJson(jsonBytes: Uint8Array): unknown { - const json = utf8Decoder.decode(jsonBytes); - return JSON.parse(json); -} - -async function createAsset(contract: Contract): Promise { - console.log(`\n--> Submit Transaction: CreateAsset, ${assetId} owned by Sam with appraised value 100`); - - const result = await contract.submitAsync('CreateAsset', { - arguments: [ assetId, 'blue', '10', 'Sam', '100' ], - }); - - const status = await result.getStatus(); - if (!status.successful) { - throw new Error(`failed to commit transaction ${status.transactionId} with status code ${String(status.code)}`); - } - - console.log('\n*** CreateAsset committed successfully'); - - return status.blockNumber; -} - -async function updateAsset(contract: Contract): Promise { - console.log(`\n--> Submit transaction: UpdateAsset, ${assetId} update appraised value to 200`); - - await contract.submitTransaction('UpdateAsset', assetId, 'blue', '10', 'Sam', '200'); - - console.log('\n*** UpdateAsset committed successfully'); -} - -async function transferAsset(contract: Contract): Promise { - console.log(`\n--> Submit transaction: TransferAsset, ${assetId} to Mary`); - - await contract.submitTransaction('TransferAsset', assetId, 'Mary'); - - console.log('\n*** TransferAsset committed successfully'); -} - -async function deleteAssetByID(contract: Contract): Promise{ - console.log(`\n--> Submit transaction: DeleteAsset, ${assetId}`); - - await contract.submitTransaction('DeleteAsset', assetId); - - console.log('\n*** DeleteAsset committed successfully'); -} - -async function replayChaincodeEvents(network: Network, startBlock: bigint): Promise { - console.log('\n*** Start chaincode event replay'); - - const events = await network.getChaincodeEvents(chaincodeName, { - startBlock, - }); - - try { - for await (const event of events) { - const payload = parseJson(event.payload); - console.log(`\n<-- Chaincode event replayed: ${event.eventName} -`, payload); - - if (event.eventName === 'DeleteAsset') { - // Reached the last submitted transaction so break to stop listening for events - break; - } - } - } finally { - events.close(); - } -} diff --git a/asset-transfer-events/application-gateway-typescript/src/connect.ts b/asset-transfer-events/application-gateway-typescript/src/connect.ts deleted file mode 100644 index c72f766a..00000000 --- a/asset-transfer-events/application-gateway-typescript/src/connect.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as grpc from '@grpc/grpc-js'; -import { Identity, Signer, signers } from '@hyperledger/fabric-gateway'; -import * as crypto from 'crypto'; -import { promises as fs } from 'fs'; -import * as path from 'path'; - -const mspId = 'Org1MSP'; - -// Path to crypto materials. -const cryptoPath = path.resolve(__dirname, '..', '..', '..', 'test-network', 'organizations', 'peerOrganizations', 'org1.example.com'); - -// Path to user private key directory. -const keyDirectoryPath = path.resolve(cryptoPath, 'users', 'User1@org1.example.com', 'msp', 'keystore'); - -// Path to user certificate. -const certDirectoryPath = path.resolve(cryptoPath, 'users', 'User1@org1.example.com', 'msp', 'signcerts'); - -// Path to peer tls certificate. -const tlsCertPath = path.resolve(cryptoPath, 'peers', 'peer0.org1.example.com', 'tls', 'ca.crt'); - -// Gateway peer endpoint. -const peerEndpoint = 'localhost:7051'; - -export async function newGrpcConnection(): Promise { - const tlsRootCert = await fs.readFile(tlsCertPath); - const tlsCredentials = grpc.credentials.createSsl(tlsRootCert); - return new grpc.Client(peerEndpoint, tlsCredentials, { - 'grpc.ssl_target_name_override': 'peer0.org1.example.com', - }); -} - -export async function newIdentity(): Promise { - const certPath = await getFirstDirFileName(certDirectoryPath); - const credentials = await fs.readFile(certPath); - return { mspId, credentials }; -} - -export async function newSigner(): Promise { - const keyPath = await getFirstDirFileName(keyDirectoryPath); - const privateKeyPem = await fs.readFile(keyPath); - const privateKey = crypto.createPrivateKey(privateKeyPem); - return signers.newPrivateKeySigner(privateKey); -} - -async function getFirstDirFileName(dirPath: string): Promise { - const files = await fs.readdir(dirPath); - const file = files[0]; - if (!file) { - throw new Error(`No files in directory: ${dirPath}`); - } - return path.join(dirPath, file); -} diff --git a/asset-transfer-events/application-gateway-typescript/tsconfig.json b/asset-transfer-events/application-gateway-typescript/tsconfig.json deleted file mode 100644 index 4c20df24..00000000 --- a/asset-transfer-events/application-gateway-typescript/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "@tsconfig/node18/tsconfig.json", - "compilerOptions": { - "outDir": "dist", - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "noUnusedLocals": true, - "noImplicitReturns": true, - "noUncheckedIndexedAccess": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["./src/**/*"], - "exclude": ["./src/**/*.spec.ts"] -} diff --git a/asset-transfer-events/chaincode-go/assetTransferEvents.go b/asset-transfer-events/chaincode-go/assetTransferEvents.go deleted file mode 100644 index 4aede5c1..00000000 --- a/asset-transfer-events/chaincode-go/assetTransferEvents.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "log" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" - "github.com/hyperledger/fabric-samples/asset-transfer-events/chaincode-go/chaincode" -) - -func main() { - assetChaincode, err := contractapi.NewChaincode(&chaincode.SmartContract{}) - if err != nil { - log.Panicf("Error creating asset-transfer-events chaincode: %v", err) - } - - if err := assetChaincode.Start(); err != nil { - log.Panicf("Error starting asset-transfer-events chaincode: %v", err) - } -} diff --git a/asset-transfer-events/chaincode-go/chaincode/smartcontract.go b/asset-transfer-events/chaincode-go/chaincode/smartcontract.go deleted file mode 100644 index e9420cfa..00000000 --- a/asset-transfer-events/chaincode-go/chaincode/smartcontract.go +++ /dev/null @@ -1,134 +0,0 @@ -package chaincode - -import ( - "encoding/json" - "fmt" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -// SmartContract provides functions for managing an Asset -type SmartContract struct { - contractapi.Contract -} - -// Asset describes basic details of what makes up a simple asset -// Insert struct field in alphabetic order => to achieve determinism across languages -// golang keeps the order when marshal to json but doesn't order automatically -type Asset struct { - AppraisedValue int `json:"AppraisedValue"` - Color string `json:"Color"` - ID string `json:"ID"` - Owner string `json:"Owner"` - Size int `json:"Size"` -} - -// CreateAsset issues a new asset to the world state with given details. -func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue int) error { - existing, err := s.readState(ctx, id) - if err == nil && existing != nil { - return fmt.Errorf("the asset %s already exists", id) - } - - asset := Asset{ - ID: id, - Color: color, - Size: size, - Owner: owner, - AppraisedValue: appraisedValue, - } - assetJSON, err := json.Marshal(asset) - if err != nil { - return err - } - - ctx.GetStub().SetEvent("CreateAsset", assetJSON) - return ctx.GetStub().PutState(id, assetJSON) -} - -func (s *SmartContract) readState(ctx contractapi.TransactionContextInterface, id string) ([]byte, error) { - assetJSON, err := ctx.GetStub().GetState(id) - if err != nil { - return nil, fmt.Errorf("failed to read from world state: %w", err) - } - if assetJSON == nil { - return nil, fmt.Errorf("the asset %s does not exist", id) - } - - return assetJSON, nil -} - -// ReadAsset returns the asset stored in the world state with given id. -func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, id string) (*Asset, error) { - assetJSON, err := s.readState(ctx, id) - if err != nil { - return nil, err - } - - var asset Asset - err = json.Unmarshal(assetJSON, &asset) - if err != nil { - return nil, err - } - - return &asset, nil -} - -// UpdateAsset updates an existing asset in the world state with provided parameters. -func (s *SmartContract) UpdateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue int) error { - _, err := s.readState(ctx, id) - if err != nil { - return err - } - - // overwriting original asset with new asset - asset := Asset{ - ID: id, - Color: color, - Size: size, - Owner: owner, - AppraisedValue: appraisedValue, - } - assetJSON, err := json.Marshal(asset) - if err != nil { - return err - } - - ctx.GetStub().SetEvent("UpdateAsset", assetJSON) - return ctx.GetStub().PutState(id, assetJSON) -} - -// DeleteAsset deletes an given asset from the world state. -func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface, id string) error { - assetJSON, err := s.readState(ctx, id) - if err != nil { - return err - } - - ctx.GetStub().SetEvent("DeleteAsset", assetJSON) - return ctx.GetStub().DelState(id) -} - -// TransferAsset updates the owner field of asset with given id in world state, and returns the old owner. -func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface, id string, newOwner string) (string, error) { - asset, err := s.ReadAsset(ctx, id) - if err != nil { - return "", err - } - - oldOwner := asset.Owner - asset.Owner = newOwner - - assetJSON, err := json.Marshal(asset) - if err != nil { - return "", err - } - - ctx.GetStub().SetEvent("TransferAsset", assetJSON) - err = ctx.GetStub().PutState(id, assetJSON) - if err != nil { - return "", err - } - - return oldOwner, nil -} diff --git a/asset-transfer-events/chaincode-go/go.mod b/asset-transfer-events/chaincode-go/go.mod deleted file mode 100644 index be5bcd4b..00000000 --- a/asset-transfer-events/chaincode-go/go.mod +++ /dev/null @@ -1,26 +0,0 @@ -module github.com/hyperledger/fabric-samples/asset-transfer-events/chaincode-go - -go 1.22.0 - -require github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 - -require ( - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 // indirect - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.36.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/asset-transfer-events/chaincode-go/go.sum b/asset-transfer-events/chaincode-go/go.sum deleted file mode 100644 index 1459ca55..00000000 --- a/asset-transfer-events/chaincode-go/go.sum +++ /dev/null @@ -1,61 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 h1:IhkHfrl5X/fVnmB6pWeCYCdIJRi9bxj+WTnVN8DtW3c= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0/go.mod h1:PHHaFffjw7p7n9bmCfcm7RqDqYdivNEsJdiNIKZo5Lk= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 h1:rmUoBmciB0GL/miqcbJmJbgp5QTWoJUrZo+CNxrNLF4= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0/go.mod h1:FeWeO/jwGjiME7ak3GufqKIcwkejtzrDG4QxbfKydWs= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/asset-transfer-events/chaincode-java/build.gradle b/asset-transfer-events/chaincode-java/build.gradle deleted file mode 100644 index b04a0bff..00000000 --- a/asset-transfer-events/chaincode-java/build.gradle +++ /dev/null @@ -1,69 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -plugins { - id 'com.gradleup.shadow' version '8.3.5' - id 'application' - id 'checkstyle' - id 'jacoco' -} - -group 'org.hyperledger.fabric.samples' -version '1.0-SNAPSHOT' - -dependencies { - implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.+' - implementation 'org.json:json:+' - testImplementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.+' -} - -repositories { - mavenCentral() - maven { - url 'https://jitpack.io' - } -} - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(11) - } -} - -application { - mainClassName = 'org.hyperledger.fabric.contract.ContractRouter' -} - - -checkstyle { - toolVersion '8.21' - configFile file("config/checkstyle/checkstyle.xml") -} - -checkstyleMain { - source ='src/main/java' -} - -checkstyleTest { - source ='src/test/java' -} - -jacocoTestReport { - dependsOn test -} - -mainClassName = 'org.hyperledger.fabric.contract.ContractRouter' - -shadowJar { - archiveBaseName = 'chaincode' - archiveVersion = '' - archiveClassifier = '' - mergeServiceFiles() - - manifest { - attributes 'Main-Class': 'org.hyperledger.fabric.contract.ContractRouter' - } -} - -installDist.dependsOn check diff --git a/asset-transfer-events/chaincode-java/config/checkstyle/checkstyle.xml b/asset-transfer-events/chaincode-java/config/checkstyle/checkstyle.xml deleted file mode 100644 index acd5df44..00000000 --- a/asset-transfer-events/chaincode-java/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/asset-transfer-events/chaincode-java/config/checkstyle/suppressions.xml b/asset-transfer-events/chaincode-java/config/checkstyle/suppressions.xml deleted file mode 100644 index 33dda041..00000000 --- a/asset-transfer-events/chaincode-java/config/checkstyle/suppressions.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/asset-transfer-events/chaincode-java/gradle/wrapper/gradle-wrapper.jar b/asset-transfer-events/chaincode-java/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index d64cd491..00000000 Binary files a/asset-transfer-events/chaincode-java/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/asset-transfer-events/chaincode-java/gradle/wrapper/gradle-wrapper.properties b/asset-transfer-events/chaincode-java/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e2847c82..00000000 --- a/asset-transfer-events/chaincode-java/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/asset-transfer-events/chaincode-java/gradlew b/asset-transfer-events/chaincode-java/gradlew deleted file mode 100755 index 1aa94a42..00000000 --- a/asset-transfer-events/chaincode-java/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/asset-transfer-events/chaincode-java/gradlew.bat b/asset-transfer-events/chaincode-java/gradlew.bat deleted file mode 100644 index 7101f8e4..00000000 --- a/asset-transfer-events/chaincode-java/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/asset-transfer-events/chaincode-java/settings.gradle b/asset-transfer-events/chaincode-java/settings.gradle deleted file mode 100644 index 7112a47d..00000000 --- a/asset-transfer-events/chaincode-java/settings.gradle +++ /dev/null @@ -1,5 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -rootProject.name = 'events' diff --git a/asset-transfer-events/chaincode-java/src/main/java/org/hyperledger/fabric/samples/events/Asset.java b/asset-transfer-events/chaincode-java/src/main/java/org/hyperledger/fabric/samples/events/Asset.java deleted file mode 100644 index f9bdc18e..00000000 --- a/asset-transfer-events/chaincode-java/src/main/java/org/hyperledger/fabric/samples/events/Asset.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.events; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.hyperledger.fabric.contract.annotation.DataType; -import org.hyperledger.fabric.contract.annotation.Property; - - -import org.json.JSONObject; - -@DataType() -public final class Asset { - - @Property() - private final String assetID; - - @Property() - private String color; - - @Property() - private int size; - - @Property() - private String owner; - - @Property() - private int appraisedValue; - - public Asset(final String assetID, final String color, - final int size, final String owner, final int value) { - - this.assetID = assetID; - this.color = color; - this.size = size; - this.owner = owner; - this.appraisedValue = value; - } - - public String getAssetID() { - return assetID; - } - - public String getColor() { - return color; - } - - public int getSize() { - return size; - } - - public String getOwner() { - return owner; - } - - public int getAppraisedValue() { - return appraisedValue; - } - - public void setOwner(final String newowner) { - this.owner = newowner; - } - - public void setAppraisedValue(final int value) { - this.appraisedValue = value; - } - - public void setColor(final String c) { - this.color = c; - } - - public void setSize(final int s) { - this.size = s; - } - - // Serialize asset without private properties - public byte[] serialize() { - return serialize(null).getBytes(UTF_8); - } - - public String serialize(final String privateProps) { - Map tMap = new HashMap(); - tMap.put("ID", assetID); - tMap.put("Color", color); - tMap.put("Owner", owner); - tMap.put("Size", Integer.toString(size)); - tMap.put("AppraisedValue", Integer.toString(appraisedValue)); - if (privateProps != null && privateProps.length() > 0) { - tMap.put("asset_properties", new JSONObject(privateProps)); - } - return new JSONObject(tMap).toString(); - } - - public static Asset deserialize(final byte[] assetJSON) { - return deserialize(new String(assetJSON, UTF_8)); - } - - public static Asset deserialize(final String assetJSON) { - - JSONObject json = new JSONObject(assetJSON); - Map tMap = json.toMap(); - final String id = (String) tMap.get("ID"); - - final String color = (String) tMap.get("Color"); - final String owner = (String) tMap.get("Owner"); - int size = 0; - int appraisedValue = 0; - if (tMap.containsKey("Size")) { - size = Integer.parseInt((String) tMap.get("Size")); - } - if (tMap.containsKey("AppraisedValue")) { - appraisedValue = Integer.parseInt((String) tMap.get("AppraisedValue")); - } - return new Asset(id, color, size, owner, appraisedValue); - - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - - Asset other = (Asset) obj; - - return Objects.deepEquals( - new String[]{getAssetID(), getColor(), getOwner()}, - new String[]{other.getAssetID(), other.getColor(), other.getOwner()}) - && - Objects.deepEquals( - new int[]{getSize(), getAppraisedValue()}, - new int[]{other.getSize(), other.getAppraisedValue()}); - } - - @Override - public int hashCode() { - return Objects.hash(getAssetID(), getColor(), getSize(), getOwner(), getAppraisedValue()); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()) - + " [assetID=" + assetID + ", appraisedValue=" + appraisedValue + ", color=" - + color + ", size=" + size + ", owner=" + owner + "]"; - } - -} diff --git a/asset-transfer-events/chaincode-java/src/main/java/org/hyperledger/fabric/samples/events/AssetTransfer.java b/asset-transfer-events/chaincode-java/src/main/java/org/hyperledger/fabric/samples/events/AssetTransfer.java deleted file mode 100644 index a892693a..00000000 --- a/asset-transfer-events/chaincode-java/src/main/java/org/hyperledger/fabric/samples/events/AssetTransfer.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.events; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.contract.ContractInterface; -import org.hyperledger.fabric.contract.annotation.Contact; -import org.hyperledger.fabric.contract.annotation.Contract; -import org.hyperledger.fabric.contract.annotation.Default; -import org.hyperledger.fabric.contract.annotation.Info; -import org.hyperledger.fabric.contract.annotation.License; -import org.hyperledger.fabric.contract.annotation.Transaction; -import org.hyperledger.fabric.shim.ChaincodeException; -import org.hyperledger.fabric.shim.ChaincodeStub; - -import java.util.Map; - -/** - * Main Chaincode class. - * - * @see org.hyperledger.fabric.shim.Chaincode - *

- * Each chaincode transaction function must take, Context as first parameter. - * Unless specified otherwise via annotation (@Contract or @Transaction), the contract name - * is the class name (without package) - * and the transaction name is the method name. - */ -@Contract( - name = "asset-transfer-events-java", - info = @Info( - title = "Asset Transfer Events", - description = "The hyperlegendary asset transfer events sample", - version = "0.0.1-SNAPSHOT", - license = @License( - name = "Apache 2.0 License", - url = "http://www.apache.org/licenses/LICENSE-2.0.html"), - contact = @Contact( - email = "a.transfer@example.com", - name = "Fabric Development Team", - url = "https://hyperledger.example.com"))) -@Default -public final class AssetTransfer implements ContractInterface { - - static final String IMPLICIT_COLLECTION_NAME_PREFIX = "_implicit_org_"; - static final String PRIVATE_PROPS_KEY = "asset_properties"; - - /** - * Retrieves the asset details with the specified ID - * - * @param ctx the transaction context - * @param assetID the ID of the asset - * @return the asset found on the ledger. Returns error if asset is not found - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public String ReadAsset(final Context ctx, final String assetID) { - System.out.printf("ReadAsset: ID %s\n", assetID); - - Asset asset = getState(ctx, assetID); - String privData = readPrivateData(ctx, assetID); - return asset.serialize(privData); - } - - /** - * Creates a new asset on the ledger. Saves the passed private data (asset properties) from transient map input. - * - * @param ctx the transaction context - * Transient map with asset_properties key with asset json as value - * @param assetID - * @param color - * @param size - * @param owner - * @param appraisedValue - * @return the created asset - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public Asset CreateAsset(final Context ctx, final String assetID, final String color, final int size, final String owner, final int appraisedValue) { - ChaincodeStub stub = ctx.getStub(); - // input validations - String errorMessage = null; - if (assetID == null || assetID.equals("")) { - errorMessage = String.format("Empty input: assetID"); - } - if (owner == null || owner.equals("")) { - errorMessage = String.format("Empty input: owner"); - } - - if (errorMessage != null) { - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - // Check if asset already exists - byte[] assetJSON = ctx.getStub().getState(assetID); - if (assetJSON != null && assetJSON.length > 0) { - errorMessage = String.format("Asset %s already exists", assetID); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_ALREADY_EXISTS.toString()); - } - - Asset asset = new Asset(assetID, color, size, owner, appraisedValue); - - savePrivateData(ctx, assetID); - assetJSON = asset.serialize(); - System.out.printf("CreateAsset Put: ID %s Data %s\n", assetID, new String(assetJSON)); - - stub.putState(assetID, assetJSON); - // add Event data to the transaction data. Event will be published after the block containing - // this transaction is committed - stub.setEvent("CreateAsset", assetJSON); - return asset; - } - - - /** - * TransferAsset transfers the asset to the new owner - * Save any private data, if provided in transient map - * - * @param ctx the transaction context - * @param assetID asset to delete - * @param newOwner new owner for the asset - * @return none - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public void TransferAsset(final Context ctx, final String assetID, final String newOwner) { - ChaincodeStub stub = ctx.getStub(); - String errorMessage = null; - - if (assetID == null || assetID.equals("")) { - errorMessage = "Empty input: assetID"; - } - if (newOwner == null || newOwner.equals("")) { - errorMessage = "Empty input: newOwner"; - } - if (errorMessage != null) { - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - System.out.printf("TransferAsset: verify asset %s exists\n", assetID); - Asset thisAsset = getState(ctx, assetID); - // Transfer asset to new owner - thisAsset.setOwner(newOwner); - - System.out.printf(" Transfer Asset: ID %s to owner %s\n", assetID, newOwner); - savePrivateData(ctx, assetID); // save private data if any - byte[] assetJSON = thisAsset.serialize(); - - stub.putState(assetID, assetJSON); - stub.setEvent("TransferAsset", assetJSON); //publish Event - } - - /** - * Update existing asset on the ledger with provided parameters. - * Saves the passed private data (asset properties) from transient map input. - * - * @param ctx the transaction context - * Transient map with asset_properties key with asset json as value - * @param assetID - * @param color - * @param size - * @param owner - * @param appraisedValue - * @return the created asset - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public Asset UpdateAsset(final Context ctx, final String assetID, final String color, final int size, final String owner, final int appraisedValue) { - ChaincodeStub stub = ctx.getStub(); - // input validations - String errorMessage = null; - if (assetID == null || assetID.equals("")) { - errorMessage = String.format("Empty input: assetID"); - } - - if (errorMessage != null) { - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - // reads from the Statedb. Check if asset already exists - Asset asset = getState(ctx, assetID); - - if (owner != null) { - asset.setOwner(owner); - } - if (color != null) { - asset.setColor(color); - } - if (size > 0) { - asset.setSize(size); - } - if (appraisedValue > 0) { - asset.setAppraisedValue(appraisedValue); - } - - savePrivateData(ctx, assetID); - byte[] assetJSON = asset.serialize(); - System.out.printf("UpdateAsset Put: ID %s Data %s\n", assetID, new String(assetJSON)); - stub.putState(assetID, assetJSON); - stub.setEvent("UpdateAsset", assetJSON); //publish Event - return asset; - } - - /** - * Deletes a asset & related details from the ledger. - * - * @param ctx the transaction context - * @param assetID asset to delete - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public void DeleteAsset(final Context ctx, final String assetID) { - ChaincodeStub stub = ctx.getStub(); - System.out.printf("DeleteAsset: verify asset %s exists\n", assetID); - Asset asset = getState(ctx, assetID); - - System.out.printf(" DeleteAsset: ID %s\n", assetID); - // delete private details of asset - removePrivateData(ctx, assetID); - stub.delState(assetID); // delete the key from Statedb - stub.setEvent("DeleteAsset", asset.serialize()); // publish Event - } - - private Asset getState(final Context ctx, final String assetID) { - byte[] assetJSON = ctx.getStub().getState(assetID); - if (assetJSON == null || assetJSON.length == 0) { - String errorMessage = String.format("Asset %s does not exist", assetID); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - - try { - Asset asset = Asset.deserialize(assetJSON); - return asset; - } catch (Exception e) { - throw new ChaincodeException("Deserialize error: " + e.getMessage(), AssetTransferErrors.DATA_ERROR.toString()); - } - } - - private String readPrivateData(final Context ctx, final String assetKey) { - String peerMSPID = ctx.getStub().getMspId(); - String clientMSPID = ctx.getClientIdentity().getMSPID(); - String implicitCollectionName = getCollectionName(ctx); - String privData = null; - // only if ClientOrgMatchesPeerOrg - if (peerMSPID.equals(clientMSPID)) { - System.out.printf(" ReadPrivateData from collection %s, ID %s\n", implicitCollectionName, assetKey); - byte[] propJSON = ctx.getStub().getPrivateData(implicitCollectionName, assetKey); - - if (propJSON != null && propJSON.length > 0) { - privData = new String(propJSON, UTF_8); - } - } - return privData; - } - - private void savePrivateData(final Context ctx, final String assetKey) { - String peerMSPID = ctx.getStub().getMspId(); - String clientMSPID = ctx.getClientIdentity().getMSPID(); - String implicitCollectionName = getCollectionName(ctx); - - if (peerMSPID.equals(clientMSPID)) { - Map transientMap = ctx.getStub().getTransient(); - if (transientMap != null && transientMap.containsKey(PRIVATE_PROPS_KEY)) { - byte[] transientAssetJSON = transientMap.get(PRIVATE_PROPS_KEY); - - System.out.printf("Asset's PrivateData Put in collection %s, ID %s\n", implicitCollectionName, assetKey); - ctx.getStub().putPrivateData(implicitCollectionName, assetKey, transientAssetJSON); - } - } - } - - private void removePrivateData(final Context ctx, final String assetKey) { - String peerMSPID = ctx.getStub().getMspId(); - String clientMSPID = ctx.getClientIdentity().getMSPID(); - String implicitCollectionName = getCollectionName(ctx); - - if (peerMSPID.equals(clientMSPID)) { - System.out.printf("PrivateData Delete from collection %s, ID %s\n", implicitCollectionName, assetKey); - ctx.getStub().delPrivateData(implicitCollectionName, assetKey); - } - } - - // Return the implicit collection name, to use for private property persistance - private String getCollectionName(final Context ctx) { - // Get the MSP ID of submitting client identity - String clientMSPID = ctx.getClientIdentity().getMSPID(); - String collectionName = IMPLICIT_COLLECTION_NAME_PREFIX + clientMSPID; - return collectionName; - } - - private enum AssetTransferErrors { - INCOMPLETE_INPUT, - INVALID_ACCESS, - ASSET_NOT_FOUND, - ASSET_ALREADY_EXISTS, - DATA_ERROR - } - -} diff --git a/asset-transfer-events/chaincode-javascript/.eslintignore b/asset-transfer-events/chaincode-javascript/.eslintignore deleted file mode 100644 index 15958470..00000000 --- a/asset-transfer-events/chaincode-javascript/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -coverage diff --git a/asset-transfer-events/chaincode-javascript/.eslintrc.js b/asset-transfer-events/chaincode-javascript/.eslintrc.js deleted file mode 100644 index cb00fa96..00000000 --- a/asset-transfer-events/chaincode-javascript/.eslintrc.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ -'use strict'; - -module.exports = { - env: { - node: true, - mocha: true, - es6: true - }, - parserOptions: { - ecmaVersion: 8, - sourceType: 'script' - }, - extends: 'eslint:recommended', - rules: { - indent: ['error', 'tab'], - 'linebreak-style': ['error', 'unix'], - quotes: ['error', 'single'], - semi: ['error', 'always'], - 'no-unused-vars': ['error', { args: 'none' }], - 'no-console': 'off', - curly: 'error', - eqeqeq: 'error', - 'no-throw-literal': 'error', - strict: 'error', - 'no-var': 'error', - 'dot-notation': 'error', - 'no-trailing-spaces': 'error', - 'no-use-before-define': 'error', - 'no-useless-call': 'error', - 'no-with': 'error', - 'operator-linebreak': 'error', - yoda: 'error', - 'quote-props': ['error', 'as-needed'], - 'no-constant-condition': ['error', { checkLoops: false }] - } -}; diff --git a/asset-transfer-events/chaincode-javascript/.gitignore b/asset-transfer-events/chaincode-javascript/.gitignore deleted file mode 100644 index eeace290..00000000 --- a/asset-transfer-events/chaincode-javascript/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -# Coverage directory used by tools like istanbul -coverage - -# Report cache used by istanbul -.nyc_output - -# Dependency directories -node_modules/ -jspm_packages/ - -package-lock.json diff --git a/asset-transfer-events/chaincode-javascript/index.js b/asset-transfer-events/chaincode-javascript/index.js deleted file mode 100644 index 3244cedf..00000000 --- a/asset-transfer-events/chaincode-javascript/index.js +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const assetTransferEvents = require('./lib/assetTransferEvents'); - -module.exports.AssetTransferEvents = assetTransferEvents; -module.exports.contracts = [assetTransferEvents]; diff --git a/asset-transfer-events/chaincode-javascript/lib/assetTransferEvents.js b/asset-transfer-events/chaincode-javascript/lib/assetTransferEvents.js deleted file mode 100644 index 27c5acbd..00000000 --- a/asset-transfer-events/chaincode-javascript/lib/assetTransferEvents.js +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Contract } = require('fabric-contract-api'); - -async function savePrivateData(ctx, assetKey) { - const clientOrg = ctx.clientIdentity.getMSPID(); - const peerOrg = ctx.stub.getMspID(); - const collection = '_implicit_org_' + peerOrg; - - if (clientOrg === peerOrg) { - const transientMap = ctx.stub.getTransient(); - if (transientMap) { - const properties = transientMap.get('asset_properties'); - if (properties) { - await ctx.stub.putPrivateData(collection, assetKey, properties); - } - } - } -} - -async function removePrivateData(ctx, assetKey) { - const clientOrg = ctx.clientIdentity.getMSPID(); - const peerOrg = ctx.stub.getMspID(); - const collection = '_implicit_org_' + peerOrg; - - if (clientOrg === peerOrg) { - const propertiesBuffer = await ctx.stub.getPrivateData(collection, assetKey); - if (propertiesBuffer && propertiesBuffer.length > 0) { - await ctx.stub.deletePrivateData(collection, assetKey); - } - } -} - -async function addPrivateData(ctx, assetKey, asset) { - const clientOrg = ctx.clientIdentity.getMSPID(); - const peerOrg = ctx.stub.getMspID(); - const collection = '_implicit_org_' + peerOrg; - - if (clientOrg === peerOrg) { - const propertiesBuffer = await ctx.stub.getPrivateData(collection, assetKey); - if (propertiesBuffer && propertiesBuffer.length > 0) { - const properties = JSON.parse(propertiesBuffer.toString()); - asset.asset_properties = properties; - } - } -} - -async function readState(ctx, id) { - const assetBuffer = await ctx.stub.getState(id); // get the asset from chaincode state - if (!assetBuffer || assetBuffer.length === 0) { - throw new Error(`The asset ${id} does not exist`); - } - const assetString = assetBuffer.toString(); - const asset = JSON.parse(assetString); - - return asset; -} - -class AssetTransferEvents extends Contract { - - // CreateAsset issues a new asset to the world state with given details. - async CreateAsset(ctx, id, color, size, owner, appraisedValue) { - const asset = { - ID: id, - Color: color, - Size: size, - Owner: owner, - AppraisedValue: appraisedValue, - }; - await savePrivateData(ctx, id); - const assetBuffer = Buffer.from(JSON.stringify(asset)); - - ctx.stub.setEvent('CreateAsset', assetBuffer); - return ctx.stub.putState(id, assetBuffer); - } - - // TransferAsset updates the owner field of an asset with the given id in - // the world state. - async TransferAsset(ctx, id, newOwner) { - const asset = await readState(ctx, id); - asset.Owner = newOwner; - const assetBuffer = Buffer.from(JSON.stringify(asset)); - await savePrivateData(ctx, id); - - ctx.stub.setEvent('TransferAsset', assetBuffer); - return ctx.stub.putState(id, assetBuffer); - } - - // ReadAsset returns the asset stored in the world state with given id. - async ReadAsset(ctx, id) { - const asset = await readState(ctx, id); - await addPrivateData(ctx, asset.ID, asset); - - return JSON.stringify(asset); - } - - // UpdateAsset updates an existing asset in the world state with provided parameters. - async UpdateAsset(ctx, id, color, size, owner, appraisedValue) { - const asset = await readState(ctx, id); - asset.Color = color; - asset.Size = size; - asset.Owner = owner; - asset.AppraisedValue = appraisedValue; - const assetBuffer = Buffer.from(JSON.stringify(asset)); - await savePrivateData(ctx, id); - - ctx.stub.setEvent('UpdateAsset', assetBuffer); - return ctx.stub.putState(id, assetBuffer); - } - - // DeleteAsset deletes an given asset from the world state. - async DeleteAsset(ctx, id) { - const asset = await readState(ctx, id); - const assetBuffer = Buffer.from(JSON.stringify(asset)); - await removePrivateData(ctx, id); - - ctx.stub.setEvent('DeleteAsset', assetBuffer); - return ctx.stub.deleteState(id); - } -} - -module.exports = AssetTransferEvents; diff --git a/asset-transfer-events/chaincode-javascript/npm-shrinkwrap.json b/asset-transfer-events/chaincode-javascript/npm-shrinkwrap.json deleted file mode 100644 index 8f9fc8e5..00000000 --- a/asset-transfer-events/chaincode-javascript/npm-shrinkwrap.json +++ /dev/null @@ -1,3982 +0,0 @@ -{ - "name": "asset-transfer-events", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "asset-transfer-events", - "version": "1.0.0", - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "~2.5", - "fabric-shim": "~2.5" - }, - "devDependencies": { - "chai": "^4.4.1", - "eslint": "^8.57.0", - "mocha": "^10.4.0", - "nyc": "^15.1.0", - "sinon": "^18.0.0", - "sinon-chai": "^3.7.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@fidm/asn1": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@fidm/asn1/-/asn1-1.0.4.tgz", - "integrity": "sha512-esd1jyNvRb2HVaQGq2Gg8Z0kbQPXzV9Tq5Z14KNIov6KfFD6PTaRIO8UpcsYiTNzOqJpmyzWgVTrUwFV3UF4TQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@fidm/x509": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@fidm/x509/-/x509-1.2.1.tgz", - "integrity": "sha512-nwc2iesjyc9hkuzcrMCBXQRn653XuAUKorfWM8PZyJawiy1QzLj4vahwzaI25+pfpwOLvMzbJ0uKpWLDNmo16w==", - "dependencies": { - "@fidm/asn1": "^1.0.4", - "tweetnacl": "^1.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.10.9", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.9.tgz", - "integrity": "sha512-5tcgUctCG0qoNyfChZifz2tJqbRbXVO9J7X6duFcOjY3HUNCxg5D0ZCK7EP9vIcZ0zRpLU9bWkyCqVCLZ46IbQ==", - "dependencies": { - "@grpc/proto-loader": "^0.7.13", - "@js-sdsl/ordered-map": "^4.4.2" - }, - "engines": { - "node": ">=12.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@hyperledger/fabric-protos": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@hyperledger/fabric-protos/-/fabric-protos-0.2.1.tgz", - "integrity": "sha512-qjm0vIQIfCall804tWDeA8p/mUfu14sl5Sj+PbOn2yDKJq+7ThoIhNsLAqf+BCxUfqsoqQq6AojhqQeTFyOOqg==", - "dependencies": { - "@grpc/grpc-js": "^1.9.0", - "google-protobuf": "^3.21.0" - }, - "engines": { - "node": ">=14.15.0" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "16.18.98", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.98.tgz", - "integrity": "sha512-fpiC20NvLpTLAzo3oVBKIqBGR6Fx/8oAK/SSf7G+fydnXMY1x4x9RZ6sBXhqKlCU21g2QapUsbLlhv3+a7wS+Q==" - }, - "node_modules/@types/triple-beam": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "dependencies": { - "default-require-extensions": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001633", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001633.tgz", - "integrity": "sha512-6sT0yf/z5jqf8tISAgpJDrmwOpLsrpnyCdD/lOZKvKkkJK4Dn0X5i7KF7THEZhOq+30bmhwBlNEaqPUiHiKtZg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/class-transformer": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", - "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==" - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-eql": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/default-require-extensions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", - "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", - "dev": true, - "dependencies": { - "strip-bom": "^4.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.802", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.802.tgz", - "integrity": "sha512-TnTMUATbgNdPXVSHsxvNVSG0uEd6cSZsANjm8c9HbvflZVVn1yTRcmVXYT1Ma95/ssB/Dcd30AHweH2TE+dNpA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fabric-contract-api": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-contract-api/-/fabric-contract-api-2.5.6.tgz", - "integrity": "sha512-AosGb8tA+Jgt+pqMEgYNB3/J/P5QuWOC7yhXbhDmAAwUzn4Sc7pdWDICH1YyrFGZNFxMGQmqJmLVWUX8BKHy0w==", - "dependencies": { - "class-transformer": "^0.4.0", - "fabric-shim-api": "2.5.6", - "fast-safe-stringify": "^2.1.1", - "get-params": "^0.1.2", - "reflect-metadata": "^0.1.13", - "winston": "^3.7.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fabric-shim": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-shim/-/fabric-shim-2.5.6.tgz", - "integrity": "sha512-4Y8WNFhYuQ9QYSEgPXWdlXnrXjwOlM10sQQzE4kJ7cDh8a4LX0rn44FxtxTCB18lnzrSLMZ8/8Cr5m0c9NeXWA==", - "dependencies": { - "@fidm/x509": "^1.2.1", - "@grpc/grpc-js": "~1.10.9", - "@hyperledger/fabric-protos": "~0.2.1", - "@types/node": "^16.11.1", - "ajv": "^6.12.2", - "fabric-contract-api": "2.5.6", - "fabric-shim-api": "2.5.6", - "fast-safe-stringify": "^2.1.1", - "long": "^5.2.3", - "reflect-metadata": "^0.1.13", - "winston": "^3.7.2", - "yargs": "^17.4.0", - "yargs-parser": "^21.0.1" - }, - "bin": { - "fabric-chaincode-node": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fabric-shim-api": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-shim-api/-/fabric-shim-api-2.5.6.tgz", - "integrity": "sha512-1L0nO7CJ31/gEOWKWHEeCqgB5HkqPVfRbpcS7L9eTscT7tffjg2OkZISvC+a7RiqihL0iyrXNBgBg5MwlSSN9g==", - "engines": { - "eslint": "^6.6.0", - "node": ">=18" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-params": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/get-params/-/get-params-0.1.2.tgz", - "integrity": "sha512-41eOxtlGgHQRbFyA8KTH+w+32Em3cRdfBud7j67ulzmIfmaHX9doq47s0fa4P5o9H64BZX9nrYI6sJvk46Op+Q==" - }, - "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/google-protobuf": { - "version": "3.21.2", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz", - "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==" - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasha/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "dependencies": { - "append-transform": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", - "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", - "dev": true, - "dependencies": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.3", - "istanbul-lib-coverage": "^3.2.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/just-extend": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", - "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", - "dev": true - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" - }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/logform": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", - "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", - "dependencies": { - "@colors/colors": "1.6.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mocha": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", - "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", - "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "8.1.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/nise": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", - "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", - "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" - } - }, - "node_modules/node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "dependencies": { - "process-on-spawn": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/nyc/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/nyc/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/nyc/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nyc/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/nyc/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", - "dev": true - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "dependencies": { - "fromentries": "^1.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protobufjs": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.2.tgz", - "integrity": "sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reflect-metadata": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", - "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==" - }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", - "dev": true, - "dependencies": { - "es6-error": "^4.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/sinon": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", - "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.2.0", - "nise": "^6.0.0", - "supports-color": "^7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" - } - }, - "node_modules/sinon-chai": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", - "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", - "dev": true, - "peerDependencies": { - "chai": "^4.0.0", - "sinon": ">=4.0.0" - } - }, - "node_modules/sinon/node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "dependencies": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "engines": { - "node": "*" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/triple-beam": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", - "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "node_modules/winston": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.0.tgz", - "integrity": "sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==", - "dependencies": { - "@colors/colors": "^1.6.0", - "@dabh/diagnostics": "^2.0.2", - "async": "^3.2.3", - "is-stream": "^2.0.0", - "logform": "^2.4.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "safe-stable-stringify": "^2.3.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/winston-transport": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", - "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", - "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/asset-transfer-events/chaincode-javascript/package.json b/asset-transfer-events/chaincode-javascript/package.json deleted file mode 100644 index 05587582..00000000 --- a/asset-transfer-events/chaincode-javascript/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "asset-transfer-events", - "version": "1.0.0", - "description": "Asset-Transfer-Events contract implemented in JavaScript", - "main": "index.js", - "engines": { - "node": ">=18" - }, - "scripts": { - "lint": "eslint .", - "pretest": "npm run lint", - "test": "nyc mocha --recursive", - "start": "fabric-chaincode-node start" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "~2.5", - "fabric-shim": "~2.5" - }, - "devDependencies": { - "chai": "^4.4.1", - "eslint": "^8.57.0", - "mocha": "^10.4.0", - "nyc": "^15.1.0", - "sinon": "^18.0.0", - "sinon-chai": "^3.7.0" - }, - "nyc": { - "exclude": [ - "coverage/**", - "test/**", - "index.js", - ".eslintrc.js" - ], - "reporter": [ - "text-summary", - "html" - ], - "all": true, - "check-coverage": true, - "statements": 100, - "branches": 100, - "functions": 100, - "lines": 100 - } -} diff --git a/asset-transfer-events/chaincode-javascript/test/assetTransferEvents.test.js b/asset-transfer-events/chaincode-javascript/test/assetTransferEvents.test.js deleted file mode 100644 index 552b8ad7..00000000 --- a/asset-transfer-events/chaincode-javascript/test/assetTransferEvents.test.js +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -'use strict'; -const sinon = require('sinon'); -const chai = require('chai'); -const sinonChai = require('sinon-chai'); -const expect = chai.expect; - -const { Context } = require('fabric-contract-api'); -const { ChaincodeStub, ClientIdentity } = require('fabric-shim'); - -const AssetTransfer = require('../lib/assetTransferEvents.js'); - -let assert = sinon.assert; -chai.use(sinonChai); - -describe('Asset Transfer Events Tests', () => { - let transactionContext, chaincodeStub, clientIdentity, asset; - let transientMap, asset_properties; - - beforeEach(() => { - transactionContext = new Context(); - - chaincodeStub = sinon.createStubInstance(ChaincodeStub); - chaincodeStub.getMspID.returns('org1'); - transactionContext.setChaincodeStub(chaincodeStub); - - clientIdentity = sinon.createStubInstance(ClientIdentity); - clientIdentity.getMSPID.returns('org1'); - transactionContext.clientIdentity = clientIdentity; - - chaincodeStub.putState.callsFake((key, value) => { - if (!chaincodeStub.states) { - chaincodeStub.states = {}; - } - chaincodeStub.states[key] = value; - }); - - chaincodeStub.getState.callsFake(async (key) => { - let ret; - if (chaincodeStub.states) { - ret = chaincodeStub.states[key]; - } - return Promise.resolve(ret); - }); - - chaincodeStub.deleteState.callsFake(async (key) => { - if (chaincodeStub.states) { - delete chaincodeStub.states[key]; - } - return Promise.resolve(key); - }); - - chaincodeStub.getStateByRange.callsFake(async () => { - function* internalGetStateByRange() { - if (chaincodeStub.states) { - // Shallow copy - const copied = Object.assign({}, chaincodeStub.states); - - for (let key in copied) { - yield {value: copied[key]}; - } - } - } - - return Promise.resolve(internalGetStateByRange()); - }); - - asset = { - ID: 'asset1', - Color: 'blue', - Size: 5, - Owner: 'Tomoko', - AppraisedValue: 300, - }; - const randomNumber = Math.floor(Math.random() * 100) + 1; - asset_properties = { - object_type: 'asset_properties', - asset_id: 'asset1', - Price: '90', - salt: Buffer.from(randomNumber.toString()).toString('hex') - }; - transientMap = new Map(); - transientMap.set('asset_properties', Buffer.from(JSON.stringify(asset_properties))); - }); - - describe('Test CreateAsset', () => { - it('should return error on CreateAsset', async () => { - chaincodeStub.putState.rejects('failed inserting key'); - - let assetTransfer = new AssetTransfer(); - try { - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - assert.fail('CreateAsset should have failed'); - } catch(err) { - expect(err.name).to.equal('failed inserting key'); - } - }); - - it('should return success on CreateAsset', async () => { - let assetTransfer = new AssetTransfer(); - - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - let ret = JSON.parse((await chaincodeStub.getState(asset.ID)).toString()); - expect(ret).to.eql(asset); - }); - it('should return success on CreateAsset with transient data', async () => { - let assetTransfer = new AssetTransfer(); - chaincodeStub.getTransient.returns(transientMap); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - let ret = JSON.parse((await chaincodeStub.getState(asset.ID)).toString()); - expect(ret).to.eql(asset); - }); - }); - - describe('Test ReadAsset', () => { - it('should return error on ReadAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - try { - await assetTransfer.ReadAsset(transactionContext, 'asset2'); - assert.fail('ReadAsset should have failed'); - } catch (err) { - expect(err.message).to.equal('The asset asset2 does not exist'); - } - }); - - it('should return success on ReadAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - const assetString = await assetTransfer.ReadAsset(transactionContext, 'asset1'); - const readAsset = JSON.parse(assetString); - expect(readAsset).to.eql(asset); - }); - - it('should return success on ReadAsset with private data', async () => { - asset.asset_properties = asset_properties; - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - chaincodeStub.getPrivateData.returns(Buffer.from(JSON.stringify(asset_properties))); - const assetString = await assetTransfer.ReadAsset(transactionContext, 'asset1'); - const readAsset = JSON.parse(assetString); - expect(readAsset).to.eql(asset); - }); - }); - - describe('Test UpdateAsset', () => { - it('should return error on UpdateAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - try { - await assetTransfer.UpdateAsset(transactionContext, 'asset2', 'orange', 10, 'Me', 500); - assert.fail('UpdateAsset should have failed'); - } catch (err) { - expect(err.message).to.equal('The asset asset2 does not exist'); - } - }); - - it('should return success on UpdateAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - await assetTransfer.UpdateAsset(transactionContext, 'asset1', 'orange', 10, 'Me', 500); - let ret = JSON.parse(await chaincodeStub.getState(asset.ID)); - let expected = { - ID: 'asset1', - Color: 'orange', - Size: 10, - Owner: 'Me', - AppraisedValue: 500 - }; - expect(ret).to.eql(expected); - }); - }); - - describe('Test DeleteAsset', () => { - it('should return error on DeleteAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - try { - await assetTransfer.DeleteAsset(transactionContext, 'asset2'); - assert.fail('DeleteAsset should have failed'); - } catch (err) { - expect(err.message).to.equal('The asset asset2 does not exist'); - } - }); - - it('should return success on DeleteAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - await assetTransfer.DeleteAsset(transactionContext, asset.ID); - let ret = await chaincodeStub.getState(asset.ID); - expect(ret).to.equal(undefined); - }); - }); - - describe('Test TransferAsset', () => { - it('should return error on TransferAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - try { - await assetTransfer.TransferAsset(transactionContext, 'asset2', 'Me'); - assert.fail('DeleteAsset should have failed'); - } catch (err) { - expect(err.message).to.equal('The asset asset2 does not exist'); - } - }); - - it('should return success on TransferAsset', async () => { - let assetTransfer = new AssetTransfer(); - await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue); - - await assetTransfer.TransferAsset(transactionContext, asset.ID, 'Me'); - let ret = JSON.parse((await chaincodeStub.getState(asset.ID)).toString()); - expect(ret).to.eql(Object.assign({}, asset, {Owner: 'Me'})); - }); - }); -}); diff --git a/asset-transfer-ledger-queries/application-java/.gitattributes b/asset-transfer-ledger-queries/application-java/.gitattributes deleted file mode 100644 index 00a51aff..00000000 --- a/asset-transfer-ledger-queries/application-java/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# These are explicitly windows files and should use crlf -*.bat text eol=crlf - diff --git a/asset-transfer-ledger-queries/application-java/build.gradle b/asset-transfer-ledger-queries/application-java/build.gradle deleted file mode 100644 index a204249d..00000000 --- a/asset-transfer-ledger-queries/application-java/build.gradle +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * This generated file contains a sample Java project to get you started. - * For more details take a look at the Java Quickstart chapter in the Gradle - * User Manual available at https://docs.gradle.org/6.5/userguide/tutorial_java_projects.html - */ - -plugins { - // Apply the java plugin to add support for Java - id 'java' - - // Apply the application plugin to add support for building a CLI application. - id 'application' -} -ext { - javaMainClass = "application.java.App" -} - -repositories { - // You can declare any Maven/Ivy/file repository here. - mavenCentral() -} - -dependencies { - // This dependency is used by the application. - implementation 'com.google.guava:guava:29.0-jre' - implementation 'org.hyperledger.fabric:fabric-gateway-java:2.1.1' -} - -application { - // Define the main class for the application. - mainClassName = 'application.java.App' -} - -// task for running the app after building dependencies -task runApp(type: Exec) { - dependsOn build - group = "Execution" - description = "Run the main class with ExecTask" - commandLine "java", "-classpath", sourceSets.main.runtimeClasspath.getAsPath(), javaMainClass -} \ No newline at end of file diff --git a/asset-transfer-ledger-queries/application-java/gradle/wrapper/gradle-wrapper.jar b/asset-transfer-ledger-queries/application-java/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index d64cd491..00000000 Binary files a/asset-transfer-ledger-queries/application-java/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/asset-transfer-ledger-queries/application-java/gradle/wrapper/gradle-wrapper.properties b/asset-transfer-ledger-queries/application-java/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e2847c82..00000000 --- a/asset-transfer-ledger-queries/application-java/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/asset-transfer-ledger-queries/application-java/gradlew b/asset-transfer-ledger-queries/application-java/gradlew deleted file mode 100755 index 1aa94a42..00000000 --- a/asset-transfer-ledger-queries/application-java/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/asset-transfer-ledger-queries/application-java/gradlew.bat b/asset-transfer-ledger-queries/application-java/gradlew.bat deleted file mode 100644 index 25da30db..00000000 --- a/asset-transfer-ledger-queries/application-java/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/asset-transfer-ledger-queries/application-java/settings.gradle b/asset-transfer-ledger-queries/application-java/settings.gradle deleted file mode 100644 index 5423bc7d..00000000 --- a/asset-transfer-ledger-queries/application-java/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * The settings file is used to specify which projects to include in your build. - * - * Detailed information about configuring a multi-project build in Gradle can be found - * in the user manual at https://docs.gradle.org/6.5/userguide/multi_project_builds.html - */ - -rootProject.name = 'application-java' diff --git a/asset-transfer-ledger-queries/application-java/src/main/java/application/java/App.java b/asset-transfer-ledger-queries/application-java/src/main/java/application/java/App.java deleted file mode 100644 index 595d6f33..00000000 --- a/asset-transfer-ledger-queries/application-java/src/main/java/application/java/App.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -// Running TestApp: -// gradle runApp - -package application.java; - -import java.nio.file.Path; -import java.nio.file.Paths; -import org.hyperledger.fabric.gateway.Contract; -import org.hyperledger.fabric.gateway.Gateway; -import org.hyperledger.fabric.gateway.Network; -import org.hyperledger.fabric.gateway.Wallet; -import org.hyperledger.fabric.gateway.Wallets; - - -public class App { - - static { - System.setProperty("org.hyperledger.fabric.sdk.service_discovery.as_localhost", "true"); - } - - // helper function for getting connected to the gateway - public static Gateway connect() throws Exception{ - // Load a file system based wallet for managing identities. - Path walletPath = Paths.get("wallet"); - Wallet wallet = Wallets.newFileSystemWallet(walletPath); - // load a CCP - Path networkConfigPath = Paths.get("..", "..", "test-network", "organizations", "peerOrganizations", "org1.example.com", "connection-org1.yaml"); - - Gateway.Builder builder = Gateway.createBuilder(); - builder.identity(wallet, "appUser").networkConfig(networkConfigPath).discovery(true); - return builder.connect(); - } - - public static void main(String[] args) throws Exception { - // enrolls the admin and registers the user - try { - EnrollAdmin.main(null); - RegisterUser.main(null); - } catch (Exception e) { - System.err.println(e); - } - - // connect to the network and invoke the smart contract - try (Gateway gateway = connect()) { - - // get the network and contract - Network network = gateway.getNetwork("mychannel"); - Contract contract = network.getContract("ledger"); - - byte[] result; - - System.out.println("Submit Transaction: InitLedger creates the initial set of assets on the ledger."); - contract.submitTransaction("InitLedger"); - - System.out.println("\n"); - // passing in 2 empty strings will query all the assets - result = contract.evaluateTransaction("GetAssetsByRange", "", ""); - System.out.println("Evaluate Transaction: GetAssetsByRange, result: " + new String(result)); - - System.out.println("\n"); - System.out.println("Submit Transaction: CreateAsset asset13"); - // CreateAsset creates an asset with ID asset13, color yellow, owner Tom, size 5 and appraisedValue of 1300 - contract.submitTransaction("CreateAsset", "asset13", "yellow", "5", "Tom", "1300"); - - System.out.println("\n"); - System.out.println("Evaluate Transaction: ReadAsset asset13"); - // ReadAsset returns an asset with given assetID - result = contract.evaluateTransaction("ReadAsset", "asset13"); - System.out.println("result: " + new String(result)); - - System.out.println("\n"); - System.out.println("Evaluate Transaction: AssetExists asset1"); - // AssetExists returns "true" if an asset with given assetID exist - result = contract.evaluateTransaction("AssetExists", "asset1"); - System.out.println("result: " + new String(result)); - - System.out.println("\n"); - System.out.println("Submit Transaction: DeleteAsset asset1"); - contract.submitTransaction("DeleteAsset", "asset1"); - - System.out.println("\n"); - System.out.println("Evaluate Transaction: AssetExists asset1"); - // AssetExists returns "true" if an asset with given assetID exist - result = contract.evaluateTransaction("AssetExists", "asset1"); - System.out.println("result: " + new String(result)); - - System.out.println("\n"); - System.out.println("Submit Transaction: TransferAsset asset2 from owner Tomoko > owner Tom"); - // TransferAsset transfers an asset with given ID to new owner Tom - contract.submitTransaction("TransferAsset", "asset2", "Tom"); - - // Rich Query with Pagination (Only supported if CouchDB is used as state database) - System.out.println("\n"); - System.out.println("Evaluate Transaction:QueryAssetsWithPagination Tom's assets"); - result = contract.evaluateTransaction("QueryAssetsWithPagination","{\"selector\":{\"docType\":\"asset\",\"owner\":\"Tom\"}, \"use_index\":[\"_design/indexOwnerDoc\", \"indexOwner\"]}","3",""); - System.out.println("result: " + new String(result)); - - System.out.println("\n"); - System.out.println("Submit Transaction: TransferAssetByColor yellow assets > newOwner Michel"); - contract.submitTransaction("TransferAssetByColor", "yellow", "Michel"); - - // Rich Query (Only supported if CouchDB is used as state database): - System.out.println("\n"); - System.out.println("Evaluate Transaction:QueryAssetsByOwner Michel"); - result = contract.evaluateTransaction("QueryAssetsByOwner", "Michel"); - System.out.println("result: " + new String(result)); - - System.out.println("\n"); - System.out.println("Evaluate Transaction:GetAssetHistory asset13"); - result = contract.evaluateTransaction("GetAssetHistory", "asset13"); - System.out.println("result: " + new String(result)); - - // Rich Query (Only supported if CouchDB is used as state database): - System.out.println("\n"); - System.out.println("Evaluate Transaction:QueryAssets assets of size 15"); - result = contract.evaluateTransaction("QueryAssets", "{\"selector\":{\"size\":15}}"); - System.out.println("result: " + new String(result)); - - // Rich Query with index design doc and index name specified (Only supported if CouchDB is used as state database): - System.out.println("\n"); - System.out.println("Evaluate Transaction:QueryAssets Jin Soo's assets"); - result = contract.evaluateTransaction("QueryAssets","{\"selector\":{\"docType\":\"asset\",\"owner\":\"Jin Soo\"}, \"use_index\":[\"_design/indexOwnerDoc\", \"indexOwner\"]}"); - System.out.println("result: " + new String(result)); - - // Range Query with Pagination - System.out.println("\n"); - System.out.println("Evaluate Transaction:GetAssetsByRangeWithPagination assets 3-5"); - result = contract.evaluateTransaction("GetAssetsByRangeWithPagination", "asset3", "asset6", "3",""); - System.out.println("result: " + new String(result)); - } - catch(Exception e){ - System.err.println(e); - System.exit(1); - } - - } -} diff --git a/asset-transfer-ledger-queries/application-java/src/main/java/application/java/EnrollAdmin.java b/asset-transfer-ledger-queries/application-java/src/main/java/application/java/EnrollAdmin.java deleted file mode 100644 index 563a35f1..00000000 --- a/asset-transfer-ledger-queries/application-java/src/main/java/application/java/EnrollAdmin.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package application.java; - -import java.nio.file.Paths; -import java.util.Properties; - -import org.hyperledger.fabric.gateway.Wallet; -import org.hyperledger.fabric.gateway.Wallets; -import org.hyperledger.fabric.gateway.Identities; -import org.hyperledger.fabric.gateway.Identity; -import org.hyperledger.fabric.sdk.Enrollment; -import org.hyperledger.fabric.sdk.security.CryptoSuite; -import org.hyperledger.fabric.sdk.security.CryptoSuiteFactory; -import org.hyperledger.fabric_ca.sdk.EnrollmentRequest; -import org.hyperledger.fabric_ca.sdk.HFCAClient; - -public class EnrollAdmin { - - public static void main(String[] args) throws Exception { - - // Create a CA client for interacting with the CA. - Properties props = new Properties(); - props.put("pemFile", - "../../test-network/organizations/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem"); - props.put("allowAllHostNames", "true"); - HFCAClient caClient = HFCAClient.createNewInstance("https://localhost:7054", props); - CryptoSuite cryptoSuite = CryptoSuiteFactory.getDefault().getCryptoSuite(); - caClient.setCryptoSuite(cryptoSuite); - - // Create a wallet for managing identities - Wallet wallet = Wallets.newFileSystemWallet(Paths.get("wallet")); - - // Check to see if we've already enrolled the admin user. - if (wallet.get("admin") != null) { - System.out.println("An identity for the admin user \"admin\" already exists in the wallet"); - return; - } - - // Enroll the admin user, and import the new identity into the wallet. - final EnrollmentRequest enrollmentRequestTLS = new EnrollmentRequest(); - enrollmentRequestTLS.addHost("localhost"); - enrollmentRequestTLS.setProfile("tls"); - Enrollment enrollment = caClient.enroll("admin", "adminpw", enrollmentRequestTLS); - Identity user = Identities.newX509Identity("Org1MSP", enrollment); - wallet.put("admin", user); - System.out.println("Successfully enrolled user \"admin\" and imported it into the wallet"); - } -} diff --git a/asset-transfer-ledger-queries/application-java/src/main/java/application/java/RegisterUser.java b/asset-transfer-ledger-queries/application-java/src/main/java/application/java/RegisterUser.java deleted file mode 100644 index 367b4a39..00000000 --- a/asset-transfer-ledger-queries/application-java/src/main/java/application/java/RegisterUser.java +++ /dev/null @@ -1,107 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package application.java; - -import java.nio.file.Paths; -import java.security.PrivateKey; -import java.util.Properties; -import java.util.Set; - -import org.hyperledger.fabric.gateway.Wallet; -import org.hyperledger.fabric.gateway.Wallets; -import org.hyperledger.fabric.gateway.Identities; -import org.hyperledger.fabric.gateway.Identity; -import org.hyperledger.fabric.gateway.X509Identity; -import org.hyperledger.fabric.sdk.Enrollment; -import org.hyperledger.fabric.sdk.User; -import org.hyperledger.fabric.sdk.security.CryptoSuite; -import org.hyperledger.fabric.sdk.security.CryptoSuiteFactory; -import org.hyperledger.fabric_ca.sdk.HFCAClient; -import org.hyperledger.fabric_ca.sdk.RegistrationRequest; - -public class RegisterUser { - - public static void main(String[] args) throws Exception { - - // Create a CA client for interacting with the CA. - Properties props = new Properties(); - props.put("pemFile", - "../../test-network/organizations/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem"); - props.put("allowAllHostNames", "true"); - HFCAClient caClient = HFCAClient.createNewInstance("https://localhost:7054", props); - CryptoSuite cryptoSuite = CryptoSuiteFactory.getDefault().getCryptoSuite(); - caClient.setCryptoSuite(cryptoSuite); - - // Create a wallet for managing identities - Wallet wallet = Wallets.newFileSystemWallet(Paths.get("wallet")); - - // Check to see if we've already enrolled the user. - if (wallet.get("appUser") != null) { - System.out.println("An identity for the user \"appUser\" already exists in the wallet"); - return; - } - - X509Identity adminIdentity = (X509Identity)wallet.get("admin"); - if (adminIdentity == null) { - System.out.println("\"admin\" needs to be enrolled and added to the wallet first"); - return; - } - User admin = new User() { - - @Override - public String getName() { - return "admin"; - } - - @Override - public Set getRoles() { - return null; - } - - @Override - public String getAccount() { - return null; - } - - @Override - public String getAffiliation() { - return "org1.department1"; - } - - @Override - public Enrollment getEnrollment() { - return new Enrollment() { - - @Override - public PrivateKey getKey() { - return adminIdentity.getPrivateKey(); - } - - @Override - public String getCert() { - return Identities.toPemString(adminIdentity.getCertificate()); - } - }; - } - - @Override - public String getMspId() { - return "Org1MSP"; - } - - }; - - // Register the user, enroll the user, and import the new identity into the wallet. - RegistrationRequest registrationRequest = new RegistrationRequest("appUser"); - registrationRequest.setAffiliation("org1.department1"); - registrationRequest.setEnrollmentID("appUser"); - String enrollmentSecret = caClient.register(registrationRequest, admin); - Enrollment enrollment = caClient.enroll("appUser", enrollmentSecret); - Identity user = Identities.newX509Identity("Org1MSP", enrollment); - wallet.put("appUser", user); - System.out.println("Successfully enrolled user \"appUser\" and imported it into the wallet"); - } - -} diff --git a/asset-transfer-ledger-queries/application-java/src/main/resources/log4j.properties b/asset-transfer-ledger-queries/application-java/src/main/resources/log4j.properties deleted file mode 100644 index f1f841fe..00000000 --- a/asset-transfer-ledger-queries/application-java/src/main/resources/log4j.properties +++ /dev/null @@ -1,19 +0,0 @@ -# initialize root logger with level ERROR for stdout and fout -log4j.rootLogger=ERROR,stdout,fout -# set the log level for these components -log4j.logger.com.endeca=INFO -log4j.logger.com.endeca.itl.web.metrics=INFO - -# add a ConsoleAppender to the logger stdout to write to the console -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -# use a simple message format -log4j.appender.stdout.layout.ConversionPattern=%m%n - -# add a FileAppender to the logger fout -log4j.appender.fout=org.apache.log4j.FileAppender -# create a log file -log4j.appender.fout.File=crawl.log -log4j.appender.fout.layout=org.apache.log4j.PatternLayout -# use a more detailed message pattern -log4j.appender.fout.layout.ConversionPattern=%p\t%d{ISO8601}\t%r\t%c\t[%t]\t%m%n diff --git a/asset-transfer-ledger-queries/application-javascript/.eslintignore b/asset-transfer-ledger-queries/application-javascript/.eslintignore deleted file mode 100644 index 15958470..00000000 --- a/asset-transfer-ledger-queries/application-javascript/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -coverage diff --git a/asset-transfer-ledger-queries/application-javascript/.eslintrc.js b/asset-transfer-ledger-queries/application-javascript/.eslintrc.js deleted file mode 100644 index 072edaf6..00000000 --- a/asset-transfer-ledger-queries/application-javascript/.eslintrc.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ -'use strict'; - -module.exports = { - env: { - node: true, - mocha: true - }, - parserOptions: { - ecmaVersion: 8, - sourceType: 'script' - }, - extends: 'eslint:recommended', - rules: { - indent: ['error', 'tab'], - 'linebreak-style': ['error', 'unix'], - quotes: ['error', 'single'], - semi: ['error', 'always'], - 'no-unused-vars': ['error', { args: 'none' }], - 'no-console': 'off', - curly: 'error', - eqeqeq: 'error', - 'no-throw-literal': 'error', - strict: 'error', - 'no-var': 'error', - 'dot-notation': 'error', - 'no-trailing-spaces': 'error', - 'no-use-before-define': 'error', - 'no-useless-call': 'error', - 'no-with': 'error', - 'operator-linebreak': 'error', - yoda: 'error', - 'quote-props': ['error', 'as-needed'] - } -}; diff --git a/asset-transfer-ledger-queries/application-javascript/.gitignore b/asset-transfer-ledger-queries/application-javascript/.gitignore deleted file mode 100644 index 21b287f7..00000000 --- a/asset-transfer-ledger-queries/application-javascript/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -# Coverage directory used by tools like istanbul -coverage - -# Dependency directories -node_modules/ -jspm_packages/ -package-lock.json - -wallet -!wallet/.gitkeep diff --git a/asset-transfer-ledger-queries/application-javascript/app.js b/asset-transfer-ledger-queries/application-javascript/app.js deleted file mode 100644 index 0aa179a8..00000000 --- a/asset-transfer-ledger-queries/application-javascript/app.js +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const FabricCAServices = require('fabric-ca-client'); -const path = require('path'); -const { buildCAClient, registerAndEnrollUser, enrollAdmin } = require('../../test-application/javascript/CAUtil.js'); -const { buildCCPOrg1, buildWallet } = require('../../test-application/javascript/AppUtil.js'); - -const channelName = 'mychannel'; -const chaincodeName = 'ledger'; -const mspOrg1 = 'Org1MSP'; - -const walletPath = path.join(__dirname, 'wallet'); -const userId = 'appUser'; - -function prettyJSONString(inputString) { - return JSON.stringify(JSON.parse(inputString), null, 2); -} - -// pre-requisites: -// - fabric-sample two organization test-network setup with two peers, ordering service, -// and 2 certificate authorities, with the state database using couchdb -// ===> from directory /fabric-samples/test-network -// ./network.sh up createChannel -ca -s couchdb -// - Use any of the asset-transfer-ledger-queries chaincodes deployed on the channel "mychannel" -// with the chaincode name of "ledger". The following deploy command will package, -// install, approve, and commit the javascript chaincode, all the actions it takes -// to deploy a chaincode to a channel. -// ===> from directory /fabric-samples/test-network -// ./network.sh deployCC -ccn ledger -ccp ../asset-transfer-ledger-queries/chaincode-javascript/ -ccl javascript -// - Be sure that node.js is installed -// ===> from directory /fabric-samples/asset-transfer-ledger-queries/application-javascript -// node -v -// - npm installed code dependencies -// ===> from directory /fabric-samples/asset-transfer-ledger-queries/application-javascript -// npm install -// - to run this test application -// ===> from directory /fabric-samples/asset-transfer-ledger-queries/application-javascript -// node app.js - -// NOTE: If you see kind an error like these: -/* - 2020-08-07T20:23:17.590Z - error: [DiscoveryService]: send[mychannel] - Channel:mychannel received discovery error:access denied - ******** FAILED to run the application: Error: DiscoveryService: mychannel error: access denied - - OR - - Failed to register user : Error: fabric-ca request register failed with errors [[ { code: 20, message: 'Authentication failure' } ]] - ******** FAILED to run the application: Error: Identity not found in wallet: appUser -*/ -// Delete the /fabric-samples/asset-transfer-ledger-queries/application-javascript/wallet directory -// and retry this application. -// -// The certificate authority must have been restarted and the saved certificates for the -// admin and application user are not valid. Deleting the wallet store will force these to be reset -// with the new certificate authority. -// - -/** - * A test application to show ledger queries operations with any of the asset-transfer-ledger-queries chaincodes - * -- How to submit a transaction - * -- How to query and check the results - * - * To see the SDK workings, try setting the logging to show on the console before running - * export HFC_LOGGING='{"debug":"console"}' - */ -async function main() { - let skipInit = false; - if (process.argv.length > 2) { - if (process.argv[2] === 'skipInit') { - skipInit = true; - } - } - - try { - // build an in memory object with the network configuration (also known as a connection profile) - const ccp = buildCCPOrg1(); - - // build an instance of the fabric ca services client based on - // the information in the network configuration - const caClient = buildCAClient(FabricCAServices, ccp, 'ca.org1.example.com'); - - // setup the wallet to hold the credentials of the application user - const wallet = await buildWallet(Wallets, walletPath); - - // in a real application this would be done on an administrative flow, and only once - await enrollAdmin(caClient, wallet, mspOrg1); - - // in a real application this would be done only when a new user was required to be added - // and would be part of an administrative flow - await registerAndEnrollUser(caClient, wallet, mspOrg1, userId, 'org1.department1'); - - // Create a new gateway instance for interacting with the fabric network. - // In a real application this would be done as the backend server session is setup for - // a user that has been verified. - const gateway = new Gateway(); - - try { - // setup the gateway instance - // The user will now be able to create connections to the fabric network and be able to - // submit transactions and query. All transactions submitted by this gateway will be - // signed by this user using the credentials stored in the wallet. - await gateway.connect(ccp, { - wallet, - identity: userId, - discovery: { enabled: true, asLocalhost: true } // using asLocalhost as this gateway is using a fabric network deployed locally - }); - - // Build a network instance based on the channel where the smart contract is deployed - const network = await gateway.getNetwork(channelName); - - // Get the contract from the network. - const contract = network.getContract(chaincodeName); - - // Initialize a set of asset data on the channel using the chaincode 'InitLedger' function. - // This type of transaction would only be run once by an application the first time it was started after it - // deployed the first time. Any updates to the chaincode deployed later would likely not need to run - // an "init" type function. - if (!skipInit) { - try { - console.log('\n--> Submit Transaction: InitLedger, function creates the initial set of assets on the ledger'); - await contract.submitTransaction('InitLedger'); - console.log('*** Result: committed'); - } catch (initError) { - // this is error is OK if we are rerunning this app without restarting - console.log(`******** initLedger failed :: ${initError}`); - } - } else { - console.log('*** not executing "InitLedger'); - } - - let result; - - // Let's try a query operation (function). - // This will be sent to just one peer and the results will be shown. - console.log('\n--> Evaluate Transaction: GetAssetsByRange, function returns assets in a specific range from asset1 to before asset6'); - result = await contract.evaluateTransaction('GetAssetsByRange', 'asset1', 'asset6'); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - console.log('\n--> Evaluate Transaction: GetAssetsByRange, function use an open start and open end range to return assest1 to asset6'); - result = await contract.evaluateTransaction('GetAssetsByRange', '', ''); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - console.log('\n--> Evaluate Transaction: GetAssetsByRange, function use an fixed start (asset3) and open end range to return assest3 to asset6'); - result = await contract.evaluateTransaction('GetAssetsByRange', 'asset3', ''); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - console.log('\n--> Evaluate Transaction: GetAssetsByRange, function use an open start and fixed end (asset3) range to return assest1 to asset2'); - result = await contract.evaluateTransaction('GetAssetsByRange', '', 'asset3'); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - // Now let's try to submit a transaction. - // This will be sent to both peers and if both peers endorse the transaction, the endorsed proposal will be sent - // to the orderer to be committed by each of the peer's to the channel ledger. - console.log('\n--> Submit Transaction: CreateAsset, creates new asset with ID(asset7), color(yellow), size(5), owner(Tom), and appraisedValue(1300) arguments'); - await contract.submitTransaction('CreateAsset', 'asset7', 'yellow', '5', 'Tom', '1300'); - console.log('*** Result: committed'); - - console.log('\n--> Evaluate Transaction: ReadAsset, function returns information about an asset with ID(asset7)'); - result = await contract.evaluateTransaction('ReadAsset', 'asset7'); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - console.log('\n--> Evaluate Transaction: AssetExists, function returns "true" if an asset with ID(asset7) exist'); - result = await contract.evaluateTransaction('AssetExists', 'asset7'); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - // Now let's try to submit a transaction that deletes an asset - // This will be sent to both peers and if both peers endorse the transaction, the endorsed proposal will be sent - // to the orderer to be committed by each of the peer's to the channel ledger. - console.log('\n--> Submit Transaction: DeleteAsset with ID(asset7)'); - await contract.submitTransaction('DeleteAsset', 'asset7'); - console.log('*** Result: committed'); - - console.log('\n--> Evaluate Transaction: AssetExists, function returns "false" if an asset with ID(asset7) does not exist'); - result = await contract.evaluateTransaction('AssetExists', 'asset7'); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - console.log('\n--> Submit Transaction: TransferAsset, transfer asset(asset2) to new owner(Max)'); - await contract.submitTransaction('TransferAsset', 'asset2', 'Max'); - console.log('*** Result: committed'); - - console.log('\n--> Evaluate Transaction: ReadAsset, function returns information about an asset with ID(asset2)'); - result = await contract.evaluateTransaction('ReadAsset', 'asset2'); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - // Rich Query with Pagination (Only supported if CouchDB is used as state database) - console.log('\n--> Evaluate Transaction: QueryAssetsWithPagination, function returns "Max" assets'); - result = await contract.evaluateTransaction('QueryAssetsWithPagination', '{"selector":{"docType":"asset","owner":"Max"}, "use_index":["_design/indexOwnerDoc", "indexOwner"]}', '1', ''); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - // Recover the bookmark from previous query. Normally it will be inside a variable. - const resultJson = JSON.parse(result.toString()); - - console.log('\n--> Evaluate Transaction: QueryAssetsWithPagination, function returns "Max" assets next page'); - result = await contract.evaluateTransaction('QueryAssetsWithPagination', '{"selector":{"docType":"asset","owner":"Max"}, "use_index":["_design/indexOwnerDoc", "indexOwner"]}', '1', resultJson.bookmark); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - console.log('\n--> Submit Transaction: TransferAssetByColor, transfer all yellow assets to new owner(Michel)'); - await contract.submitTransaction('TransferAssetByColor', 'yellow', 'Michel'); - console.log('*** Result: committed'); - - // Rich Query (Only supported if CouchDB is used as state database): - console.log('\n--> Evaluate Transaction: QueryAssetsByOwner, find all assets with owner(Michel)'); - result = await contract.evaluateTransaction('QueryAssetsByOwner', 'Michel'); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - console.log('\n--> Evaluate Transaction: GetAssetHistory, get the history of an asset(asset7)'); - result = await contract.evaluateTransaction('GetAssetHistory', 'asset7'); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - // Rich Query (Only supported if CouchDB is used as state database): - console.log('\n--> Evaluate Transaction: QueryAssets, assets of size 15'); - result = await contract.evaluateTransaction('QueryAssets', '{"selector":{"size":15}}'); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - // Rich Query with index design doc and index name specified (Only supported if CouchDB is used as state database): - console.log('\n--> Evaluate Transaction: QueryAssets, Jin Soo\'s assets'); - result = await contract.evaluateTransaction('QueryAssets', '{"selector":{"docType":"asset","owner":"Jin Soo"}, "use_index":["_design/indexOwnerDoc", "indexOwner"]}'); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - // Range Query with Pagination - console.log('\n--> Evaluate Transaction: GetAssetsByRangeWithPagination - get page 1 of assets from asset2 to asset6 (asset2, asset3)'); - result = await contract.evaluateTransaction('GetAssetsByRangeWithPagination', 'asset2', 'asset6', '2', ''); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - // Range Query with Pagination - console.log('\n--> Evaluate Transaction: GetAssetsByRangeWithPagination - get page 2 of assets from asset2 to asset6 (asset4, asset5)'); - result = await contract.evaluateTransaction('GetAssetsByRangeWithPagination', 'asset2', 'asset6', '2', 'asset4'); - console.log(`*** Result: ${prettyJSONString(result.toString())}`); - - console.log('*** all tests completed'); - } finally { - // Disconnect from the gateway when the application is closing - // This will close all connections to the network - gateway.disconnect(); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - process.exit(1); - } - - console.log('*** application ending'); - -} - -main(); diff --git a/asset-transfer-ledger-queries/application-javascript/package.json b/asset-transfer-ledger-queries/application-javascript/package.json deleted file mode 100644 index a3cafb86..00000000 --- a/asset-transfer-ledger-queries/application-javascript/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "asset-transfer-ledger-queries", - "version": "1.0.0", - "description": "Asset transfer ledger queries application implemented in JavaScript", - "engines": { - "node": ">=12", - "npm": ">=5" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "scripts": { - "run": "node app.js", - "lint": "eslint *.js" - }, - "dependencies": { - "fabric-ca-client": "^2.2.19", - "fabric-network": "^2.2.19" - }, - "devDependencies": { - "eslint": "^7.32.0" - } -} diff --git a/asset-transfer-ledger-queries/chaincode-go/META-INF/statedb/couchdb/indexes/indexOwner.json b/asset-transfer-ledger-queries/chaincode-go/META-INF/statedb/couchdb/indexes/indexOwner.json deleted file mode 100644 index 305f0904..00000000 --- a/asset-transfer-ledger-queries/chaincode-go/META-INF/statedb/couchdb/indexes/indexOwner.json +++ /dev/null @@ -1 +0,0 @@ -{"index":{"fields":["docType","owner"]},"ddoc":"indexOwnerDoc", "name":"indexOwner","type":"json"} diff --git a/asset-transfer-ledger-queries/chaincode-go/asset_transfer_ledger_chaincode.go b/asset-transfer-ledger-queries/chaincode-go/asset_transfer_ledger_chaincode.go deleted file mode 100644 index 45eb1ba0..00000000 --- a/asset-transfer-ledger-queries/chaincode-go/asset_transfer_ledger_chaincode.go +++ /dev/null @@ -1,469 +0,0 @@ -/* - SPDX-License-Identifier: Apache-2.0 -*/ - -/* -====CHAINCODE EXECUTION SAMPLES (CLI) ================== - -==== Invoke assets ==== -peer chaincode invoke -C myc1 -n asset_transfer -c '{"Args":["CreateAsset","asset1","blue","5","tom","35"]}' -peer chaincode invoke -C myc1 -n asset_transfer -c '{"Args":["CreateAsset","asset2","red","4","tom","50"]}' -peer chaincode invoke -C myc1 -n asset_transfer -c '{"Args":["CreateAsset","asset3","blue","6","tom","70"]}' -peer chaincode invoke -C myc1 -n asset_transfer -c '{"Args":["TransferAsset","asset2","jerry"]}' -peer chaincode invoke -C myc1 -n asset_transfer -c '{"Args":["TransferAssetByColor","blue","jerry"]}' -peer chaincode invoke -C myc1 -n asset_transfer -c '{"Args":["DeleteAsset","asset1"]}' - -==== Query assets ==== -peer chaincode query -C myc1 -n asset_transfer -c '{"Args":["ReadAsset","asset1"]}' -peer chaincode query -C myc1 -n asset_transfer -c '{"Args":["GetAssetsByRange","asset1","asset3"]}' -peer chaincode query -C myc1 -n asset_transfer -c '{"Args":["GetAssetHistory","asset1"]}' - -Rich Query (Only supported if CouchDB is used as state database): -peer chaincode query -C myc1 -n asset_transfer -c '{"Args":["QueryAssetsByOwner","tom"]}' -peer chaincode query -C myc1 -n asset_transfer -c '{"Args":["QueryAssets","{\"selector\":{\"owner\":\"tom\"}}"]}' - -Rich Query with Pagination (Only supported if CouchDB is used as state database): -peer chaincode query -C myc1 -n asset_transfer -c '{"Args":["QueryAssetsWithPagination","{\"selector\":{\"owner\":\"tom\"}}","3",""]}' - -INDEXES TO SUPPORT COUCHDB RICH QUERIES - -Indexes in CouchDB are required in order to make JSON queries efficient and are required for -any JSON query with a sort. Indexes may be packaged alongside -chaincode in a META-INF/statedb/couchdb/indexes directory. Each index must be defined in its own -text file with extension *.json with the index definition formatted in JSON following the -CouchDB index JSON syntax as documented at: -http://docs.couchdb.org/en/2.3.1/api/database/find.html#db-index - -This asset transfer ledger example chaincode demonstrates a packaged -index which you can find in META-INF/statedb/couchdb/indexes/indexOwner.json. - -If you have access to the your peer's CouchDB state database in a development environment, -you may want to iteratively test various indexes in support of your chaincode queries. You -can use the CouchDB Fauxton interface or a command line curl utility to create and update -indexes. Then once you finalize an index, include the index definition alongside your -chaincode in the META-INF/statedb/couchdb/indexes directory, for packaging and deployment -to managed environments. - -In the examples below you can find index definitions that support asset transfer ledger -chaincode queries, along with the syntax that you can use in development environments -to create the indexes in the CouchDB Fauxton interface or a curl command line utility. - - -Index for docType, owner. - -Example curl command line to define index in the CouchDB channel_chaincode database -curl -i -X POST -H "Content-Type: application/json" -d "{\"index\":{\"fields\":[\"docType\",\"owner\"]},\"name\":\"indexOwner\",\"ddoc\":\"indexOwnerDoc\",\"type\":\"json\"}" http://hostname:port/myc1_assets/_index - - -Index for docType, owner, size (descending order). - -Example curl command line to define index in the CouchDB channel_chaincode database: -curl -i -X POST -H "Content-Type: application/json" -d "{\"index\":{\"fields\":[{\"size\":\"desc\"},{\"docType\":\"desc\"},{\"owner\":\"desc\"}]},\"ddoc\":\"indexSizeSortDoc\", \"name\":\"indexSizeSortDesc\",\"type\":\"json\"}" http://hostname:port/myc1_assets/_index - -Rich Query with index design doc and index name specified (Only supported if CouchDB is used as state database): -peer chaincode query -C myc1 -n asset_transfer -c '{"Args":["QueryAssets","{\"selector\":{\"docType\":\"asset\",\"owner\":\"tom\"}, \"use_index\":[\"_design/indexOwnerDoc\", \"indexOwner\"]}"]}' - -Rich Query with index design doc specified only (Only supported if CouchDB is used as state database): -peer chaincode query -C myc1 -n asset_transfer -c '{"Args":["QueryAssets","{\"selector\":{\"docType\":{\"$eq\":\"asset\"},\"owner\":{\"$eq\":\"tom\"},\"size\":{\"$gt\":0}},\"fields\":[\"docType\",\"owner\",\"size\"],\"sort\":[{\"size\":\"desc\"}],\"use_index\":\"_design/indexSizeSortDoc\"}"]}' -*/ - -package main - -import ( - "encoding/json" - "fmt" - "log" - "time" - - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -const index = "color~name" - -// SimpleChaincode implements the fabric-contract-api-go programming model -type SimpleChaincode struct { - contractapi.Contract -} - -type Asset struct { - DocType string `json:"docType"` //docType is used to distinguish the various types of objects in state database - ID string `json:"ID"` //the field tags are needed to keep case from bouncing around - Color string `json:"color"` - Size int `json:"size"` - Owner string `json:"owner"` - AppraisedValue int `json:"appraisedValue"` -} - -// HistoryQueryResult structure used for returning result of history query -type HistoryQueryResult struct { - Record *Asset `json:"record"` - TxId string `json:"txId"` - Timestamp time.Time `json:"timestamp"` - IsDelete bool `json:"isDelete"` -} - -// PaginatedQueryResult structure used for returning paginated query results and metadata -type PaginatedQueryResult struct { - Records []*Asset `json:"records"` - FetchedRecordsCount int32 `json:"fetchedRecordsCount"` - Bookmark string `json:"bookmark"` -} - -// CreateAsset initializes a new asset in the ledger -func (t *SimpleChaincode) CreateAsset(ctx contractapi.TransactionContextInterface, assetID, color string, size int, owner string, appraisedValue int) error { - exists, err := t.AssetExists(ctx, assetID) - if err != nil { - return fmt.Errorf("failed to get asset: %v", err) - } - if exists { - return fmt.Errorf("asset already exists: %s", assetID) - } - - asset := &Asset{ - DocType: "asset", - ID: assetID, - Color: color, - Size: size, - Owner: owner, - AppraisedValue: appraisedValue, - } - assetBytes, err := json.Marshal(asset) - if err != nil { - return err - } - - err = ctx.GetStub().PutState(assetID, assetBytes) - if err != nil { - return err - } - - // Create an index to enable color-based range queries, e.g. return all blue assets. - // An 'index' is a normal key-value entry in the ledger. - // The key is a composite key, with the elements that you want to range query on listed first. - // In our case, the composite key is based on indexName~color~name. - // This will enable very efficient state range queries based on composite keys matching indexName~color~* - colorNameIndexKey, err := ctx.GetStub().CreateCompositeKey(index, []string{asset.Color, asset.ID}) - if err != nil { - return err - } - // Save index entry to world state. Only the key name is needed, no need to store a duplicate copy of the asset. - // Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value - value := []byte{0x00} - return ctx.GetStub().PutState(colorNameIndexKey, value) -} - -// ReadAsset retrieves an asset from the ledger -func (t *SimpleChaincode) ReadAsset(ctx contractapi.TransactionContextInterface, assetID string) (*Asset, error) { - assetBytes, err := ctx.GetStub().GetState(assetID) - if err != nil { - return nil, fmt.Errorf("failed to get asset %s: %v", assetID, err) - } - if assetBytes == nil { - return nil, fmt.Errorf("asset %s does not exist", assetID) - } - - var asset Asset - err = json.Unmarshal(assetBytes, &asset) - if err != nil { - return nil, err - } - - return &asset, nil -} - -// DeleteAsset removes an asset key-value pair from the ledger -func (t *SimpleChaincode) DeleteAsset(ctx contractapi.TransactionContextInterface, assetID string) error { - asset, err := t.ReadAsset(ctx, assetID) - if err != nil { - return err - } - - err = ctx.GetStub().DelState(assetID) - if err != nil { - return fmt.Errorf("failed to delete asset %s: %v", assetID, err) - } - - colorNameIndexKey, err := ctx.GetStub().CreateCompositeKey(index, []string{asset.Color, asset.ID}) - if err != nil { - return err - } - - // Delete index entry - return ctx.GetStub().DelState(colorNameIndexKey) -} - -// TransferAsset transfers an asset by setting a new owner name on the asset -func (t *SimpleChaincode) TransferAsset(ctx contractapi.TransactionContextInterface, assetID, newOwner string) error { - asset, err := t.ReadAsset(ctx, assetID) - if err != nil { - return err - } - - asset.Owner = newOwner - assetBytes, err := json.Marshal(asset) - if err != nil { - return err - } - - return ctx.GetStub().PutState(assetID, assetBytes) -} - -// constructQueryResponseFromIterator constructs a slice of assets from the resultsIterator -func constructQueryResponseFromIterator(resultsIterator shim.StateQueryIteratorInterface) ([]*Asset, error) { - var assets []*Asset - for resultsIterator.HasNext() { - queryResult, err := resultsIterator.Next() - if err != nil { - return nil, err - } - var asset Asset - err = json.Unmarshal(queryResult.Value, &asset) - if err != nil { - return nil, err - } - assets = append(assets, &asset) - } - - return assets, nil -} - -// GetAssetsByRange performs a range query based on the start and end keys provided. -// Read-only function results are not typically submitted to ordering. If the read-only -// results are submitted to ordering, or if the query is used in an update transaction -// and submitted to ordering, then the committing peers will re-execute to guarantee that -// result sets are stable between endorsement time and commit time. The transaction is -// invalidated by the committing peers if the result set has changed between endorsement -// time and commit time. -// Therefore, range queries are a safe option for performing update transactions based on query results. -func (t *SimpleChaincode) GetAssetsByRange(ctx contractapi.TransactionContextInterface, startKey, endKey string) ([]*Asset, error) { - resultsIterator, err := ctx.GetStub().GetStateByRange(startKey, endKey) - if err != nil { - return nil, err - } - defer resultsIterator.Close() - - return constructQueryResponseFromIterator(resultsIterator) -} - -// TransferAssetByColor will transfer assets of a given color to a certain new owner. -// Uses GetStateByPartialCompositeKey (range query) against color~name 'index'. -// Committing peers will re-execute range queries to guarantee that result sets are stable -// between endorsement time and commit time. The transaction is invalidated by the -// committing peers if the result set has changed between endorsement time and commit time. -// Therefore, range queries are a safe option for performing update transactions based on query results. -// Example: GetStateByPartialCompositeKey/RangeQuery -func (t *SimpleChaincode) TransferAssetByColor(ctx contractapi.TransactionContextInterface, color, newOwner string) error { - // Execute a key range query on all keys starting with 'color' - coloredAssetResultsIterator, err := ctx.GetStub().GetStateByPartialCompositeKey(index, []string{color}) - if err != nil { - return err - } - defer coloredAssetResultsIterator.Close() - - for coloredAssetResultsIterator.HasNext() { - responseRange, err := coloredAssetResultsIterator.Next() - if err != nil { - return err - } - - _, compositeKeyParts, err := ctx.GetStub().SplitCompositeKey(responseRange.Key) - if err != nil { - return err - } - - if len(compositeKeyParts) > 1 { - returnedAssetID := compositeKeyParts[1] - asset, err := t.ReadAsset(ctx, returnedAssetID) - if err != nil { - return err - } - asset.Owner = newOwner - assetBytes, err := json.Marshal(asset) - if err != nil { - return err - } - err = ctx.GetStub().PutState(returnedAssetID, assetBytes) - if err != nil { - return fmt.Errorf("transfer failed for asset %s: %v", returnedAssetID, err) - } - } - } - - return nil -} - -// QueryAssetsByOwner queries for assets based on the owners name. -// This is an example of a parameterized query where the query logic is baked into the chaincode, -// and accepting a single query parameter (owner). -// Only available on state databases that support rich query (e.g. CouchDB) -// Example: Parameterized rich query -func (t *SimpleChaincode) QueryAssetsByOwner(ctx contractapi.TransactionContextInterface, owner string) ([]*Asset, error) { - queryString := fmt.Sprintf(`{"selector":{"docType":"asset","owner":"%s"}}`, owner) - return getQueryResultForQueryString(ctx, queryString) -} - -// QueryAssets uses a query string to perform a query for assets. -// Query string matching state database syntax is passed in and executed as is. -// Supports ad hoc queries that can be defined at runtime by the client. -// If this is not desired, follow the QueryAssetsForOwner example for parameterized queries. -// Only available on state databases that support rich query (e.g. CouchDB) -// Example: Ad hoc rich query -func (t *SimpleChaincode) QueryAssets(ctx contractapi.TransactionContextInterface, queryString string) ([]*Asset, error) { - return getQueryResultForQueryString(ctx, queryString) -} - -// getQueryResultForQueryString executes the passed in query string. -// The result set is built and returned as a byte array containing the JSON results. -func getQueryResultForQueryString(ctx contractapi.TransactionContextInterface, queryString string) ([]*Asset, error) { - resultsIterator, err := ctx.GetStub().GetQueryResult(queryString) - if err != nil { - return nil, err - } - defer resultsIterator.Close() - - return constructQueryResponseFromIterator(resultsIterator) -} - -// GetAssetsByRangeWithPagination performs a range query based on the start and end key, -// page size and a bookmark. -// The number of fetched records will be equal to or lesser than the page size. -// Paginated range queries are only valid for read only transactions. -// Example: Pagination with Range Query -func (t *SimpleChaincode) GetAssetsByRangeWithPagination(ctx contractapi.TransactionContextInterface, startKey string, endKey string, pageSize int, bookmark string) (*PaginatedQueryResult, error) { - - resultsIterator, responseMetadata, err := ctx.GetStub().GetStateByRangeWithPagination(startKey, endKey, int32(pageSize), bookmark) - if err != nil { - return nil, err - } - defer resultsIterator.Close() - - assets, err := constructQueryResponseFromIterator(resultsIterator) - if err != nil { - return nil, err - } - - return &PaginatedQueryResult{ - Records: assets, - FetchedRecordsCount: responseMetadata.FetchedRecordsCount, - Bookmark: responseMetadata.Bookmark, - }, nil -} - -// QueryAssetsWithPagination uses a query string, page size and a bookmark to perform a query -// for assets. Query string matching state database syntax is passed in and executed as is. -// The number of fetched records would be equal to or lesser than the specified page size. -// Supports ad hoc queries that can be defined at runtime by the client. -// If this is not desired, follow the QueryAssetsForOwner example for parameterized queries. -// Only available on state databases that support rich query (e.g. CouchDB) -// Paginated queries are only valid for read only transactions. -// Example: Pagination with Ad hoc Rich Query -func (t *SimpleChaincode) QueryAssetsWithPagination(ctx contractapi.TransactionContextInterface, queryString string, pageSize int, bookmark string) (*PaginatedQueryResult, error) { - - return getQueryResultForQueryStringWithPagination(ctx, queryString, int32(pageSize), bookmark) -} - -// getQueryResultForQueryStringWithPagination executes the passed in query string with -// pagination info. The result set is built and returned as a byte array containing the JSON results. -func getQueryResultForQueryStringWithPagination(ctx contractapi.TransactionContextInterface, queryString string, pageSize int32, bookmark string) (*PaginatedQueryResult, error) { - - resultsIterator, responseMetadata, err := ctx.GetStub().GetQueryResultWithPagination(queryString, pageSize, bookmark) - if err != nil { - return nil, err - } - defer resultsIterator.Close() - - assets, err := constructQueryResponseFromIterator(resultsIterator) - if err != nil { - return nil, err - } - - return &PaginatedQueryResult{ - Records: assets, - FetchedRecordsCount: responseMetadata.FetchedRecordsCount, - Bookmark: responseMetadata.Bookmark, - }, nil -} - -// GetAssetHistory returns the chain of custody for an asset since issuance. -func (t *SimpleChaincode) GetAssetHistory(ctx contractapi.TransactionContextInterface, assetID string) ([]HistoryQueryResult, error) { - log.Printf("GetAssetHistory: ID %v", assetID) - - resultsIterator, err := ctx.GetStub().GetHistoryForKey(assetID) - if err != nil { - return nil, err - } - defer resultsIterator.Close() - - var records []HistoryQueryResult - for resultsIterator.HasNext() { - response, err := resultsIterator.Next() - if err != nil { - return nil, err - } - - var asset Asset - if len(response.Value) > 0 { - err = json.Unmarshal(response.Value, &asset) - if err != nil { - return nil, err - } - } else { - asset = Asset{ - ID: assetID, - } - } - - record := HistoryQueryResult{ - TxId: response.TxId, - Timestamp: response.Timestamp.AsTime(), - Record: &asset, - IsDelete: response.IsDelete, - } - records = append(records, record) - } - - return records, nil -} - -// AssetExists returns true when asset with given ID exists in the ledger. -func (t *SimpleChaincode) AssetExists(ctx contractapi.TransactionContextInterface, assetID string) (bool, error) { - assetBytes, err := ctx.GetStub().GetState(assetID) - if err != nil { - return false, fmt.Errorf("failed to read asset %s from world state. %v", assetID, err) - } - - return assetBytes != nil, nil -} - -// InitLedger creates the initial set of assets in the ledger. -func (t *SimpleChaincode) InitLedger(ctx contractapi.TransactionContextInterface) error { - assets := []Asset{ - {DocType: "asset", ID: "asset1", Color: "blue", Size: 5, Owner: "Tomoko", AppraisedValue: 300}, - {DocType: "asset", ID: "asset2", Color: "red", Size: 5, Owner: "Brad", AppraisedValue: 400}, - {DocType: "asset", ID: "asset3", Color: "green", Size: 10, Owner: "Jin Soo", AppraisedValue: 500}, - {DocType: "asset", ID: "asset4", Color: "yellow", Size: 10, Owner: "Max", AppraisedValue: 600}, - {DocType: "asset", ID: "asset5", Color: "black", Size: 15, Owner: "Adriana", AppraisedValue: 700}, - {DocType: "asset", ID: "asset6", Color: "white", Size: 15, Owner: "Michel", AppraisedValue: 800}, - } - - for _, asset := range assets { - err := t.CreateAsset(ctx, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue) - if err != nil { - return err - } - } - - return nil -} - -func main() { - chaincode, err := contractapi.NewChaincode(&SimpleChaincode{}) - if err != nil { - log.Panicf("Error creating asset chaincode: %v", err) - } - - if err := chaincode.Start(); err != nil { - log.Panicf("Error starting asset chaincode: %v", err) - } -} diff --git a/asset-transfer-ledger-queries/chaincode-go/go.mod b/asset-transfer-ledger-queries/chaincode-go/go.mod deleted file mode 100644 index 000abbbd..00000000 --- a/asset-transfer-ledger-queries/chaincode-go/go.mod +++ /dev/null @@ -1,28 +0,0 @@ -module github.com/hyperledger/fabric-samples/asset-transfer-ledger-queries/chaincode-go - -go 1.22.0 - -require ( - github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 - github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 -) - -require ( - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.36.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/asset-transfer-ledger-queries/chaincode-go/go.sum b/asset-transfer-ledger-queries/chaincode-go/go.sum deleted file mode 100644 index fa4d3b24..00000000 --- a/asset-transfer-ledger-queries/chaincode-go/go.sum +++ /dev/null @@ -1,61 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 h1:IhkHfrl5X/fVnmB6pWeCYCdIJRi9bxj+WTnVN8DtW3c= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0/go.mod h1:PHHaFffjw7p7n9bmCfcm7RqDqYdivNEsJdiNIKZo5Lk= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 h1:rmUoBmciB0GL/miqcbJmJbgp5QTWoJUrZo+CNxrNLF4= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0/go.mod h1:FeWeO/jwGjiME7ak3GufqKIcwkejtzrDG4QxbfKydWs= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/asset-transfer-ledger-queries/chaincode-javascript/.eslintignore b/asset-transfer-ledger-queries/chaincode-javascript/.eslintignore deleted file mode 100644 index 15958470..00000000 --- a/asset-transfer-ledger-queries/chaincode-javascript/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -coverage diff --git a/asset-transfer-ledger-queries/chaincode-javascript/.eslintrc.js b/asset-transfer-ledger-queries/chaincode-javascript/.eslintrc.js deleted file mode 100644 index 072edaf6..00000000 --- a/asset-transfer-ledger-queries/chaincode-javascript/.eslintrc.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ -'use strict'; - -module.exports = { - env: { - node: true, - mocha: true - }, - parserOptions: { - ecmaVersion: 8, - sourceType: 'script' - }, - extends: 'eslint:recommended', - rules: { - indent: ['error', 'tab'], - 'linebreak-style': ['error', 'unix'], - quotes: ['error', 'single'], - semi: ['error', 'always'], - 'no-unused-vars': ['error', { args: 'none' }], - 'no-console': 'off', - curly: 'error', - eqeqeq: 'error', - 'no-throw-literal': 'error', - strict: 'error', - 'no-var': 'error', - 'dot-notation': 'error', - 'no-trailing-spaces': 'error', - 'no-use-before-define': 'error', - 'no-useless-call': 'error', - 'no-with': 'error', - 'operator-linebreak': 'error', - yoda: 'error', - 'quote-props': ['error', 'as-needed'] - } -}; diff --git a/asset-transfer-ledger-queries/chaincode-javascript/META-INF/statedb/couchdb/indexes/indexOwner.json b/asset-transfer-ledger-queries/chaincode-javascript/META-INF/statedb/couchdb/indexes/indexOwner.json deleted file mode 100644 index 305f0904..00000000 --- a/asset-transfer-ledger-queries/chaincode-javascript/META-INF/statedb/couchdb/indexes/indexOwner.json +++ /dev/null @@ -1 +0,0 @@ -{"index":{"fields":["docType","owner"]},"ddoc":"indexOwnerDoc", "name":"indexOwner","type":"json"} diff --git a/asset-transfer-ledger-queries/chaincode-javascript/index.js b/asset-transfer-ledger-queries/chaincode-javascript/index.js deleted file mode 100644 index 5c7b6e0d..00000000 --- a/asset-transfer-ledger-queries/chaincode-javascript/index.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const CC = require('./lib/asset_transfer_ledger_chaincode.js'); - -module.exports.CC = CC; -module.exports.contracts = [ CC ]; diff --git a/asset-transfer-ledger-queries/chaincode-javascript/lib/asset_transfer_ledger_chaincode.js b/asset-transfer-ledger-queries/chaincode-javascript/lib/asset_transfer_ledger_chaincode.js deleted file mode 100644 index fbd92152..00000000 --- a/asset-transfer-ledger-queries/chaincode-javascript/lib/asset_transfer_ledger_chaincode.js +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 -*/ - -// ====CHAINCODE EXECUTION SAMPLES (CLI) ================== - -// ==== Invoke assets ==== -// peer chaincode invoke -C CHANNEL_NAME -n asset_transfer -c '{"Args":["CreateAsset","asset1","blue","35","Tom","100"]}' -// peer chaincode invoke -C CHANNEL_NAME -n asset_transfer -c '{"Args":["CreateAsset","asset2","red","50","Tom","150"]}' -// peer chaincode invoke -C CHANNEL_NAME -n asset_transfer -c '{"Args":["CreateAsset","asset3","blue","70","Tom","200"]}' -// peer chaincode invoke -C CHANNEL_NAME -n asset_transfer -c '{"Args":["TransferAsset","asset2","jerry"]}' -// peer chaincode invoke -C CHANNEL_NAME -n asset_transfer -c '{"Args":["TransferAssetByColor","blue","jerry"]}' -// peer chaincode invoke -C CHANNEL_NAME -n asset_transfer -c '{"Args":["DeleteAsset","asset1"]}' - -// ==== Query assets ==== -// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["ReadAsset","asset1"]}' -// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["GetAssetsByRange","asset1","asset3"]}' -// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["GetAssetHistory","asset1"]}' - -// Rich Query (Only supported if CouchDB is used as state database): -// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["QueryAssetsByOwner","Tom"]}' output issue -// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["QueryAssets","{\"selector\":{\"owner\":\"Tom\"}}"]}' - -// Rich Query with Pagination (Only supported if CouchDB is used as state database): -// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["QueryAssetsWithPagination","{\"selector\":{\"owner\":\"Tom\"}}","3",""]}' - -// INDEXES TO SUPPORT COUCHDB RICH QUERIES -// -// Indexes in CouchDB are required in order to make JSON queries efficient and are required for -// any JSON query with a sort. Indexes may be packaged alongside -// chaincode in a META-INF/statedb/couchdb/indexes directory. Each index must be defined in its own -// text file with extension *.json with the index definition formatted in JSON following the -// CouchDB index JSON syntax as documented at: -// http://docs.couchdb.org/en/2.3.1/api/database/find.html#db-index -// -// This asset transfer ledger example chaincode demonstrates a packaged -// index which you can find in META-INF/statedb/couchdb/indexes/indexOwner.json. -// -// If you have access to the your peer's CouchDB state database in a development environment, -// you may want to iteratively test various indexes in support of your chaincode queries. You -// can use the CouchDB Fauxton interface or a command line curl utility to create and update -// indexes. Then once you finalize an index, include the index definition alongside your -// chaincode in the META-INF/statedb/couchdb/indexes directory, for packaging and deployment -// to managed environments. -// -// In the examples below you can find index definitions that support asset transfer ledger -// chaincode queries, along with the syntax that you can use in development environments -// to create the indexes in the CouchDB Fauxton interface or a curl command line utility. -// - -// Index for docType, owner. -// -// Example curl command line to define index in the CouchDB channel_chaincode database -// curl -i -X POST -H "Content-Type: application/json" -d "{\"index\":{\"fields\":[\"docType\",\"owner\"]},\"name\":\"indexOwner\",\"ddoc\":\"indexOwnerDoc\",\"type\":\"json\"}" http://hostname:port/myc1_assets/_index -// - -// Index for docType, owner, size (descending order). -// -// Example curl command line to define index in the CouchDB channel_chaincode database -// curl -i -X POST -H "Content-Type: application/json" -d "{\"index\":{\"fields\":[{\"size\":\"desc\"},{\"docType\":\"desc\"},{\"owner\":\"desc\"}]},\"ddoc\":\"indexSizeSortDoc\", \"name\":\"indexSizeSortDesc\",\"type\":\"json\"}" http://hostname:port/myc1_assets/_index - -// Rich Query with index design doc and index name specified (Only supported if CouchDB is used as state database): -// peer chaincode query -C CHANNEL_NAME -n ledger -c '{"Args":["QueryAssets","{\"selector\":{\"docType\":\"asset\",\"owner\":\"Tom\"}, \"use_index\":[\"_design/indexOwnerDoc\", \"indexOwner\"]}"]}' - -// Rich Query with index design doc specified only (Only supported if CouchDB is used as state database): -// peer chaincode query -C CHANNEL_NAME -n ledger -c '{"Args":["QueryAssets","{\"selector\":{\"docType\":{\"$eq\":\"asset\"},\"owner\":{\"$eq\":\"Tom\"},\"size\":{\"$gt\":0}},\"fields\":[\"docType\",\"owner\",\"size\"],\"sort\":[{\"size\":\"desc\"}],\"use_index\":\"_design/indexSizeSortDoc\"}"]}' - -'use strict'; - -const {Contract} = require('fabric-contract-api'); - -class Chaincode extends Contract { - - // CreateAsset - create a new asset, store into chaincode state - async CreateAsset(ctx, assetID, color, size, owner, appraisedValue) { - const exists = await this.AssetExists(ctx, assetID); - if (exists) { - throw new Error(`The asset ${assetID} already exists`); - } - - // ==== Create asset object and marshal to JSON ==== - let asset = { - docType: 'asset', - assetID: assetID, - color: color, - size: size, - owner: owner, - appraisedValue: appraisedValue - }; - - - // === Save asset to state === - await ctx.stub.putState(assetID, Buffer.from(JSON.stringify(asset))); - let indexName = 'color~name'; - let colorNameIndexKey = await ctx.stub.createCompositeKey(indexName, [asset.color, asset.assetID]); - - // Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the marble. - // Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value - await ctx.stub.putState(colorNameIndexKey, Buffer.from('\u0000')); - } - - // ReadAsset returns the asset stored in the world state with given id. - async ReadAsset(ctx, id) { - const assetJSON = await ctx.stub.getState(id); // get the asset from chaincode state - if (!assetJSON || assetJSON.length === 0) { - throw new Error(`Asset ${id} does not exist`); - } - - return assetJSON.toString(); - } - - // delete - remove a asset key/value pair from state - async DeleteAsset(ctx, id) { - if (!id) { - throw new Error('Asset name must not be empty'); - } - - let exists = await this.AssetExists(ctx, id); - if (!exists) { - throw new Error(`Asset ${id} does not exist`); - } - - // to maintain the color~name index, we need to read the asset first and get its color - let valAsbytes = await ctx.stub.getState(id); // get the asset from chaincode state - let jsonResp = {}; - if (!valAsbytes) { - jsonResp.error = `Asset does not exist: ${id}`; - throw new Error(jsonResp); - } - let assetJSON; - try { - assetJSON = JSON.parse(valAsbytes.toString()); - } catch (err) { - jsonResp = {}; - jsonResp.error = `Failed to decode JSON of: ${id}`; - throw new Error(jsonResp); - } - await ctx.stub.deleteState(id); //remove the asset from chaincode state - - // delete the index - let indexName = 'color~name'; - let colorNameIndexKey = ctx.stub.createCompositeKey(indexName, [assetJSON.color, assetJSON.assetID]); - if (!colorNameIndexKey) { - throw new Error(' Failed to create the createCompositeKey'); - } - // Delete index entry to state. - await ctx.stub.deleteState(colorNameIndexKey); - } - - // TransferAsset transfers a asset by setting a new owner name on the asset - async TransferAsset(ctx, assetName, newOwner) { - - let assetAsBytes = await ctx.stub.getState(assetName); - if (!assetAsBytes || !assetAsBytes.toString()) { - throw new Error(`Asset ${assetName} does not exist`); - } - let assetToTransfer = {}; - try { - assetToTransfer = JSON.parse(assetAsBytes.toString()); //unmarshal - } catch (err) { - let jsonResp = {}; - jsonResp.error = 'Failed to decode JSON of: ' + assetName; - throw new Error(jsonResp); - } - assetToTransfer.owner = newOwner; //change the owner - - let assetJSONasBytes = Buffer.from(JSON.stringify(assetToTransfer)); - await ctx.stub.putState(assetName, assetJSONasBytes); //rewrite the asset - } - - // GetAssetsByRange performs a range query based on the start and end keys provided. - // Read-only function results are not typically submitted to ordering. If the read-only - // results are submitted to ordering, or if the query is used in an update transaction - // and submitted to ordering, then the committing peers will re-execute to guarantee that - // result sets are stable between endorsement time and commit time. The transaction is - // invalidated by the committing peers if the result set has changed between endorsement - // time and commit time. - // Therefore, range queries are a safe option for performing update transactions based on query results. - async GetAssetsByRange(ctx, startKey, endKey) { - - let resultsIterator = await ctx.stub.getStateByRange(startKey, endKey); - let results = await this._GetAllResults(resultsIterator, false); - - return JSON.stringify(results); - } - - // TransferAssetByColor will transfer assets of a given color to a certain new owner. - // Uses a GetStateByPartialCompositeKey (range query) against color~name 'index'. - // Committing peers will re-execute range queries to guarantee that result sets are stable - // between endorsement time and commit time. The transaction is invalidated by the - // committing peers if the result set has changed between endorsement time and commit time. - // Therefore, range queries are a safe option for performing update transactions based on query results. - // Example: GetStateByPartialCompositeKey/RangeQuery - async TransferAssetByColor(ctx, color, newOwner) { - // Query the color~name index by color - // This will execute a key range query on all keys starting with 'color' - let coloredAssetResultsIterator = await ctx.stub.getStateByPartialCompositeKey('color~name', [color]); - - // Iterate through result set and for each asset found, transfer to newOwner - let responseRange = await coloredAssetResultsIterator.next(); - while (!responseRange.done) { - if (!responseRange || !responseRange.value || !responseRange.value.key) { - return; - } - - let objectType; - let attributes; - ( - {objectType, attributes} = await ctx.stub.splitCompositeKey(responseRange.value.key) - ); - - console.log(objectType); - let returnedAssetName = attributes[1]; - - // Now call the transfer function for the found asset. - // Re-use the same function that is used to transfer individual assets - await this.TransferAsset(ctx, returnedAssetName, newOwner); - responseRange = await coloredAssetResultsIterator.next(); - } - } - - // QueryAssetsByOwner queries for assets based on a passed in owner. - // This is an example of a parameterized query where the query logic is baked into the chaincode, - // and accepting a single query parameter (owner). - // Only available on state databases that support rich query (e.g. CouchDB) - // Example: Parameterized rich query - async QueryAssetsByOwner(ctx, owner) { - let queryString = {}; - queryString.selector = {}; - queryString.selector.docType = 'asset'; - queryString.selector.owner = owner; - return await this.GetQueryResultForQueryString(ctx, JSON.stringify(queryString)); //shim.success(queryResults); - } - - // Example: Ad hoc rich query - // QueryAssets uses a query string to perform a query for assets. - // Query string matching state database syntax is passed in and executed as is. - // Supports ad hoc queries that can be defined at runtime by the client. - // If this is not desired, follow the QueryAssetsForOwner example for parameterized queries. - // Only available on state databases that support rich query (e.g. CouchDB) - async QueryAssets(ctx, queryString) { - return await this.GetQueryResultForQueryString(ctx, queryString); - } - - // GetQueryResultForQueryString executes the passed in query string. - // Result set is built and returned as a byte array containing the JSON results. - async GetQueryResultForQueryString(ctx, queryString) { - - let resultsIterator = await ctx.stub.getQueryResult(queryString); - let results = await this._GetAllResults(resultsIterator, false); - - return JSON.stringify(results); - } - - // Example: Pagination with Range Query - // GetAssetsByRangeWithPagination performs a range query based on the start & end key, - // page size and a bookmark. - // The number of fetched records will be equal to or lesser than the page size. - // Paginated range queries are only valid for read only transactions. - async GetAssetsByRangeWithPagination(ctx, startKey, endKey, pageSize, bookmark) { - - const {iterator, metadata} = await ctx.stub.getStateByRangeWithPagination(startKey, endKey, pageSize, bookmark); - let results = {}; - - results.results = await this._GetAllResults(iterator, false); - - results.fetchedRecordsCount = metadata.fetchedRecordsCount; - - results.bookmark = metadata.bookmark; - - return JSON.stringify(results); - } - - // Example: Pagination with Ad hoc Rich Query - // QueryAssetsWithPagination uses a query string, page size and a bookmark to perform a query - // for assets. Query string matching state database syntax is passed in and executed as is. - // The number of fetched records would be equal to or lesser than the specified page size. - // Supports ad hoc queries that can be defined at runtime by the client. - // If this is not desired, follow the QueryAssetsForOwner example for parameterized queries. - // Only available on state databases that support rich query (e.g. CouchDB) - // Paginated queries are only valid for read only transactions. - async QueryAssetsWithPagination(ctx, queryString, pageSize, bookmark) { - - const {iterator, metadata} = await ctx.stub.getQueryResultWithPagination(queryString, pageSize, bookmark); - let results = {}; - - results.results = await this._GetAllResults(iterator, false); - - results.fetchedRecordsCount = metadata.fetchedRecordsCount; - - results.bookmark = metadata.bookmark; - - return JSON.stringify(results); - } - - // GetAssetHistory returns the chain of custody for an asset since issuance. - async GetAssetHistory(ctx, assetName) { - - let resultsIterator = await ctx.stub.getHistoryForKey(assetName); - let results = await this._GetAllResults(resultsIterator, true); - - return JSON.stringify(results); - } - - // AssetExists returns true when asset with given ID exists in world state - async AssetExists(ctx, assetName) { - // ==== Check if asset already exists ==== - let assetState = await ctx.stub.getState(assetName); - return assetState && assetState.length > 0; - } - - // This is JavaScript so without Funcation Decorators, all functions are assumed - // to be transaction functions - // - // For internal functions... prefix them with _ - async _GetAllResults(iterator, isHistory) { - let allResults = []; - let res = await iterator.next(); - while (!res.done) { - if (res.value && res.value.value.toString()) { - let jsonRes = {}; - console.log(res.value.value.toString('utf8')); - if (isHistory && isHistory === true) { - jsonRes.TxId = res.value.txId; - jsonRes.Timestamp = res.value.timestamp; - try { - jsonRes.Value = JSON.parse(res.value.value.toString('utf8')); - } catch (err) { - console.log(err); - jsonRes.Value = res.value.value.toString('utf8'); - } - } else { - jsonRes.Key = res.value.key; - try { - jsonRes.Record = JSON.parse(res.value.value.toString('utf8')); - } catch (err) { - console.log(err); - jsonRes.Record = res.value.value.toString('utf8'); - } - } - allResults.push(jsonRes); - } - res = await iterator.next(); - } - iterator.close(); - return allResults; - } - - // InitLedger creates sample assets in the ledger - async InitLedger(ctx) { - const assets = [ - { - assetID: 'asset1', - color: 'blue', - size: 5, - owner: 'Tom', - appraisedValue: 100 - }, - { - assetID: 'asset2', - color: 'red', - size: 5, - owner: 'Brad', - appraisedValue: 100 - }, - { - assetID: 'asset3', - color: 'green', - size: 10, - owner: 'Jin Soo', - appraisedValue: 200 - }, - { - assetID: 'asset4', - color: 'yellow', - size: 10, - owner: 'Max', - appraisedValue: 200 - }, - { - assetID: 'asset5', - color: 'black', - size: 15, - owner: 'Adriana', - appraisedValue: 250 - }, - { - assetID: 'asset6', - color: 'white', - size: 15, - owner: 'Michel', - appraisedValue: 250 - }, - ]; - - for (const asset of assets) { - await this.CreateAsset( - ctx, - asset.assetID, - asset.color, - asset.size, - asset.owner, - asset.appraisedValue - ); - } - } -} - -module.exports = Chaincode; diff --git a/asset-transfer-ledger-queries/chaincode-javascript/npm-shrinkwrap.json b/asset-transfer-ledger-queries/chaincode-javascript/npm-shrinkwrap.json deleted file mode 100644 index 46c74951..00000000 --- a/asset-transfer-ledger-queries/chaincode-javascript/npm-shrinkwrap.json +++ /dev/null @@ -1,1733 +0,0 @@ -{ - "name": "asset-transfer-ledger-queries", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "asset-transfer-ledger-queries", - "version": "1.0.0", - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "~2.5", - "fabric-shim": "~2.5" - }, - "devDependencies": { - "eslint": "^8.57.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@fidm/asn1": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@fidm/asn1/-/asn1-1.0.4.tgz", - "integrity": "sha512-esd1jyNvRb2HVaQGq2Gg8Z0kbQPXzV9Tq5Z14KNIov6KfFD6PTaRIO8UpcsYiTNzOqJpmyzWgVTrUwFV3UF4TQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@fidm/x509": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@fidm/x509/-/x509-1.2.1.tgz", - "integrity": "sha512-nwc2iesjyc9hkuzcrMCBXQRn653XuAUKorfWM8PZyJawiy1QzLj4vahwzaI25+pfpwOLvMzbJ0uKpWLDNmo16w==", - "dependencies": { - "@fidm/asn1": "^1.0.4", - "tweetnacl": "^1.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.10.9", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.9.tgz", - "integrity": "sha512-5tcgUctCG0qoNyfChZifz2tJqbRbXVO9J7X6duFcOjY3HUNCxg5D0ZCK7EP9vIcZ0zRpLU9bWkyCqVCLZ46IbQ==", - "dependencies": { - "@grpc/proto-loader": "^0.7.13", - "@js-sdsl/ordered-map": "^4.4.2" - }, - "engines": { - "node": ">=12.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@hyperledger/fabric-protos": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@hyperledger/fabric-protos/-/fabric-protos-0.2.1.tgz", - "integrity": "sha512-qjm0vIQIfCall804tWDeA8p/mUfu14sl5Sj+PbOn2yDKJq+7ThoIhNsLAqf+BCxUfqsoqQq6AojhqQeTFyOOqg==", - "dependencies": { - "@grpc/grpc-js": "^1.9.0", - "google-protobuf": "^3.21.0" - }, - "engines": { - "node": ">=14.15.0" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@types/node": { - "version": "16.18.98", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.98.tgz", - "integrity": "sha512-fpiC20NvLpTLAzo3oVBKIqBGR6Fx/8oAK/SSf7G+fydnXMY1x4x9RZ6sBXhqKlCU21g2QapUsbLlhv3+a7wS+Q==" - }, - "node_modules/@types/triple-beam": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/class-transformer": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", - "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==" - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fabric-contract-api": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-contract-api/-/fabric-contract-api-2.5.6.tgz", - "integrity": "sha512-AosGb8tA+Jgt+pqMEgYNB3/J/P5QuWOC7yhXbhDmAAwUzn4Sc7pdWDICH1YyrFGZNFxMGQmqJmLVWUX8BKHy0w==", - "dependencies": { - "class-transformer": "^0.4.0", - "fabric-shim-api": "2.5.6", - "fast-safe-stringify": "^2.1.1", - "get-params": "^0.1.2", - "reflect-metadata": "^0.1.13", - "winston": "^3.7.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fabric-shim": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-shim/-/fabric-shim-2.5.6.tgz", - "integrity": "sha512-4Y8WNFhYuQ9QYSEgPXWdlXnrXjwOlM10sQQzE4kJ7cDh8a4LX0rn44FxtxTCB18lnzrSLMZ8/8Cr5m0c9NeXWA==", - "dependencies": { - "@fidm/x509": "^1.2.1", - "@grpc/grpc-js": "~1.10.9", - "@hyperledger/fabric-protos": "~0.2.1", - "@types/node": "^16.11.1", - "ajv": "^6.12.2", - "fabric-contract-api": "2.5.6", - "fabric-shim-api": "2.5.6", - "fast-safe-stringify": "^2.1.1", - "long": "^5.2.3", - "reflect-metadata": "^0.1.13", - "winston": "^3.7.2", - "yargs": "^17.4.0", - "yargs-parser": "^21.0.1" - }, - "bin": { - "fabric-chaincode-node": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fabric-shim-api": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-shim-api/-/fabric-shim-api-2.5.6.tgz", - "integrity": "sha512-1L0nO7CJ31/gEOWKWHEeCqgB5HkqPVfRbpcS7L9eTscT7tffjg2OkZISvC+a7RiqihL0iyrXNBgBg5MwlSSN9g==", - "engines": { - "eslint": "^6.6.0", - "node": ">=18" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-params": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/get-params/-/get-params-0.1.2.tgz", - "integrity": "sha512-41eOxtlGgHQRbFyA8KTH+w+32Em3cRdfBud7j67ulzmIfmaHX9doq47s0fa4P5o9H64BZX9nrYI6sJvk46Op+Q==" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/google-protobuf": { - "version": "3.21.2", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz", - "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/logform": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", - "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", - "dependencies": { - "@colors/colors": "1.6.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/protobufjs": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.2.tgz", - "integrity": "sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/reflect-metadata": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", - "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==" - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "engines": { - "node": "*" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/triple-beam": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", - "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/winston": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.0.tgz", - "integrity": "sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==", - "dependencies": { - "@colors/colors": "^1.6.0", - "@dabh/diagnostics": "^2.0.2", - "async": "^3.2.3", - "is-stream": "^2.0.0", - "logform": "^2.4.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "safe-stable-stringify": "^2.3.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/winston-transport": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", - "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", - "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/asset-transfer-ledger-queries/chaincode-javascript/package.json b/asset-transfer-ledger-queries/chaincode-javascript/package.json deleted file mode 100644 index 384069fa..00000000 --- a/asset-transfer-ledger-queries/chaincode-javascript/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "asset-transfer-ledger-queries", - "version": "1.0.0", - "description": "asset chaincode implemented in node.js", - "main": "index.js", - "engines": { - "node": ">=18" - }, - "scripts": { - "start": "fabric-chaincode-node start", - "lint": "eslint *.js */**.js", - "test": "" - }, - "engine-strict": true, - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "~2.5", - "fabric-shim": "~2.5" - }, - "devDependencies": { - "eslint": "^8.57.0" - } -} diff --git a/asset-transfer-private-data/README.md b/asset-transfer-private-data/README.md deleted file mode 100644 index 0df860a8..00000000 --- a/asset-transfer-private-data/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# Asset transfer private data sample - -The asset transfer private data sample demonstrates: - -- Usage of organization private data collections -- Read data from the organization private data collection. -- Store data in organization private data collection. - -For more information about private data, visit the -[Private Data](https://hyperledger-fabric.readthedocs.io/en/latest/private-data-arch.html) -page in the Fabric documentation. - -## About the sample - -This sample includes smart contract and application code in multiple languages. In a use-case similar to basic asset transfer (see [asset-transfer-basic](../asset-transfer-basic) folder) this sample shows sending and receiving of asset along with its private data owned by organizations during create / delete of an asset , and during transfer of an asset to a new owner. - -### Application - -Please refer the below link to understand the application flow. -https://hyperledger-fabric.readthedocs.io/en/latest/private-data/private-data.html#example-scenario-asset-transfer-using-private-data-collections - -### Smart Contract - -The smart contract (in folder `chaincode-xyz`) implements the following functions to support the application: - -CreateAsset -AgreeToTransfer -TransferAsset -DeleteAsset -DeleteTranferAgreement - -ReadAsset -ReadAssetPrivateDetails -ReadTransferAgreement -GetAssetByRange -QueryAssetByOwner -QueryAssets -getQueryResultForQueryString - -## Running the sample - -Like other samples, the Fabric test network is used to deploy and run this sample. Follow these steps in order: - -1. Create the test network and a channel (from the `test-network` folder). - ``` - ./network.sh up createChannel -c mychannel -ca - ``` - -2. Deploy one of the smart contract implementations (from the `test-network` folder). - ``` - # To deploy the Java chaincode implementation - ./network.sh deployCC -ccn private -ccp ../asset-transfer-private-data/chaincode-java -ccl java -ccep "OR('Org1MSP.peer','Org2MSP.peer')" -cccg '../asset-transfer-private-data/chaincode-java/collections_config.json' -ccep "OR('Org1MSP.peer','Org2MSP.peer')" - - # To deploy the go chaincode implementation - ./network.sh deployCC -ccn private -ccp ../asset-transfer-private-data/chaincode-go -ccl go -ccep "OR('Org1MSP.peer','Org2MSP.peer')" -cccg '../asset-transfer-private-data/chaincode-go/collections_config.json' -ccep "OR('Org1MSP.peer','Org2MSP.peer')" - - # To deploy the typescript chaincode implementation - ./network.sh deployCC -ccn private -ccp ../asset-transfer-private-data/chaincode-typescript/ -ccl typescript -ccep "OR('Org1MSP.peer','Org2MSP.peer')" -cccg ../asset-transfer-private-data/chaincode-typescript/collections_config.json - ``` - -3. Run the application (from the `asset-transfer-private-data` folder). - ``` - # To run the Typescript sample application - cd application-gateway-typescript - npm install - npm start - - # To run the Go sample application - cd application-gateway-go - go run . - ``` - -## Clean up - -When you are finished, you can bring down the test network (from the `test-network` folder). The command will remove all the nodes of the test network, and delete any ledger data that you created. - -``` -./network.sh down -``` diff --git a/asset-transfer-private-data/application-gateway-go/app.go b/asset-transfer-private-data/application-gateway-go/app.go deleted file mode 100644 index 5274e3ab..00000000 --- a/asset-transfer-private-data/application-gateway-go/app.go +++ /dev/null @@ -1,398 +0,0 @@ -/* -Copyright 2024 IBM All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "strings" - "time" - - "github.com/hyperledger/fabric-gateway/pkg/client" - "github.com/hyperledger/fabric-gateway/pkg/hash" - "github.com/hyperledger/fabric-protos-go-apiv2/gateway" - "google.golang.org/grpc/status" -) - -type transient = map[string][]byte - -const ( - channelName = "mychannel" - chaincodeName = "private" - mspIDOrg1 = "Org1MSP" - mspIDOrg2 = "Org2MSP" - - // Collection names. - org1PrivateCollectionName = "Org1MSPPrivateCollection" - org2PrivateCollectionName = "Org2MSPPrivateCollection" - - Red = "\033[31m" - Reset = "\033[0m" -) - -// Use a unique key so that we can run multiple times. -var now = time.Now() -var assetID1 = fmt.Sprintf("asset%d", now.Unix()) -var assetID2 = fmt.Sprintf("asset%d", now.Unix()+1) - -func main() { - clientOrg1 := newGrpcConnection( - tlsCertPathOrg1, - peerEndpointOrg1, - peerNameOrg1, - ) - defer clientOrg1.Close() - - gatewayOrg1, err := client.Connect( - newIdentity(certDirectoryPathOrg1, mspIDOrg1), - client.WithSign(newSign(keyDirectoryPathOrg1)), - client.WithClientConnection(clientOrg1), - client.WithHash(hash.SHA256), - ) - if err != nil { - panic(err) - } - defer gatewayOrg1.Close() - - clientOrg2 := newGrpcConnection( - tlsCertPathOrg2, - peerEndpointOrg2, - peerNameOrg2, - ) - defer clientOrg2.Close() - - gatewayOrg2, err := client.Connect( - newIdentity(certDirectoryPathOrg2, mspIDOrg2), - client.WithSign(newSign(keyDirectoryPathOrg2)), - client.WithClientConnection(clientOrg2), - client.WithHash(hash.SHA256), - ) - if err != nil { - panic(err) - } - defer gatewayOrg2.Close() - - // Get the smart contract as an Org1 client. - contractOrg1 := gatewayOrg1.GetNetwork(channelName).GetContract(chaincodeName) - - // Get the smart contract as an Org1 client. - contractOrg2 := gatewayOrg2.GetNetwork(channelName).GetContract(chaincodeName) - - fmt.Println("~~~~~~~~~~~~~~~~ As Org1 Client ~~~~~~~~~~~~~~~~") - - // Create new assets on the ledger. - createAssets(contractOrg1) - - // Read asset from the Org1's private data collection with ID in the given range. - getAssetByRange(contractOrg1) - - // Attempt to transfer asset without prior approval from Org2, transaction expected to fail. - fmt.Println("\nAttempt TransferAsset without prior AgreeToTransfer") - err = transferAsset(contractOrg1, assetID1) - if err == nil { - doFail("TransferAsset transaction succeeded when it was expected to fail") - } - fmt.Printf("*** Received expected error: %+v\n", errorWithDetails(err)) - - fmt.Println("\n~~~~~~~~~~~~~~~~ As Org2 Client ~~~~~~~~~~~~~~~~") - - // Read the asset by ID. - readAssetByID(contractOrg2, assetID1) - - // Make agreement to transfer the asset from Org1 to Org2. - agreeToTransfer(contractOrg2, assetID1) - - fmt.Println("\n~~~~~~~~~~~~~~~~ As Org1 Client ~~~~~~~~~~~~~~~~") - - // Read transfer agreement. - readTransferAgreement(contractOrg1, assetID1) - - // Transfer asset to Org2. - if err := transferAsset(contractOrg1, assetID1); err != nil { - doFail(fmt.Sprintf("TransferAsset transaction failed when it was expected to succeed: %+v\n", errorWithDetails(err))) - } - - // Again ReadAsset: results will show that the buyer identity now owns the asset. - readAssetByID(contractOrg1, assetID1) - - // Confirm that transfer removed the private details from the Org1 collection. - org1ReadSuccess := readAssetPrivateDetails(contractOrg1, assetID1, org1PrivateCollectionName) - if org1ReadSuccess { - doFail(fmt.Sprintf("Asset private data still exists in %s", org1PrivateCollectionName)) - } - - fmt.Println("\n~~~~~~~~~~~~~~~~ As Org2 Client ~~~~~~~~~~~~~~~~") - - // Org2 can read asset private details: Org2 is owner, and private details exist in new owner's Collection. - org2ReadSuccess := readAssetPrivateDetails(contractOrg2, assetID1, org2PrivateCollectionName) - if !org2ReadSuccess { - doFail(fmt.Sprintf("Asset private data not found in %s", org2PrivateCollectionName)) - } - - fmt.Println("\nAttempt DeleteAsset using non-owner organization") - err = deleteAsset(contractOrg2, assetID2) - if err == nil { - doFail("DeleteAsset transaction succeeded when it was expected to fail") - } - fmt.Printf("*** Received expected error: %+v\n", errorWithDetails(err)) - - fmt.Println("\n~~~~~~~~~~~~~~~~ As Org1 Client ~~~~~~~~~~~~~~~~") - - // Delete AssetID2 as Org1. - if err := deleteAsset(contractOrg1, assetID2); err != nil { - doFail(fmt.Sprintf("DeleteAsset transaction failed when it was expected to succeed: %+v\n", errorWithDetails(err))) - } - - // Trigger a purge of the private data for the asset. - // The previous delete is optional if purge is used. - if err := purgeAsset(contractOrg1, assetID2); err != nil { - doFail(fmt.Sprintf("PurgeAsset transaction failed when it was expected to succeed: %+v\n", errorWithDetails(err))) - } -} - -func createAssets(contract *client.Contract) { - assetType := "ValuableAsset" - - fmt.Printf("\n--> Submit Transaction: CreateAsset, ID: %s\n", assetID1) - - type assetTransientInput struct { - ObjectType string - AssetID string - Color string - Size uint8 - AppraisedValue uint16 - } - - asset1Data := assetTransientInput{ - ObjectType: assetType, - AssetID: assetID1, - Color: "green", - Size: 20, - AppraisedValue: 100, - } - - if _, err := contract.Submit( - "CreateAsset", - client.WithTransient(transient{ - "asset_properties": marshal(asset1Data), - }), - ); err != nil { - panic(err) - } - - logTxCommitSuccess() - fmt.Printf("\n--> Submit Transaction: CreateAsset, ID: %s\n", assetID2) - - asset2Data := assetTransientInput{ - ObjectType: assetType, - AssetID: assetID2, - Color: "blue", - Size: 35, - AppraisedValue: 727, - } - - if _, err := contract.Submit( - "CreateAsset", - client.WithTransient(transient{ - "asset_properties": marshal(asset2Data), - }), - ); err != nil { - panic(err) - } - - logTxCommitSuccess() -} - -func getAssetByRange(contract *client.Contract) { - // GetAssetByRange returns assets on the ledger with ID in the range of startKey (inclusive) and endKey (exclusive). - fmt.Printf("\n--> Evaluate Transaction: GetAssetByRange from %s\n", org1PrivateCollectionName) - - resultBytes, err := contract.EvaluateTransaction("GetAssetByRange", assetID1, fmt.Sprintf("asset%d", now.Unix()+2)) - if err != nil { - panic(err) - } - - if len(resultBytes) == 0 { - doFail("Received empty query list for GetAssetByRange") - } - - fmt.Printf("*** Result: %s\n", formatJSON(resultBytes)) -} - -func readAssetByID(contract *client.Contract, assetID string) { - fmt.Printf("\n--> Evaluate Transaction: ReadAsset, ID: %s\n", assetID) - - resultBytes, err := contract.EvaluateTransaction("ReadAsset", assetID) - if err != nil { - panic(err) - } - - if len(resultBytes) == 0 { - doFail("Received empty result for ReadAsset") - } - - fmt.Printf("*** Result: %s\n", formatJSON(resultBytes)) -} - -func agreeToTransfer(contract *client.Contract, assetID string) { - // Buyer from Org2 agrees to buy the asset. - // To purchase the asset, the buyer needs to agree to the same value as the asset owner. - dataForAgreement := struct { - AssetID string `json:"assetID"` - AppraisedValue int `json:"appraisedValue"` - }{assetID, 100} - fmt.Printf("\n--> Submit Transaction: AgreeToTransfer, payload: %+v\n", dataForAgreement) - - if _, err := contract.Submit( - "AgreeToTransfer", - client.WithTransient(transient{ - "asset_value": marshal(dataForAgreement), - }), - ); err != nil { - panic(err) - } - - logTxCommitSuccess() -} - -func readTransferAgreement(contract *client.Contract, assetID string) { - fmt.Printf("\n--> Evaluate Transaction: ReadTransferAgreement, ID: %s\n", assetID) - - resultBytes, err := contract.EvaluateTransaction("ReadTransferAgreement", assetID) - if err != nil { - panic(err) - } - - if len(resultBytes) == 0 { - doFail("Received empty result for ReadTransferAgreement") - } - - fmt.Printf("*** Result: %s\n", formatJSON(resultBytes)) -} - -func transferAsset(contract *client.Contract, assetID string) (err error) { - fmt.Printf("\n--> Submit Transaction: TransferAsset, ID: %s\n", assetID) - - buyerDetails := struct { - AssetID string `json:"assetID"` - BuyerMSP string `json:"buyerMSP"` - }{assetID, mspIDOrg2} - - if _, err = contract.Submit( - "TransferAsset", - client.WithTransient(transient{ - "asset_owner": marshal(buyerDetails), - }), - ); err != nil { - return - } - - logTxCommitSuccess() - return -} - -func deleteAsset(contract *client.Contract, assetID string) (err error) { - fmt.Printf("\n--> Submit Transaction: DeleteAsset, ID: %s\n", assetID) - - dataForDelete := struct{ AssetID string }{assetID} - - if _, err = contract.Submit( - "DeleteAsset", - client.WithTransient(transient{ - "asset_delete": marshal(dataForDelete), - }), - ); err != nil { - return - } - - logTxCommitSuccess() - return -} - -func purgeAsset(contract *client.Contract, assetID string) (err error) { - fmt.Printf("\n--> Submit Transaction: PurgeAsset, ID: %s\n", assetID) - - dataForPurge := struct{ AssetID string }{assetID} - - if _, err = contract.Submit( - "PurgeAsset", - client.WithTransient(transient{ - "asset_purge": marshal(dataForPurge), - }), - ); err != nil { - return - } - - logTxCommitSuccess() - return -} - -func readAssetPrivateDetails(contract *client.Contract, assetID, collectionName string) bool { - fmt.Printf("\n--> Evaluate Transaction: ReadAssetPrivateDetails from %s, ID: %s\n", collectionName, assetID) - - resultBytes, err := contract.EvaluateTransaction("ReadAssetPrivateDetails", collectionName, assetID) - if err != nil { - panic(err) - } - - if len(resultBytes) == 0 { - fmt.Println("*** No result") - return false - } - - fmt.Printf("*** Result: %s\n", formatJSON(resultBytes)) - - return true -} - -func marshal(value any) []byte { - valueAsBytes, err := json.Marshal(&value) - if err != nil { - panic(err) - } - - return valueAsBytes -} - -func logTxCommitSuccess() { - fmt.Println("*** Transaction committed successfully") -} - -func doFail(msg string) { - fmt.Println(Red + msg + Reset) - panic(errors.New(msg)) -} - -func formatJSON(data []byte) string { - var result bytes.Buffer - if err := json.Indent(&result, data, "", " "); err != nil { - panic(fmt.Errorf("failed to parse JSON: %w", err)) - } - return result.String() -} - -func errorWithDetails(err error) error { - var buf strings.Builder - - statusErr := status.Convert(err) - errDetails := statusErr.Details() - if len(errDetails) > 0 { - buf.WriteString("\nError Details:") - - for _, errDetail := range errDetails { - if detail, ok := errDetail.(*gateway.ErrorDetail); ok { - buf.WriteString(fmt.Sprintf("\n- address: %s", detail.GetAddress())) - buf.WriteString(fmt.Sprintf("\n- mspID: %s", detail.GetMspId())) - buf.WriteString(fmt.Sprintf("\n- message: %s\n", detail.GetMessage())) - } - } - } - - return fmt.Errorf("%w%s", err, buf.String()) -} diff --git a/asset-transfer-private-data/application-gateway-go/connect.go b/asset-transfer-private-data/application-gateway-go/connect.go deleted file mode 100644 index 3bd76863..00000000 --- a/asset-transfer-private-data/application-gateway-go/connect.go +++ /dev/null @@ -1,111 +0,0 @@ -/* -Copyright 2022 IBM All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "crypto/x509" - "fmt" - "os" - "path" - - "github.com/hyperledger/fabric-gateway/pkg/identity" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" -) - -const ( - cryptoPathOrg1 = "../../test-network/organizations/peerOrganizations/org1.example.com" - keyDirectoryPathOrg1 = cryptoPathOrg1 + "/users/User1@org1.example.com/msp/keystore" - certDirectoryPathOrg1 = cryptoPathOrg1 + "/users/User1@org1.example.com/msp/signcerts" - tlsCertPathOrg1 = cryptoPathOrg1 + "/peers/peer0.org1.example.com/tls/ca.crt" - peerEndpointOrg1 = "dns:///localhost:7051" - peerNameOrg1 = "peer0.org1.example.com" - cryptoPathOrg2 = "../../test-network/organizations/peerOrganizations/org2.example.com" - keyDirectoryPathOrg2 = cryptoPathOrg2 + "/users/User1@org2.example.com/msp/keystore" - certDirectoryPathOrg2 = cryptoPathOrg2 + "/users/User1@org2.example.com/msp/signcerts" - tlsCertPathOrg2 = cryptoPathOrg2 + "/peers/peer0.org2.example.com/tls/ca.crt" - peerEndpointOrg2 = "dns:///localhost:9051" - peerNameOrg2 = "peer0.org2.example.com" -) - -// newGrpcConnection creates a gRPC connection to the Gateway server. -func newGrpcConnection(tlsCertPath, peerEndpoint, peerName string) *grpc.ClientConn { - certificatePEM, err := os.ReadFile(tlsCertPath) - if err != nil { - panic(fmt.Errorf("failed to read TLS certificate file: %w", err)) - } - - certificate, err := identity.CertificateFromPEM(certificatePEM) - if err != nil { - panic(err) - } - - certPool := x509.NewCertPool() - certPool.AddCert(certificate) - transportCredentials := credentials.NewClientTLSFromCert(certPool, peerName) - - connection, err := grpc.NewClient(peerEndpoint, grpc.WithTransportCredentials(transportCredentials)) - if err != nil { - panic(fmt.Errorf("failed to create gRPC connection: %w", err)) - } - - return connection -} - -// newIdentity creates a client identity for this Gateway connection using an X.509 certificate. -func newIdentity(certDirectoryPath, mspId string) *identity.X509Identity { - certificatePEM, err := readFirstFile(certDirectoryPath) - if err != nil { - panic(fmt.Errorf("failed to read certificate file: %w", err)) - } - - certificate, err := identity.CertificateFromPEM(certificatePEM) - if err != nil { - panic(err) - } - - id, err := identity.NewX509Identity(mspId, certificate) - if err != nil { - panic(err) - } - - return id -} - -// newSign creates a function that generates a digital signature from a message digest using a private key. -func newSign(keyDirectoryPash string) identity.Sign { - privateKeyPEM, err := readFirstFile(keyDirectoryPash) - if err != nil { - panic(fmt.Errorf("failed to read private key file: %w", err)) - } - - privateKey, err := identity.PrivateKeyFromPEM(privateKeyPEM) - if err != nil { - panic(err) - } - - sign, err := identity.NewPrivateKeySign(privateKey) - if err != nil { - panic(err) - } - - return sign -} - -func readFirstFile(dirPath string) ([]byte, error) { - dir, err := os.Open(dirPath) - if err != nil { - return nil, err - } - - fileNames, err := dir.Readdirnames(1) - if err != nil { - return nil, err - } - - return os.ReadFile(path.Join(dirPath, fileNames[0])) -} diff --git a/asset-transfer-private-data/application-gateway-go/go.mod b/asset-transfer-private-data/application-gateway-go/go.mod deleted file mode 100644 index 83a97113..00000000 --- a/asset-transfer-private-data/application-gateway-go/go.mod +++ /dev/null @@ -1,23 +0,0 @@ -module assetTransfer - -go 1.22.0 - -require ( - github.com/hyperledger/fabric-gateway v1.6.0 - google.golang.org/grpc v1.67.0 -) - -require ( - github.com/golang/protobuf v1.5.3 // indirect - github.com/hyperledger/fabric-protos-go v0.0.0-20200707132912-fee30f3ccd23 // indirect - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.3 // indirect - github.com/hyperledger/fabric-sdk-go v1.0.0 // indirect - github.com/miekg/pkcs11 v1.1.1 // indirect - github.com/pkg/errors v0.8.1 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect - google.golang.org/protobuf v1.34.2 // indirect -) diff --git a/asset-transfer-private-data/application-gateway-go/go.sum b/asset-transfer-private-data/application-gateway-go/go.sum deleted file mode 100644 index 5306d77e..00000000 --- a/asset-transfer-private-data/application-gateway-go/go.sum +++ /dev/null @@ -1,223 +0,0 @@ -bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c/go.mod h1:hSVuE3qU7grINVSwrmzHfpg9k87ALBk+XaualNyUzI4= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= -github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= -github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a/go.mod h1:rzgs2ZOiguV6/NpiDgADjRLPNyZlApIWxKpkT+X8SdY= -github.com/cloudflare/cfssl v1.4.1/go.mod h1:KManx/OJPb5QY+y0+o/898AMcM128sF0bURvoVUSjTo= -github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4= -github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hyperledger/fabric-config v0.0.5/go.mod h1:YpITBI/+ZayA3XWY5lF302K7PAsFYjEEPM/zr3hegA8= -github.com/hyperledger/fabric-gateway v1.6.0 h1:mPdXFSHdEjT0cmhsqKBfFMTVyBvfJXlO3Neicp/c27E= -github.com/hyperledger/fabric-gateway v1.6.0/go.mod h1:qHdJcgC6UrTxfYH+YIyAhPUkeNri0gPpyP/6xmiYrZo= -github.com/hyperledger/fabric-lib-go v1.0.0/go.mod h1:H362nMlunurmHwkYqR5uHL2UDWbQdbfz74n8kbCFsqc= -github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20200707132912-fee30f3ccd23 h1:SEbB3yH4ISTGRifDamYXAst36gO2kM855ndMJlsv+pc= -github.com/hyperledger/fabric-protos-go v0.0.0-20200707132912-fee30f3ccd23/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.3 h1:Xpd6fzG/KjAOHJsq7EQXY2l+qi/y8muxBaY7R6QWABk= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.3/go.mod h1:2pq0ui6ZWA0cC8J+eCErgnMDCS1kPOEYVY+06ZAK0qE= -github.com/hyperledger/fabric-sdk-go v1.0.0 h1:NRu0iNbHV6u4nd9jgYghAdA1Ll4g0Sri4hwMEGiTbyg= -github.com/hyperledger/fabric-sdk-go v1.0.0/go.mod h1:qWE9Syfg1KbwNjtILk70bJLilnmCvllIYFCSY/pa1RU= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548/go.mod h1:hGT6jSUVzF6no3QaDSMLGLEHtHSBSefs+MgcDWnmhmo= -github.com/jmoiron/sqlx v0.0.0-20180124204410-05cef0741ade/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= -github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28/go.mod h1:T/T7jsxVqf9k/zYOqbgNAsANsjxTd1Yq3htjDhQ1H0c= -github.com/lib/pq v0.0.0-20180201184707-88edab080323/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= -github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/spf13/afero v1.3.1/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.1.1/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= -github.com/weppos/publicsuffix-go v0.5.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= -github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= -github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= -github.com/zmap/zcrypto v0.0.0-20190729165852-9051775e6a2e/go.mod h1:w7kd3qXHh8FNaczNjslXqvFQiv5mMWRXlL9klTUAHc8= -github.com/zmap/zlint v0.0.0-20190806154020-fd021b4cfbeb/go.mod h1:29UiAJNsiVdvTBFCJW8e3q6dcDbOoPkhMgttOSCIMMY= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/asset-transfer-private-data/application-gateway-typescript/.gitignore b/asset-transfer-private-data/application-gateway-typescript/.gitignore deleted file mode 100644 index 99e5af9f..00000000 --- a/asset-transfer-private-data/application-gateway-typescript/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - - -# Coverage directory used by tools like istanbul -coverage - -# Dependency directories -node_modules/ -jspm_packages/ - -# Compiled TypeScript files -dist diff --git a/asset-transfer-private-data/application-gateway-typescript/.npmrc b/asset-transfer-private-data/application-gateway-typescript/.npmrc deleted file mode 100644 index b6f27f13..00000000 --- a/asset-transfer-private-data/application-gateway-typescript/.npmrc +++ /dev/null @@ -1 +0,0 @@ -engine-strict=true diff --git a/asset-transfer-private-data/application-gateway-typescript/README.md b/asset-transfer-private-data/application-gateway-typescript/README.md deleted file mode 100644 index 94cc79c0..00000000 --- a/asset-transfer-private-data/application-gateway-typescript/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Asset Transfer Private Data Sample - -This app uses fabric-samples/test-network based setup and the companion chaincode asset-transfer-private-data/chaincode-go/ with chaincode endorsement policy as "OR('Org1MSP.peer','Org2MSP.peer')" - -For this usecase illustration, we will use both Org1 & Org2 client identity from this same app -In real world the Org1 & Org2 identity will be used in different apps to achieve asset transfer. - -For more details refer: -https://hyperledger-fabric.readthedocs.io/en/release-2.4/private_data_tutorial.html#pd-use-case - diff --git a/asset-transfer-private-data/application-gateway-typescript/eslint.config.mjs b/asset-transfer-private-data/application-gateway-typescript/eslint.config.mjs deleted file mode 100644 index 9ef6b243..00000000 --- a/asset-transfer-private-data/application-gateway-typescript/eslint.config.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import js from '@eslint/js'; -import tseslint from 'typescript-eslint'; - -export default tseslint.config(js.configs.recommended, ...tseslint.configs.strictTypeChecked, { - languageOptions: { - ecmaVersion: 2023, - sourceType: 'module', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: import.meta.dirname, - }, - }, -}); diff --git a/asset-transfer-private-data/application-gateway-typescript/package.json b/asset-transfer-private-data/application-gateway-typescript/package.json deleted file mode 100644 index 96d609bf..00000000 --- a/asset-transfer-private-data/application-gateway-typescript/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "asset-transfer-private-data", - "version": "1.0.0", - "description": "Asset transfer private data application implemented in typeScript using fabric-gateway", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "engines": { - "node": ">=18" - }, - "scripts": { - "build": "tsc", - "build:watch": "tsc -w", - "lint": "eslint src", - "prepare": "npm run build", - "pretest": "npm run lint", - "start": "node dist/app.js" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "@grpc/grpc-js": "^1.12.2", - "@hyperledger/fabric-gateway": "^1.7.0" - }, - "devDependencies": { - "@eslint/js": "^9.3.0", - "@tsconfig/node18": "^18.2.2", - "@types/node": "^18.18.6", - "eslint": "^8.57.0", - "typescript": "~5.4", - "typescript-eslint": "^7.13.0" - } -} diff --git a/asset-transfer-private-data/application-gateway-typescript/src/app.ts b/asset-transfer-private-data/application-gateway-typescript/src/app.ts deleted file mode 100644 index 1e190227..00000000 --- a/asset-transfer-private-data/application-gateway-typescript/src/app.ts +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { connect, Contract, hash } from '@hyperledger/fabric-gateway'; -import { TextDecoder } from 'util'; -import { - certDirectoryPathOrg1, certDirectoryPathOrg2, keyDirectoryPathOrg1, keyDirectoryPathOrg2, newGrpcConnection, newIdentity, - newSigner, peerEndpointOrg1, peerEndpointOrg2, peerNameOrg1, peerNameOrg2, tlsCertPathOrg1, tlsCertPathOrg2 -} from './connect'; - -const channelName = 'mychannel'; -const chaincodeName = 'private'; -const mspIdOrg1 = 'Org1MSP'; -const mspIdOrg2 = 'Org2MSP'; - -const utf8Decoder = new TextDecoder(); - -// Collection names. -const org1PrivateCollectionName = 'Org1MSPPrivateCollection'; -const org2PrivateCollectionName = 'Org2MSPPrivateCollection'; - -const RED = '\x1b[31m\n'; -const RESET = '\x1b[0m'; - -// Use a unique key so that we can run multiple times. -const now = Date.now(); -const assetID1 = `asset${String(now)}`; -const assetID2 = `asset${String(now + 1)}`; - -async function main(): Promise { - const clientOrg1 = await newGrpcConnection( - tlsCertPathOrg1, - peerEndpointOrg1, - peerNameOrg1 - ); - - const gatewayOrg1 = connect({ - client: clientOrg1, - identity: await newIdentity(certDirectoryPathOrg1, mspIdOrg1), - signer: await newSigner(keyDirectoryPathOrg1), - hash: hash.sha256, - }); - - const clientOrg2 = await newGrpcConnection( - tlsCertPathOrg2, - peerEndpointOrg2, - peerNameOrg2 - ); - - const gatewayOrg2 = connect({ - client: clientOrg2, - identity: await newIdentity(certDirectoryPathOrg2, mspIdOrg2), - signer: await newSigner(keyDirectoryPathOrg2), - hash: hash.sha256, - }); - - try { - // Get the smart contract as an Org1 client. - const contractOrg1 = gatewayOrg1 - .getNetwork(channelName) - .getContract(chaincodeName); - - // Get the smart contract as an Org2 client. - const contractOrg2 = gatewayOrg2 - .getNetwork(channelName) - .getContract(chaincodeName); - - console.log('\n~~~~~~~~~~~~~~~~ As Org1 Client ~~~~~~~~~~~~~~~~'); - - // Create new assets on the ledger. - await createAssets(contractOrg1); - - // Read asset from the Org1's private data collection with ID in the given range. - await getAssetByRange(contractOrg1); - - try { - // Attempt to transfer asset without prior approval from Org2, transaction expected to fail. - console.log('\nAttempt TransferAsset without prior AgreeToTransfer'); - await transferAsset(contractOrg1, assetID1); - doFail('TransferAsset transaction succeeded when it was expected to fail'); - } catch (e) { - console.log('*** Received expected error:', e); - } - - console.log('\n~~~~~~~~~~~~~~~~ As Org2 Client ~~~~~~~~~~~~~~~~'); - - // Read the asset by ID. - await readAssetByID(contractOrg2, assetID1); - - // Make agreement to transfer the asset from Org1 to Org2. - await agreeToTransfer(contractOrg2, assetID1); - - console.log('\n~~~~~~~~~~~~~~~~ As Org1 Client ~~~~~~~~~~~~~~~~'); - - // Read transfer agreement. - await readTransferAgreement(contractOrg1, assetID1); - - // Transfer asset to Org2. - await transferAsset(contractOrg1, assetID1); - - // Again ReadAsset: results will show that the buyer identity now owns the asset. - await readAssetByID(contractOrg1, assetID1); - - // Confirm that transfer removed the private details from the Org1 collection. - const org1ReadSuccess = await readAssetPrivateDetails(contractOrg1, assetID1, org1PrivateCollectionName); - if (org1ReadSuccess) { - doFail(`Asset private data still exists in ${org1PrivateCollectionName}`); - } - - console.log('\n~~~~~~~~~~~~~~~~ As Org2 Client ~~~~~~~~~~~~~~~~'); - - // Org2 can read asset private details: Org2 is owner, and private details exist in new owner's collection. - const org2ReadSuccess = await readAssetPrivateDetails(contractOrg2, assetID1, org2PrivateCollectionName); - if (!org2ReadSuccess) { - doFail(`Asset private data not found in ${org2PrivateCollectionName}`); - } - - try { - console.log('\nAttempt DeleteAsset using non-owner organization'); - await deleteAsset(contractOrg2, assetID2); - doFail('DeleteAsset transaction succeeded when it was expected to fail'); - } catch (e) { - console.log('*** Received expected error:', e); - } - - console.log('\n~~~~~~~~~~~~~~~~ As Org1 Client ~~~~~~~~~~~~~~~~'); - - // Delete AssetID2 as Org1. - await deleteAsset(contractOrg1, assetID2); - - // Trigger a purge of the private data for the asset. - // The previous delete is optional if purge is used. - await purgeAsset(contractOrg1, assetID2); - } finally { - gatewayOrg1.close(); - clientOrg1.close(); - - gatewayOrg2.close(); - clientOrg2.close(); - } -} - -main().catch((error: unknown) => { - console.error('******** FAILED to run the application:', error); - process.exitCode = 1; -}); - -/** - * Submit a transaction synchronously, blocking until it has been committed to the ledger. - */ -async function createAssets(contract: Contract): Promise { - const assetType = 'ValuableAsset'; - - console.log(`\n--> Submit Transaction: CreateAsset, ID: ${assetID1}`); - - const asset1Data = { - objectType: assetType, - assetID: assetID1, - color: 'green', - size: 20, - appraisedValue: 100, - }; - - await contract.submit('CreateAsset', { - transientData: { asset_properties: JSON.stringify(asset1Data) }, - }); - - console.log('*** Transaction committed successfully'); - console.log(`\n--> Submit Transaction: CreateAsset, ID: ${assetID2}`); - - const asset2Data = { - objectType: assetType, - assetID: assetID2, - color: 'blue', - size: 35, - appraisedValue: 727, - }; - - await contract.submit('CreateAsset', { - transientData: { asset_properties: JSON.stringify(asset2Data) }, - }); - - console.log('*** Transaction committed successfully'); -} - -async function getAssetByRange(contract: Contract): Promise { - // GetAssetByRange returns assets on the ledger with ID in the range of startKey (inclusive) and endKey (exclusive). - console.log(`\n--> Evaluate Transaction: GetAssetByRange from ${org1PrivateCollectionName}`); - - const resultBytes = await contract.evaluateTransaction( - 'GetAssetByRange', - assetID1, - `asset${String(now + 2)}` - ); - - const resultString = utf8Decoder.decode(resultBytes); - if (!resultString) { - doFail('Received empty query list for GetAssetByRange'); - } - const result: unknown = JSON.parse(resultString); - console.log('*** Result:', result); -} - -async function readAssetByID(contract: Contract, assetID: string): Promise { - console.log(`\n--> Evaluate Transaction: ReadAsset, ID: ${assetID}`); - const resultBytes = await contract.evaluateTransaction('ReadAsset', assetID); - - const resultString = utf8Decoder.decode(resultBytes); - if (!resultString) { - doFail('Received empty result for ReadAsset'); - } - const result: unknown = JSON.parse(resultString); - console.log('*** Result:', result); -} - -async function agreeToTransfer(contract: Contract, assetID: string): Promise { - // Buyer from Org2 agrees to buy the asset. - // To purchase the asset, the buyer needs to agree to the same value as the asset owner. - - const dataForAgreement = { assetID, appraisedValue: 100 }; - console.log('\n--> Submit Transaction: AgreeToTransfer, payload:', dataForAgreement); - - await contract.submit('AgreeToTransfer', { - transientData: { asset_value: JSON.stringify(dataForAgreement) }, - }); - - console.log('*** Transaction committed successfully'); -} - -async function readTransferAgreement(contract: Contract, assetID: string): Promise { - console.log(`\n--> Evaluate Transaction: ReadTransferAgreement, ID: ${assetID}`); - - const resultBytes = await contract.evaluateTransaction( - 'ReadTransferAgreement', - assetID - ); - - const resultString = utf8Decoder.decode(resultBytes); - if (!resultString) { - doFail('Received no result for ReadTransferAgreement'); - } - const result: unknown = JSON.parse(resultString); - console.log('*** Result:', result); -} - -async function transferAsset(contract: Contract, assetID: string): Promise { - console.log(`\n--> Submit Transaction: TransferAsset, ID: ${assetID}`); - - const buyerDetails = { assetID, buyerMSP: mspIdOrg2 }; - await contract.submit('TransferAsset', { - transientData: { asset_owner: JSON.stringify(buyerDetails) }, - }); - - console.log('*** Transaction committed successfully'); -} - -async function deleteAsset(contract: Contract, assetID: string): Promise { - console.log('\n--> Submit Transaction: DeleteAsset, ID:', assetID); - const dataForDelete = { assetID }; - await contract.submit('DeleteAsset', { - transientData: { asset_delete: JSON.stringify(dataForDelete) }, - }); - - console.log('*** Transaction committed successfully'); -} - -async function purgeAsset(contract: Contract, assetID: string): Promise { - console.log('\n--> Submit Transaction: PurgeAsset, ID:', assetID); - const dataForPurge = { assetID }; - await contract.submit('PurgeAsset', { - transientData: { asset_purge: JSON.stringify(dataForPurge) }, - }); - - console.log('*** Transaction committed successfully'); -} - -async function readAssetPrivateDetails(contract: Contract, assetID: string, collectionName: string): Promise { - console.log(`\n--> Evaluate Transaction: ReadAssetPrivateDetails from ${collectionName}, ID: ${assetID}`); - - const resultBytes = await contract.evaluateTransaction( - 'ReadAssetPrivateDetails', - collectionName, - assetID - ); - - const resultJson = utf8Decoder.decode(resultBytes); - if (!resultJson) { - console.log('*** No result'); - return false; - } - const result: unknown = JSON.parse(resultJson); - console.log('*** Result:', result); - return true; -} - -export function doFail(msgString: string): never { - console.error(`${RED}\t${msgString}${RESET}`); - throw new Error(msgString); -} diff --git a/asset-transfer-private-data/application-gateway-typescript/src/connect.ts b/asset-transfer-private-data/application-gateway-typescript/src/connect.ts deleted file mode 100644 index 0fe7f3a3..00000000 --- a/asset-transfer-private-data/application-gateway-typescript/src/connect.ts +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as grpc from '@grpc/grpc-js'; -import { Identity, Signer, signers } from '@hyperledger/fabric-gateway'; -import * as crypto from 'crypto'; -import { promises as fs } from 'fs'; -import * as path from 'path'; - -// Path to org1 crypto materials. -const cryptoPathOrg1 = path.resolve( - __dirname, - '..', - '..', - '..', - 'test-network', - 'organizations', - 'peerOrganizations', - 'org1.example.com' -); - -// Path to org1 user private key directory. -export const keyDirectoryPathOrg1 = path.resolve( - cryptoPathOrg1, - 'users', - 'User1@org1.example.com', - 'msp', - 'keystore' -); - -// Path to org1 user certificate. -export const certDirectoryPathOrg1 = path.resolve( - cryptoPathOrg1, - 'users', - 'User1@org1.example.com', - 'msp', - 'signcerts' -); - -// Path to org1 peer tls certificate. -export const tlsCertPathOrg1 = path.resolve( - cryptoPathOrg1, - 'peers', - 'peer0.org1.example.com', - 'tls', - 'ca.crt' -); - -// Path to org2 crypto materials. -export const cryptoPathOrg2 = path.resolve( - __dirname, - '..', - '..', - '..', - 'test-network', - 'organizations', - 'peerOrganizations', - 'org2.example.com' -); - -// Path to org2 user private key directory. -export const keyDirectoryPathOrg2 = path.resolve( - cryptoPathOrg2, - 'users', - 'User1@org2.example.com', - 'msp', - 'keystore' -); - -// Path to org2 user certificate. -export const certDirectoryPathOrg2 = path.resolve( - cryptoPathOrg2, - 'users', - 'User1@org2.example.com', - 'msp', - 'signcerts' -); - -// Path to org2 peer tls certificate. -export const tlsCertPathOrg2 = path.resolve( - cryptoPathOrg2, - 'peers', - 'peer0.org2.example.com', - 'tls', - 'ca.crt' -); - -// Gateway peer endpoint. -export const peerEndpointOrg1 = 'localhost:7051'; -export const peerEndpointOrg2 = 'localhost:9051'; - -// Gateway peer container name. -export const peerNameOrg1 = 'peer0.org1.example.com'; -export const peerNameOrg2 = 'peer0.org2.example.com'; - - -export async function newGrpcConnection( - tlsCertPath: string, - peerEndpoint: string, - peerName: string -): Promise { - const tlsRootCert = await fs.readFile(tlsCertPath); - const tlsCredentials = grpc.credentials.createSsl(tlsRootCert); - return new grpc.Client(peerEndpoint, tlsCredentials, { - 'grpc.ssl_target_name_override': peerName, - }); -} - -export async function newIdentity( - certDirectoryPath: string, - mspId: string -): Promise { - const certPath = await getFirstDirFileName(certDirectoryPath); - const credentials = await fs.readFile(certPath); - return { mspId, credentials }; -} - -export async function newSigner(keyDirectoryPath: string): Promise { - const keyPath = await getFirstDirFileName(keyDirectoryPath); - const privateKeyPem = await fs.readFile(keyPath); - const privateKey = crypto.createPrivateKey(privateKeyPem); - return signers.newPrivateKeySigner(privateKey); -} - -async function getFirstDirFileName(dirPath: string): Promise { - const files = await fs.readdir(dirPath); - const file = files[0]; - if (!file) { - throw new Error(`No files in directory: ${dirPath}`); - } - return path.join(dirPath, file); -} diff --git a/asset-transfer-private-data/application-gateway-typescript/tsconfig.json b/asset-transfer-private-data/application-gateway-typescript/tsconfig.json deleted file mode 100644 index 4c20df24..00000000 --- a/asset-transfer-private-data/application-gateway-typescript/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "@tsconfig/node18/tsconfig.json", - "compilerOptions": { - "outDir": "dist", - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "noUnusedLocals": true, - "noImplicitReturns": true, - "noUncheckedIndexedAccess": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["./src/**/*"], - "exclude": ["./src/**/*.spec.ts"] -} diff --git a/asset-transfer-private-data/chaincode-go/META-INF/statedb/couchdb/collections/assetCollection/indexes/indexOwner.json b/asset-transfer-private-data/chaincode-go/META-INF/statedb/couchdb/collections/assetCollection/indexes/indexOwner.json deleted file mode 100644 index e2d1d087..00000000 --- a/asset-transfer-private-data/chaincode-go/META-INF/statedb/couchdb/collections/assetCollection/indexes/indexOwner.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "index": { - "fields": [ - "objectType", - "owner" - ] - }, - "ddoc": "indexOwnerDoc", - "name": "indexOwner", - "type": "json" -} - diff --git a/asset-transfer-private-data/chaincode-go/README.md b/asset-transfer-private-data/chaincode-go/README.md deleted file mode 100644 index f87a95c6..00000000 --- a/asset-transfer-private-data/chaincode-go/README.md +++ /dev/null @@ -1 +0,0 @@ -[Using Private Data tutorial](https://hyperledger-fabric.readthedocs.io/en/latest/private_data_tutorial.html) diff --git a/asset-transfer-private-data/chaincode-go/chaincode/asset_queries.go b/asset-transfer-private-data/chaincode-go/chaincode/asset_queries.go deleted file mode 100644 index 0542947a..00000000 --- a/asset-transfer-private-data/chaincode-go/chaincode/asset_queries.go +++ /dev/null @@ -1,190 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package chaincode - -import ( - "encoding/json" - "fmt" - "log" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -// ReadAsset reads the information from collection -func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, assetID string) (*Asset, error) { - - log.Printf("ReadAsset: collection %v, ID %v", assetCollection, assetID) - assetJSON, err := ctx.GetStub().GetPrivateData(assetCollection, assetID) //get the asset from chaincode state - if err != nil { - return nil, fmt.Errorf("failed to read asset: %v", err) - } - - // No Asset found, return empty response - if assetJSON == nil { - log.Printf("%v does not exist in collection %v", assetID, assetCollection) - return nil, nil - } - - var asset *Asset - err = json.Unmarshal(assetJSON, &asset) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - return asset, nil - -} - -// ReadAssetPrivateDetails reads the asset private details in organization specific collection -func (s *SmartContract) ReadAssetPrivateDetails(ctx contractapi.TransactionContextInterface, collection string, assetID string) (*AssetPrivateDetails, error) { - log.Printf("ReadAssetPrivateDetails: collection %v, ID %v", collection, assetID) - assetDetailsJSON, err := ctx.GetStub().GetPrivateData(collection, assetID) // Get the asset from chaincode state - if err != nil { - return nil, fmt.Errorf("failed to read asset details: %v", err) - } - if assetDetailsJSON == nil { - log.Printf("AssetPrivateDetails for %v does not exist in collection %v", assetID, collection) - return nil, nil - } - - var assetDetails *AssetPrivateDetails - err = json.Unmarshal(assetDetailsJSON, &assetDetails) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - return assetDetails, nil -} - -// ReadTransferAgreement gets the buyer's identity from the transfer agreement from collection -func (s *SmartContract) ReadTransferAgreement(ctx contractapi.TransactionContextInterface, assetID string) (*TransferAgreement, error) { - log.Printf("ReadTransferAgreement: collection %v, ID %v", assetCollection, assetID) - // composite key for TransferAgreement of this asset - transferAgreeKey, err := ctx.GetStub().CreateCompositeKey(transferAgreementObjectType, []string{assetID}) - if err != nil { - return nil, fmt.Errorf("failed to create composite key: %v", err) - } - - buyerIdentity, err := ctx.GetStub().GetPrivateData(assetCollection, transferAgreeKey) // Get the identity from collection - if err != nil { - return nil, fmt.Errorf("failed to read TransferAgreement: %v", err) - } - if buyerIdentity == nil { - log.Printf("TransferAgreement for %v does not exist", assetID) - return nil, nil - } - agreement := &TransferAgreement{ - ID: assetID, - BuyerID: string(buyerIdentity), - } - return agreement, nil -} - -// GetAssetByRange performs a range query based on the start and end keys provided. Range -// queries can be used to read data from private data collections, but can not be used in -// a transaction that also writes to private data. -func (s *SmartContract) GetAssetByRange(ctx contractapi.TransactionContextInterface, startKey string, endKey string) ([]*Asset, error) { - - resultsIterator, err := ctx.GetStub().GetPrivateDataByRange(assetCollection, startKey, endKey) - if err != nil { - return nil, err - } - defer resultsIterator.Close() - - results := []*Asset{} - - for resultsIterator.HasNext() { - response, err := resultsIterator.Next() - if err != nil { - return nil, err - } - - var asset *Asset - err = json.Unmarshal(response.Value, &asset) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - results = append(results, asset) - } - - return results, nil - -} - -// =======Rich queries ========================================================================= -// Two examples of rich queries are provided below (parameterized query and ad hoc query). -// Rich queries pass a query string to the state database. -// Rich queries are only supported by state database implementations -// that support rich query (e.g. CouchDB). -// The query string is in the syntax of the underlying state database. -// With rich queries there is no guarantee that the result set hasn't changed between -// endorsement time and commit time, aka 'phantom reads'. -// Therefore, rich queries should not be used in update transactions, unless the -// application handles the possibility of result set changes between endorsement and commit time. -// Rich queries can be used for point-in-time queries against a peer. -// ============================================================================================ - -// ===== Example: Parameterized rich query ================================================= - -// QueryAssetByOwner queries for assets based on assetType, owner. -// This is an example of a parameterized query where the query logic is baked into the chaincode, -// and accepting a single query parameter (owner). -// Only available on state databases that support rich query (e.g. CouchDB) -// ========================================================================================= -func (s *SmartContract) QueryAssetByOwner(ctx contractapi.TransactionContextInterface, assetType string, owner string) ([]*Asset, error) { - - queryString := fmt.Sprintf("{\"selector\":{\"objectType\":\"%v\",\"owner\":\"%v\"}}", assetType, owner) - - queryResults, err := s.getQueryResultForQueryString(ctx, queryString) - if err != nil { - return nil, err - } - return queryResults, nil -} - -// QueryAssets uses a query string to perform a query for assets. -// Query string matching state database syntax is passed in and executed as is. -// Supports ad hoc queries that can be defined at runtime by the client. -// If this is not desired, follow the QueryAssetByOwner example for parameterized queries. -// Only available on state databases that support rich query (e.g. CouchDB) -func (s *SmartContract) QueryAssets(ctx contractapi.TransactionContextInterface, queryString string) ([]*Asset, error) { - - queryResults, err := s.getQueryResultForQueryString(ctx, queryString) - if err != nil { - return nil, err - } - return queryResults, nil -} - -// getQueryResultForQueryString executes the passed in query string. -func (s *SmartContract) getQueryResultForQueryString(ctx contractapi.TransactionContextInterface, queryString string) ([]*Asset, error) { - - resultsIterator, err := ctx.GetStub().GetPrivateDataQueryResult(assetCollection, queryString) - if err != nil { - return nil, err - } - defer resultsIterator.Close() - - results := []*Asset{} - - for resultsIterator.HasNext() { - response, err := resultsIterator.Next() - if err != nil { - return nil, err - } - var asset *Asset - - err = json.Unmarshal(response.Value, &asset) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - results = append(results, asset) - } - return results, nil -} diff --git a/asset-transfer-private-data/chaincode-go/chaincode/asset_queries_test.go b/asset-transfer-private-data/chaincode-go/chaincode/asset_queries_test.go deleted file mode 100644 index c35e9f20..00000000 --- a/asset-transfer-private-data/chaincode-go/chaincode/asset_queries_test.go +++ /dev/null @@ -1,185 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ -package chaincode_test - -import ( - "encoding/json" - "fmt" - "testing" - - "github.com/hyperledger/fabric-protos-go-apiv2/ledger/queryresult" - - "github.com/hyperledger/fabric-samples/asset-transfer-private-data/chaincode-go/chaincode" - "github.com/hyperledger/fabric-samples/asset-transfer-private-data/chaincode-go/chaincode/mocks" - "github.com/stretchr/testify/require" -) - -/* -For details on generating the mocks, see comments in the file asset_transfer_test.go -*/ -func TestReadAsset(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - - assetBytes, err := assetTransferCC.ReadAsset(transactionContext, "id1") - require.NoError(t, err) - require.Nil(t, assetBytes) - - chaincodeStub.GetPrivateDataReturns(nil, fmt.Errorf("unable to retrieve asset")) - assetBytes, err = assetTransferCC.ReadAsset(transactionContext, "id1") - require.EqualError(t, err, "failed to read asset: unable to retrieve asset") - - testAsset := &chaincode.Asset{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - Owner: myOrg1Clientid, - } - setReturnPrivateDataInStub(t, chaincodeStub, testAsset) - assetRead, err := assetTransferCC.ReadAsset(transactionContext, "id1") - require.NoError(t, err) - require.Equal(t, testAsset, assetRead) -} - -func TestReadAssetPrivateDetails(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - - assetBytes, err := assetTransferCC.ReadAssetPrivateDetails(transactionContext, myOrg1PrivCollection, "id1") - require.NoError(t, err) - require.Nil(t, assetBytes) - - // read from the collection with no access - chaincodeStub.GetPrivateDataReturns(nil, fmt.Errorf("collection not found")) - assetBytes, err = assetTransferCC.ReadAssetPrivateDetails(transactionContext, myOrg2PrivCollection, "id1") - require.EqualError(t, err, "failed to read asset details: collection not found") - - returnPrivData := &chaincode.AssetPrivateDetails{ - ID: "id1", - AppraisedValue: 5, - } - setReturnAssetPrivateDetailsInStub(t, chaincodeStub, returnPrivData) - assetRead, err := assetTransferCC.ReadAssetPrivateDetails(transactionContext, myOrg1PrivCollection, "id1") - require.NoError(t, err) - require.Equal(t, returnPrivData, assetRead) -} - -func TestReadTransferAgreement(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - - // TransferAgreement does not exist - assetBytes, err := assetTransferCC.ReadTransferAgreement(transactionContext, "id1") - require.NoError(t, err) - require.Nil(t, assetBytes) - - chaincodeStub.GetPrivateDataReturns([]byte(myOrg2Clientid), nil) - expectedData := &chaincode.TransferAgreement{ - ID: "id1", - BuyerID: myOrg2Clientid, - } - dataRead, err := assetTransferCC.ReadTransferAgreement(transactionContext, "id1") - require.NoError(t, err) - require.Equal(t, expectedData, dataRead) -} - -func TestQueryAssetByOwner(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - - asset := &chaincode.Asset{Type: "valuableasset", ID: "asset1", Owner: "user1"} - asset1Bytes, err := json.Marshal(asset) - require.NoError(t, err) - - iterator := &mocks.StateQueryIterator{} - iterator.HasNextReturnsOnCall(0, true) - iterator.HasNextReturnsOnCall(1, false) - iterator.NextReturns(&queryresult.KV{Value: asset1Bytes}, nil) - chaincodeStub.GetPrivateDataQueryResultReturns(iterator, nil) - - assetTransferCC := &chaincode.SmartContract{} - assets, err := assetTransferCC.QueryAssetByOwner(transactionContext, "valuableasset", "user1") - require.NoError(t, err) - require.Equal(t, []*chaincode.Asset{asset}, assets) - - iterator.HasNextReturns(true) - iterator.NextReturns(nil, fmt.Errorf("failed retrieving next item")) - assets, err = assetTransferCC.QueryAssetByOwner(transactionContext, "valuableasset", "user1") - require.EqualError(t, err, "failed retrieving next item") - require.Nil(t, assets) - -} - -func TestQueryAssets(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - // Iterator with no records - iterator := &mocks.StateQueryIterator{} - iterator.HasNextReturns(false) - chaincodeStub.GetPrivateDataQueryResultReturns(iterator, nil) - - assetTransferCC := &chaincode.SmartContract{} - assets, err := assetTransferCC.QueryAssets(transactionContext, "querystr") - require.NoError(t, err) - require.Equal(t, []*chaincode.Asset{}, assets) - - iterator = &mocks.StateQueryIterator{} - chaincodeStub.GetPrivateDataQueryResultReturns(iterator, nil) - iterator.HasNextReturns(true) - iterator.NextReturns(nil, fmt.Errorf("failed retrieving next item")) - assets, err = assetTransferCC.QueryAssets(transactionContext, "querystr") - require.EqualError(t, err, "failed retrieving next item") - require.Nil(t, assets) - - asset := &chaincode.Asset{Type: "valuableasset", ID: "asset1", Owner: "user1"} - asset1Bytes, err := json.Marshal(asset) - require.NoError(t, err) - - iterator = &mocks.StateQueryIterator{} - chaincodeStub.GetPrivateDataQueryResultReturns(iterator, nil) - iterator.HasNextReturnsOnCall(0, true) - iterator.HasNextReturnsOnCall(1, false) - iterator.NextReturns(&queryresult.KV{Value: asset1Bytes}, nil) - - assets, err = assetTransferCC.QueryAssets(transactionContext, "querystr") - require.NoError(t, err) - require.Equal(t, []*chaincode.Asset{asset}, assets) -} - -func TestGetAssetByRange(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - // Iterator with no records - iterator := &mocks.StateQueryIterator{} - iterator.HasNextReturns(false) - chaincodeStub.GetPrivateDataByRangeReturns(iterator, nil) - - assetTransferCC := &chaincode.SmartContract{} - assets, err := assetTransferCC.GetAssetByRange(transactionContext, "st", "end") - require.NoError(t, err) - require.Equal(t, []*chaincode.Asset{}, assets) - - iterator = &mocks.StateQueryIterator{} - chaincodeStub.GetPrivateDataByRangeReturns(iterator, nil) - iterator.HasNextReturns(true) - iterator.NextReturns(nil, fmt.Errorf("failed retrieving next item")) - assets, err = assetTransferCC.GetAssetByRange(transactionContext, "st", "end") - require.EqualError(t, err, "failed retrieving next item") - require.Nil(t, assets) - - asset := &chaincode.Asset{Type: "valuableasset", ID: "asset1", Owner: "user1"} - asset1Bytes, err := json.Marshal(asset) - require.NoError(t, err) - - iterator = &mocks.StateQueryIterator{} - chaincodeStub.GetPrivateDataByRangeReturns(iterator, nil) - iterator.HasNextReturnsOnCall(0, true) - iterator.HasNextReturnsOnCall(1, false) - iterator.NextReturns(&queryresult.KV{Value: asset1Bytes}, nil) - - assets, err = assetTransferCC.GetAssetByRange(transactionContext, "st", "end") - require.NoError(t, err) - require.Equal(t, []*chaincode.Asset{asset}, assets) - -} diff --git a/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go b/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go deleted file mode 100644 index 58817a56..00000000 --- a/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go +++ /dev/null @@ -1,652 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package chaincode - -import ( - "bytes" - "encoding/base64" - "encoding/json" - "fmt" - "log" - - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -const assetCollection = "assetCollection" -const transferAgreementObjectType = "transferAgreement" - -// SmartContract of this fabric sample -type SmartContract struct { - contractapi.Contract -} - -// Asset describes main asset details that are visible to all organizations -type Asset struct { - Type string `json:"objectType"` //Type is used to distinguish the various types of objects in state database - ID string `json:"assetID"` - Color string `json:"color"` - Size int `json:"size"` - Owner string `json:"owner"` -} - -// AssetPrivateDetails describes details that are private to owners -type AssetPrivateDetails struct { - ID string `json:"assetID"` - AppraisedValue int `json:"appraisedValue"` -} - -// TransferAgreement describes the buyer agreement returned by ReadTransferAgreement -type TransferAgreement struct { - ID string `json:"assetID"` - BuyerID string `json:"buyerID"` -} - -// CreateAsset creates a new asset by placing the main asset details in the assetCollection -// that can be read by both organizations. The appraisal value is stored in the owners org specific collection. -func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface) error { - - // Get new asset from transient map - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return fmt.Errorf("error getting transient: %v", err) - } - - // Asset properties are private, therefore they get passed in transient field, instead of func args - transientAssetJSON, ok := transientMap["asset_properties"] - if !ok { - // log error to stdout - return fmt.Errorf("asset not found in the transient map input") - } - - type assetTransientInput struct { - Type string `json:"objectType"` //Type is used to distinguish the various types of objects in state database - ID string `json:"assetID"` - Color string `json:"color"` - Size int `json:"size"` - AppraisedValue int `json:"appraisedValue"` - } - - var assetInput assetTransientInput - err = json.Unmarshal(transientAssetJSON, &assetInput) - if err != nil { - return fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - if len(assetInput.Type) == 0 { - return fmt.Errorf("objectType field must be a non-empty string") - } - if len(assetInput.ID) == 0 { - return fmt.Errorf("assetID field must be a non-empty string") - } - if len(assetInput.Color) == 0 { - return fmt.Errorf("color field must be a non-empty string") - } - if assetInput.Size <= 0 { - return fmt.Errorf("size field must be a positive integer") - } - if assetInput.AppraisedValue <= 0 { - return fmt.Errorf("appraisedValue field must be a positive integer") - } - - // Check if asset already exists - assetAsBytes, err := ctx.GetStub().GetPrivateData(assetCollection, assetInput.ID) - if err != nil { - return fmt.Errorf("failed to get asset: %v", err) - } else if assetAsBytes != nil { - fmt.Println("Asset already exists: " + assetInput.ID) - return fmt.Errorf("this asset already exists: " + assetInput.ID) - } - - // Get ID of submitting client identity - clientID, err := submittingClientIdentity(ctx) - if err != nil { - return err - } - - // Verify that the client is submitting request to peer in their organization - // This is to ensure that a client from another org doesn't attempt to read or - // write private data from this peer. - err = verifyClientOrgMatchesPeerOrg(ctx) - if err != nil { - return fmt.Errorf("CreateAsset cannot be performed: Error %v", err) - } - - // Make submitting client the owner - asset := Asset{ - Type: assetInput.Type, - ID: assetInput.ID, - Color: assetInput.Color, - Size: assetInput.Size, - Owner: clientID, - } - assetJSONasBytes, err := json.Marshal(asset) - if err != nil { - return fmt.Errorf("failed to marshal asset into JSON: %v", err) - } - - // Save asset to private data collection - // Typical logger, logs to stdout/file in the fabric managed docker container, running this chaincode - // Look for container name like dev-peer0.org1.example.com-{chaincodename_version}-xyz - log.Printf("CreateAsset Put: collection %v, ID %v, owner %v", assetCollection, assetInput.ID, clientID) - - err = ctx.GetStub().PutPrivateData(assetCollection, assetInput.ID, assetJSONasBytes) - if err != nil { - return fmt.Errorf("failed to put asset into private data collecton: %v", err) - } - - // Save asset details to collection visible to owning organization - assetPrivateDetails := AssetPrivateDetails{ - ID: assetInput.ID, - AppraisedValue: assetInput.AppraisedValue, - } - - assetPrivateDetailsAsBytes, err := json.Marshal(assetPrivateDetails) // marshal asset details to JSON - if err != nil { - return fmt.Errorf("failed to marshal into JSON: %v", err) - } - - // Get collection name for this organization. - orgCollection, err := getCollectionName(ctx) - if err != nil { - return fmt.Errorf("failed to infer private collection name for the org: %v", err) - } - - // Put asset appraised value into owners org specific private data collection - log.Printf("Put: collection %v, ID %v", orgCollection, assetInput.ID) - err = ctx.GetStub().PutPrivateData(orgCollection, assetInput.ID, assetPrivateDetailsAsBytes) - if err != nil { - return fmt.Errorf("failed to put asset private details: %v", err) - } - return nil -} - -// AgreeToTransfer is used by the potential buyer of the asset to agree to the -// asset value. The agreed to appraisal value is stored in the buying orgs -// org specifc collection, while the buyer client ID is stored in the asset collection -// using a composite key -func (s *SmartContract) AgreeToTransfer(ctx contractapi.TransactionContextInterface) error { - - // Get ID of submitting client identity - clientID, err := submittingClientIdentity(ctx) - if err != nil { - return err - } - - // Value is private, therefore it gets passed in transient field - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return fmt.Errorf("error getting transient: %v", err) - } - - // Persist the JSON bytes as-is so that there is no risk of nondeterministic marshaling. - valueJSONasBytes, ok := transientMap["asset_value"] - if !ok { - return fmt.Errorf("asset_value key not found in the transient map") - } - - // Unmarshal the tranisent map to get the asset ID. - var valueJSON AssetPrivateDetails - err = json.Unmarshal(valueJSONasBytes, &valueJSON) - if err != nil { - return fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - // Do some error checking since we get the chance - if len(valueJSON.ID) == 0 { - return fmt.Errorf("assetID field must be a non-empty string") - } - if valueJSON.AppraisedValue <= 0 { - return fmt.Errorf("appraisedValue field must be a positive integer") - } - - // Read asset from the private data collection - asset, err := s.ReadAsset(ctx, valueJSON.ID) - if err != nil { - return fmt.Errorf("error reading asset: %v", err) - } - if asset == nil { - return fmt.Errorf("%v does not exist", valueJSON.ID) - } - // Verify that the client is submitting request to peer in their organization - err = verifyClientOrgMatchesPeerOrg(ctx) - if err != nil { - return fmt.Errorf("AgreeToTransfer cannot be performed: Error %v", err) - } - - // Get collection name for this organization. Needs to be read by a member of the organization. - orgCollection, err := getCollectionName(ctx) - if err != nil { - return fmt.Errorf("failed to infer private collection name for the org: %v", err) - } - - log.Printf("AgreeToTransfer Put: collection %v, ID %v", orgCollection, valueJSON.ID) - // Put agreed value in the org specifc private data collection - err = ctx.GetStub().PutPrivateData(orgCollection, valueJSON.ID, valueJSONasBytes) - if err != nil { - return fmt.Errorf("failed to put asset bid: %v", err) - } - - // Create agreeement that indicates which identity has agreed to purchase - // In a more realistic transfer scenario, a transfer agreement would be secured to ensure that it cannot - // be overwritten by another channel member - transferAgreeKey, err := ctx.GetStub().CreateCompositeKey(transferAgreementObjectType, []string{valueJSON.ID}) - if err != nil { - return fmt.Errorf("failed to create composite key: %v", err) - } - - log.Printf("AgreeToTransfer Put: collection %v, ID %v, Key %v", assetCollection, valueJSON.ID, transferAgreeKey) - err = ctx.GetStub().PutPrivateData(assetCollection, transferAgreeKey, []byte(clientID)) - if err != nil { - return fmt.Errorf("failed to put asset bid: %v", err) - } - - return nil -} - -// TransferAsset transfers the asset to the new owner by setting a new owner ID -func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface) error { - - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return fmt.Errorf("error getting transient %v", err) - } - - // Asset properties are private, therefore they get passed in transient field - transientTransferJSON, ok := transientMap["asset_owner"] - if !ok { - return fmt.Errorf("asset owner not found in the transient map") - } - - type assetTransferTransientInput struct { - ID string `json:"assetID"` - BuyerMSP string `json:"buyerMSP"` - } - - var assetTransferInput assetTransferTransientInput - err = json.Unmarshal(transientTransferJSON, &assetTransferInput) - if err != nil { - return fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - if len(assetTransferInput.ID) == 0 { - return fmt.Errorf("assetID field must be a non-empty string") - } - if len(assetTransferInput.BuyerMSP) == 0 { - return fmt.Errorf("buyerMSP field must be a non-empty string") - } - log.Printf("TransferAsset: verify asset exists ID %v", assetTransferInput.ID) - // Read asset from the private data collection - asset, err := s.ReadAsset(ctx, assetTransferInput.ID) - if err != nil { - return fmt.Errorf("error reading asset: %v", err) - } - if asset == nil { - return fmt.Errorf("%v does not exist", assetTransferInput.ID) - } - // Verify that the client is submitting request to peer in their organization - err = verifyClientOrgMatchesPeerOrg(ctx) - if err != nil { - return fmt.Errorf("TransferAsset cannot be performed: Error %v", err) - } - - // Verify transfer details and transfer owner - err = s.verifyAgreement(ctx, assetTransferInput.ID, asset.Owner, assetTransferInput.BuyerMSP) - if err != nil { - return fmt.Errorf("failed transfer verification: %v", err) - } - - transferAgreement, err := s.ReadTransferAgreement(ctx, assetTransferInput.ID) - if err != nil { - return fmt.Errorf("failed ReadTransferAgreement to find buyerID: %v", err) - } - if transferAgreement.BuyerID == "" { - return fmt.Errorf("BuyerID not found in TransferAgreement for %v", assetTransferInput.ID) - } - - // Transfer asset in private data collection to new owner - asset.Owner = transferAgreement.BuyerID - - assetJSONasBytes, err := json.Marshal(asset) - if err != nil { - return fmt.Errorf("failed marshalling asset %v: %v", assetTransferInput.ID, err) - } - - log.Printf("TransferAsset Put: collection %v, ID %v", assetCollection, assetTransferInput.ID) - err = ctx.GetStub().PutPrivateData(assetCollection, assetTransferInput.ID, assetJSONasBytes) //rewrite the asset - if err != nil { - return err - } - - // Get collection name for this organization - ownersCollection, err := getCollectionName(ctx) - if err != nil { - return fmt.Errorf("failed to infer private collection name for the org: %v", err) - } - - // Delete the asset appraised value from this organization's private data collection - err = ctx.GetStub().DelPrivateData(ownersCollection, assetTransferInput.ID) - if err != nil { - return err - } - - // Delete the transfer agreement from the asset collection - transferAgreeKey, err := ctx.GetStub().CreateCompositeKey(transferAgreementObjectType, []string{assetTransferInput.ID}) - if err != nil { - return fmt.Errorf("failed to create composite key: %v", err) - } - - err = ctx.GetStub().DelPrivateData(assetCollection, transferAgreeKey) - if err != nil { - return err - } - - return nil - -} - -// verifyAgreement is an internal helper function used by TransferAsset to verify -// that the transfer is being initiated by the owner and that the buyer has agreed -// to the same appraisal value as the owner -func (s *SmartContract) verifyAgreement(ctx contractapi.TransactionContextInterface, assetID string, owner string, buyerMSP string) error { - - // Check 1: verify that the transfer is being initiatied by the owner - - // Get ID of submitting client identity - clientID, err := submittingClientIdentity(ctx) - if err != nil { - return err - } - - if clientID != owner { - return fmt.Errorf("error: submitting client identity does not own asset") - } - - // Check 2: verify that the buyer has agreed to the appraised value - - // Get collection names - collectionOwner, err := getCollectionName(ctx) // get owner collection from caller identity - if err != nil { - return fmt.Errorf("failed to infer private collection name for the org: %v", err) - } - - collectionBuyer := buyerMSP + "PrivateCollection" // get buyers collection - - // Get hash of owners agreed to value - ownerAppraisedValueHash, err := ctx.GetStub().GetPrivateDataHash(collectionOwner, assetID) - if err != nil { - return fmt.Errorf("failed to get hash of appraised value from owners collection %v: %v", collectionOwner, err) - } - if ownerAppraisedValueHash == nil { - return fmt.Errorf("hash of appraised value for %v does not exist in collection %v", assetID, collectionOwner) - } - - // Get hash of buyers agreed to value - buyerAppraisedValueHash, err := ctx.GetStub().GetPrivateDataHash(collectionBuyer, assetID) - if err != nil { - return fmt.Errorf("failed to get hash of appraised value from buyer collection %v: %v", collectionBuyer, err) - } - if buyerAppraisedValueHash == nil { - return fmt.Errorf("hash of appraised value for %v does not exist in collection %v. AgreeToTransfer must be called by the buyer first", assetID, collectionBuyer) - } - - // Verify that the two hashes match - if !bytes.Equal(ownerAppraisedValueHash, buyerAppraisedValueHash) { - return fmt.Errorf("hash for appraised value for owner %x does not value for seller %x", ownerAppraisedValueHash, buyerAppraisedValueHash) - } - - return nil -} - -// DeleteAsset can be used by the owner of the asset to delete the asset -func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface) error { - - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return fmt.Errorf("Error getting transient: %v", err) - } - - // Asset properties are private, therefore they get passed in transient field - transientDeleteJSON, ok := transientMap["asset_delete"] - if !ok { - return fmt.Errorf("asset to delete not found in the transient map") - } - - type assetDelete struct { - ID string `json:"assetID"` - } - - var assetDeleteInput assetDelete - err = json.Unmarshal(transientDeleteJSON, &assetDeleteInput) - if err != nil { - return fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - if len(assetDeleteInput.ID) == 0 { - return fmt.Errorf("assetID field must be a non-empty string") - } - - // Verify that the client is submitting request to peer in their organization - err = verifyClientOrgMatchesPeerOrg(ctx) - if err != nil { - return fmt.Errorf("DeleteAsset cannot be performed: Error %v", err) - } - - log.Printf("Deleting Asset: %v", assetDeleteInput.ID) - valAsbytes, err := ctx.GetStub().GetPrivateData(assetCollection, assetDeleteInput.ID) //get the asset from chaincode state - if err != nil { - return fmt.Errorf("failed to read asset: %v", err) - } - if valAsbytes == nil { - return fmt.Errorf("asset not found: %v", assetDeleteInput.ID) - } - - ownerCollection, err := getCollectionName(ctx) // Get owners collection - if err != nil { - return fmt.Errorf("failed to infer private collection name for the org: %v", err) - } - - // Check the asset is in the caller org's private collection - valAsbytes, err = ctx.GetStub().GetPrivateData(ownerCollection, assetDeleteInput.ID) - if err != nil { - return fmt.Errorf("failed to read asset from owner's Collection: %v", err) - } - if valAsbytes == nil { - return fmt.Errorf("asset not found in owner's private Collection %v: %v", ownerCollection, assetDeleteInput.ID) - } - - // delete the asset from state - err = ctx.GetStub().DelPrivateData(assetCollection, assetDeleteInput.ID) - if err != nil { - return fmt.Errorf("failed to delete state: %v", err) - } - - // Finally, delete private details of asset - err = ctx.GetStub().DelPrivateData(ownerCollection, assetDeleteInput.ID) - if err != nil { - return err - } - - return nil - -} - -// PurgeAsset can be used by the owner of the asset to delete the asset -// Trigger removal of the asset -func (s *SmartContract) PurgeAsset(ctx contractapi.TransactionContextInterface) error { - - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return fmt.Errorf("Error getting transient: %v", err) - } - - // Asset properties are private, therefore they get passed in transient field - transientDeleteJSON, ok := transientMap["asset_purge"] - if !ok { - return fmt.Errorf("asset to purge not found in the transient map") - } - - type assetPurge struct { - ID string `json:"assetID"` - } - - var assetPurgeInput assetPurge - err = json.Unmarshal(transientDeleteJSON, &assetPurgeInput) - if err != nil { - return fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - if len(assetPurgeInput.ID) == 0 { - return fmt.Errorf("assetID field must be a non-empty string") - } - - // Verify that the client is submitting request to peer in their organization - err = verifyClientOrgMatchesPeerOrg(ctx) - if err != nil { - return fmt.Errorf("PurgeAsset cannot be performed: Error %v", err) - } - - log.Printf("Purging Asset: %v", assetPurgeInput.ID) - - // Note that there is no check here to see if the id exist; it might have been 'deleted' already - // so a check here is pointless. We would need to call purge irrespective of the result - // A delete can be called before purge, but is not essential - - ownerCollection, err := getCollectionName(ctx) // Get owners collection - if err != nil { - return fmt.Errorf("failed to infer private collection name for the org: %v", err) - } - - // delete the asset from state - err = ctx.GetStub().PurgePrivateData(assetCollection, assetPurgeInput.ID) - if err != nil { - return fmt.Errorf("failed to purge state from asset collection: %v", err) - } - - // Finally, delete private details of asset - err = ctx.GetStub().PurgePrivateData(ownerCollection, assetPurgeInput.ID) - if err != nil { - return fmt.Errorf("failed to purge state from owner collection: %v", err) - } - - return nil - -} - -// DeleteTranferAgreement can be used by the buyer to withdraw a proposal from -// the asset collection and from his own collection. -func (s *SmartContract) DeleteTranferAgreement(ctx contractapi.TransactionContextInterface) error { - - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return fmt.Errorf("error getting transient: %v", err) - } - - // Asset properties are private, therefore they get passed in transient field - transientDeleteJSON, ok := transientMap["agreement_delete"] - if !ok { - return fmt.Errorf("asset to delete not found in the transient map") - } - - type assetDelete struct { - ID string `json:"assetID"` - } - - var assetDeleteInput assetDelete - err = json.Unmarshal(transientDeleteJSON, &assetDeleteInput) - if err != nil { - return fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - if len(assetDeleteInput.ID) == 0 { - return fmt.Errorf("transient input ID field must be a non-empty string") - } - - // Verify that the client is submitting request to peer in their organization - err = verifyClientOrgMatchesPeerOrg(ctx) - if err != nil { - return fmt.Errorf("DeleteTranferAgreement cannot be performed: Error %v", err) - } - // Delete private details of agreement - orgCollection, err := getCollectionName(ctx) // Get proposers collection. - if err != nil { - return fmt.Errorf("failed to infer private collection name for the org: %v", err) - } - tranferAgreeKey, err := ctx.GetStub().CreateCompositeKey(transferAgreementObjectType, []string{assetDeleteInput. - ID}) // Create composite key - if err != nil { - return fmt.Errorf("failed to create composite key: %v", err) - } - - valAsbytes, err := ctx.GetStub().GetPrivateData(assetCollection, tranferAgreeKey) //get the transfer_agreement - if err != nil { - return fmt.Errorf("failed to read transfer_agreement: %v", err) - } - if valAsbytes == nil { - return fmt.Errorf("asset's transfer_agreement does not exist: %v", assetDeleteInput.ID) - } - - log.Printf("Deleting TranferAgreement: %v", assetDeleteInput.ID) - err = ctx.GetStub().DelPrivateData(orgCollection, assetDeleteInput.ID) // Delete the asset - if err != nil { - return err - } - - // Delete transfer agreement record - err = ctx.GetStub().DelPrivateData(assetCollection, tranferAgreeKey) // remove agreement from state - if err != nil { - return err - } - - return nil - -} - -// getCollectionName is an internal helper function to get collection of submitting client identity. -func getCollectionName(ctx contractapi.TransactionContextInterface) (string, error) { - - // Get the MSP ID of submitting client identity - clientMSPID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return "", fmt.Errorf("failed to get verified MSPID: %v", err) - } - - // Create the collection name - orgCollection := clientMSPID + "PrivateCollection" - - return orgCollection, nil -} - -// verifyClientOrgMatchesPeerOrg is an internal function used verify client org id and matches peer org id. -func verifyClientOrgMatchesPeerOrg(ctx contractapi.TransactionContextInterface) error { - clientMSPID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return fmt.Errorf("failed getting the client's MSPID: %v", err) - } - peerMSPID, err := shim.GetMSPID() - if err != nil { - return fmt.Errorf("failed getting the peer's MSPID: %v", err) - } - - if clientMSPID != peerMSPID { - return fmt.Errorf("client from org %v is not authorized to read or write private data from an org %v peer", clientMSPID, peerMSPID) - } - - return nil -} - -func submittingClientIdentity(ctx contractapi.TransactionContextInterface) (string, error) { - b64ID, err := ctx.GetClientIdentity().GetID() - if err != nil { - return "", fmt.Errorf("Failed to read clientID: %v", err) - } - decodeID, err := base64.StdEncoding.DecodeString(b64ID) - if err != nil { - return "", fmt.Errorf("failed to base64 decode clientID: %v", err) - } - return string(decodeID), nil -} diff --git a/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer_test.go b/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer_test.go deleted file mode 100644 index 6eaf338d..00000000 --- a/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer_test.go +++ /dev/null @@ -1,445 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ -package chaincode_test - -import ( - "encoding/base64" - "encoding/json" - "os" - "testing" - - "github.com/hyperledger/fabric-chaincode-go/v2/pkg/cid" - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" - - "github.com/hyperledger/fabric-samples/asset-transfer-private-data/chaincode-go/chaincode" - "github.com/hyperledger/fabric-samples/asset-transfer-private-data/chaincode-go/chaincode/mocks" - "github.com/stretchr/testify/require" -) - -/* -These unit tests use mocks to simulate chaincode-api & fabric interactions -The mocks are generated using counterfeiter directives in the comments (starting with "go:generate counterfeiter") -All files in mocks/* are generated by running following, in the directory with your directive: - `go generate` -*/ - -//go:generate counterfeiter -o mocks/transaction.go -fake-name TransactionContext . transactionContext -type transactionContext interface { - contractapi.TransactionContextInterface -} - -//go:generate counterfeiter -o mocks/chaincodestub.go -fake-name ChaincodeStub . chaincodeStub -type chaincodeStub interface { - shim.ChaincodeStubInterface -} - -//go:generate counterfeiter -o mocks/statequeryiterator.go -fake-name StateQueryIterator . stateQueryIterator -type stateQueryIterator interface { - shim.StateQueryIteratorInterface -} - -//go:generate counterfeiter -o mocks/clientIdentity.go -fake-name ClientIdentity . clientIdentity -type clientIdentity interface { - cid.ClientIdentity -} - -const assetCollectionName = "assetCollection" -const transferAgreementObjectType = "transferAgreement" -const myOrg1Msp = "Org1Testmsp" -const myOrg1Clientid = "myOrg1Userid" -const myOrg1PrivCollection = "Org1TestmspPrivateCollection" -const myOrg2Msp = "Org2Testmsp" -const myOrg2Clientid = "myOrg2Userid" -const myOrg2PrivCollection = "Org2TestmspPrivateCollection" - -type assetTransientInput struct { - Type string `json:"objectType"` - ID string `json:"assetID"` - Color string `json:"color"` - Size int `json:"size"` - AppraisedValue int `json:"appraisedValue"` -} - -type assetTransferTransientInput struct { - ID string `json:"assetID"` - BuyerMSP string `json:"buyerMSP"` -} - -func TestCreateAssetBadInput(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - - // No transient map - err := assetTransferCC.CreateAsset(transactionContext) - require.EqualError(t, err, "asset not found in the transient map input") - - // transient map with incomplete asset data - assetPropMap := map[string][]byte{ - "asset_properties": []byte("ill formatted property"), - } - chaincodeStub.GetTransientReturns(assetPropMap, nil) - err = assetTransferCC.CreateAsset(transactionContext) - require.Error(t, err, "Expected error: transient map with incomplete asset data") - require.Contains(t, err.Error(), "failed to unmarshal JSON") - - testAsset := &assetTransientInput{ - Type: "testfulasset", - } - setReturnAssetPropsInTransientMap(t, chaincodeStub, testAsset) - err = assetTransferCC.CreateAsset(transactionContext) - require.EqualError(t, err, "assetID field must be a non-empty string") - - testAsset = &assetTransientInput{ - ID: "id1", - Color: "gray", - } - setReturnAssetPropsInTransientMap(t, chaincodeStub, testAsset) - err = assetTransferCC.CreateAsset(transactionContext) - require.EqualError(t, err, "objectType field must be a non-empty string") - - // case when asset exists, GetPrivateData returns a valid data from ledger - testAsset = &assetTransientInput{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - AppraisedValue: 500, - } - setReturnAssetPropsInTransientMap(t, chaincodeStub, testAsset) - chaincodeStub.GetPrivateDataReturns([]byte{}, nil) - err = assetTransferCC.CreateAsset(transactionContext) - require.EqualError(t, err, "this asset already exists: id1") -} - -func TestCreateAssetSuccessful(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - testAsset := &assetTransientInput{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - AppraisedValue: 500, - } - setReturnAssetPropsInTransientMap(t, chaincodeStub, testAsset) - err := assetTransferCC.CreateAsset(transactionContext) - require.NoError(t, err) - // Validate PutPrivateData calls - calledCollection, calledId, _ := chaincodeStub.PutPrivateDataArgsForCall(0) - require.Equal(t, assetCollectionName, calledCollection) - require.Equal(t, "id1", calledId) - - expectedPrivateDetails := &chaincode.AssetPrivateDetails{ - ID: "id1", - AppraisedValue: 500, - } - assetBytes, err := json.Marshal(expectedPrivateDetails) - calledCollection, calledId, calledAssetBytes := chaincodeStub.PutPrivateDataArgsForCall(1) - require.Equal(t, myOrg1PrivCollection, calledCollection) - require.Equal(t, "id1", calledId) - require.Equal(t, assetBytes, calledAssetBytes) -} - -func TestAgreeToTransferBadInput(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - - assetPrivDetail := &chaincode.AssetPrivateDetails{ - ID: "id1", - // no AppraisedValue - } - setReturnAssetPrivateDetailsInTransientMap(t, chaincodeStub, assetPrivDetail) - origAsset := chaincode.Asset{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - Owner: myOrg1Clientid, - } - setReturnPrivateDataInStub(t, chaincodeStub, &origAsset) - - err := assetTransferCC.AgreeToTransfer(transactionContext) - require.EqualError(t, err, "appraisedValue field must be a positive integer") - - assetPrivDetail = &chaincode.AssetPrivateDetails{ - // no ID - AppraisedValue: 500, - } - setReturnAssetPrivateDetailsInTransientMap(t, chaincodeStub, assetPrivDetail) - err = assetTransferCC.AgreeToTransfer(transactionContext) - require.EqualError(t, err, "assetID field must be a non-empty string") - - assetPrivDetail = &chaincode.AssetPrivateDetails{ - ID: "id1", - AppraisedValue: 500, - } - setReturnAssetPrivateDetailsInTransientMap(t, chaincodeStub, assetPrivDetail) - // asset does not exist - setReturnPrivateDataInStub(t, chaincodeStub, nil) - err = assetTransferCC.AgreeToTransfer(transactionContext) - require.EqualError(t, err, "id1 does not exist") -} - -func TestAgreeToTransferSuccessful(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - assetPrivDetail := &chaincode.AssetPrivateDetails{ - ID: "id1", - AppraisedValue: 500, - } - setReturnAssetPrivateDetailsInTransientMap(t, chaincodeStub, assetPrivDetail) - origAsset := chaincode.Asset{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - Owner: myOrg1Clientid, - } - setReturnPrivateDataInStub(t, chaincodeStub, &origAsset) - chaincodeStub.CreateCompositeKeyReturns(transferAgreementObjectType+"id1", nil) - err := assetTransferCC.AgreeToTransfer(transactionContext) - require.NoError(t, err) - - expectedDataBytes, err := json.Marshal(assetPrivDetail) - calledCollection, calledId, calledWithDataBytes := chaincodeStub.PutPrivateDataArgsForCall(0) - require.Equal(t, myOrg1PrivCollection, calledCollection) - require.Equal(t, "id1", calledId) - require.Equal(t, expectedDataBytes, calledWithDataBytes) - - calledCollection, calledId, calledWithDataBytes = chaincodeStub.PutPrivateDataArgsForCall(1) - require.Equal(t, assetCollectionName, calledCollection) - require.Equal(t, transferAgreementObjectType+"id1", calledId) - require.Equal(t, []byte(myOrg1Clientid), calledWithDataBytes) -} -func TestTransferAssetBadInput(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - - assetNewOwner := &assetTransferTransientInput{ - ID: "id1", - BuyerMSP: "", - } - setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner) - setReturnPrivateDataInStub(t, chaincodeStub, &chaincode.Asset{}) - err := assetTransferCC.TransferAsset(transactionContext) - require.EqualError(t, err, "buyerMSP field must be a non-empty string") - - assetNewOwner = &assetTransferTransientInput{ - ID: "id1", - BuyerMSP: myOrg2Msp, - } - setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner) - // asset does not exist - setReturnPrivateDataInStub(t, chaincodeStub, nil) - err = assetTransferCC.TransferAsset(transactionContext) - require.EqualError(t, err, "id1 does not exist") -} - -func TestTransferAssetSuccessful(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - assetNewOwner := &assetTransferTransientInput{ - ID: "id1", - BuyerMSP: myOrg2Msp, - } - setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner) - origAsset := chaincode.Asset{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - Owner: myOrg1Clientid, - } - setReturnPrivateDataInStub(t, chaincodeStub, &origAsset) - // to ensure we pass data hash verification - chaincodeStub.GetPrivateDataHashReturns([]byte("datahash"), nil) - // to ensure that ReadTransferAgreement call returns org2 client ID - chaincodeStub.GetPrivateDataReturnsOnCall(1, []byte(myOrg2Clientid), nil) - chaincodeStub.CreateCompositeKeyReturns(transferAgreementObjectType+"id1", nil) - - err := assetTransferCC.TransferAsset(transactionContext) - require.NoError(t, err) - // Validate PutPrivateData calls - expectedNewAsset := origAsset - expectedNewAsset.Owner = myOrg2Clientid - expectedNewAssetBytes, err := json.Marshal(expectedNewAsset) - require.NoError(t, err) - calledCollection, calledId, calledWithAssetBytes := chaincodeStub.PutPrivateDataArgsForCall(0) - require.Equal(t, assetCollectionName, calledCollection) - require.Equal(t, "id1", calledId) - require.Equal(t, expectedNewAssetBytes, calledWithAssetBytes) - calledCollection, calledId = chaincodeStub.DelPrivateDataArgsForCall(0) - require.Equal(t, myOrg1PrivCollection, calledCollection) - require.Equal(t, "id1", calledId) - - calledCollection, calledId = chaincodeStub.DelPrivateDataArgsForCall(1) - require.Equal(t, assetCollectionName, calledCollection) - require.Equal(t, transferAgreementObjectType+"id1", calledId) - -} - -func TestTransferAssetByNonOwner(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - assetNewOwner := &assetTransferTransientInput{ - ID: "id1", - BuyerMSP: myOrg1Msp, - } - setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner) - // Try to transfer asset owned by Org2 - org2Asset := chaincode.Asset{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - Owner: myOrg2Clientid, - } - setReturnPrivateDataInStub(t, chaincodeStub, &org2Asset) - err := assetTransferCC.TransferAsset(transactionContext) - require.EqualError(t, err, "failed transfer verification: error: submitting client identity does not own asset") -} - -func TestTransferAssetWithoutAnAgreement(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - assetNewOwner := &assetTransferTransientInput{ - ID: "id1", - BuyerMSP: myOrg1Msp, - } - setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner) - orgAsset := chaincode.Asset{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - Owner: myOrg1Clientid, - } - setReturnPrivateDataInStub(t, chaincodeStub, &orgAsset) - // to ensure we pass data hash verification - chaincodeStub.GetPrivateDataHashReturns([]byte("datahash"), nil) - chaincodeStub.CreateCompositeKeyReturns(transferAgreementObjectType+"id1", nil) - // ReadTransferAgreement call returns no buyer client ID - chaincodeStub.GetPrivateDataReturnsOnCall(1, []byte{}, nil) - - err := assetTransferCC.TransferAsset(transactionContext) - require.EqualError(t, err, "BuyerID not found in TransferAgreement for id1") -} - -func TestTransferAssetNonMatchingAppraisalValue(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - assetNewOwner := &assetTransferTransientInput{ - ID: "id1", - BuyerMSP: myOrg2Msp, - } - setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner) - - orgAsset := chaincode.Asset{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - Owner: myOrg1Clientid, - } - setReturnPrivateDataInStub(t, chaincodeStub, &orgAsset) - chaincodeStub.CreateCompositeKeyReturns(transferAgreementObjectType+"id1", nil) - // data hash different in each collection - chaincodeStub.GetPrivateDataHashReturnsOnCall(0, []byte("datahash1"), nil) - chaincodeStub.GetPrivateDataHashReturnsOnCall(1, []byte("datahash2"), nil) - - err := assetTransferCC.TransferAsset(transactionContext) - require.Error(t, err, "Expected failed hash verification") - require.Contains(t, err.Error(), "failed transfer verification: hash for appraised value") -} - -func prepMocksAsOrg1() (*mocks.TransactionContext, *mocks.ChaincodeStub) { - return prepMocks(myOrg1Msp, myOrg1Clientid) -} -func prepMocksAsOrg2() (*mocks.TransactionContext, *mocks.ChaincodeStub) { - return prepMocks(myOrg2Msp, myOrg2Clientid) -} -func prepMocks(orgMSP, clientId string) (*mocks.TransactionContext, *mocks.ChaincodeStub) { - chaincodeStub := &mocks.ChaincodeStub{} - transactionContext := &mocks.TransactionContext{} - transactionContext.GetStubReturns(chaincodeStub) - - clientIdentity := &mocks.ClientIdentity{} - clientIdentity.GetMSPIDReturns(orgMSP, nil) - clientIdentity.GetIDReturns(base64.StdEncoding.EncodeToString([]byte(clientId)), nil) - // set matching msp ID using peer shim env variable - os.Setenv("CORE_PEER_LOCALMSPID", orgMSP) - transactionContext.GetClientIdentityReturns(clientIdentity) - return transactionContext, chaincodeStub -} - -func setReturnAssetPrivateDetailsInTransientMap(t *testing.T, chaincodeStub *mocks.ChaincodeStub, assetPrivDetail *chaincode.AssetPrivateDetails) []byte { - assetOwnerBytes := []byte{} - if assetPrivDetail != nil { - var err error - assetOwnerBytes, err = json.Marshal(assetPrivDetail) - require.NoError(t, err) - } - assetPropMap := map[string][]byte{ - "asset_value": assetOwnerBytes, - } - chaincodeStub.GetTransientReturns(assetPropMap, nil) - return assetOwnerBytes -} - -func setReturnAssetOwnerInTransientMap(t *testing.T, chaincodeStub *mocks.ChaincodeStub, assetOwner *assetTransferTransientInput) []byte { - assetOwnerBytes := []byte{} - if assetOwner != nil { - var err error - assetOwnerBytes, err = json.Marshal(assetOwner) - require.NoError(t, err) - } - assetPropMap := map[string][]byte{ - "asset_owner": assetOwnerBytes, - } - chaincodeStub.GetTransientReturns(assetPropMap, nil) - return assetOwnerBytes -} - -func setReturnAssetPropsInTransientMap(t *testing.T, chaincodeStub *mocks.ChaincodeStub, testAsset *assetTransientInput) []byte { - assetBytes := []byte{} - if testAsset != nil { - var err error - assetBytes, err = json.Marshal(testAsset) - require.NoError(t, err) - } - assetPropMap := map[string][]byte{ - "asset_properties": assetBytes, - } - chaincodeStub.GetTransientReturns(assetPropMap, nil) - return assetBytes -} - -func setReturnPrivateDataInStub(t *testing.T, chaincodeStub *mocks.ChaincodeStub, testAsset *chaincode.Asset) []byte { - if testAsset == nil { - chaincodeStub.GetPrivateDataReturns(nil, nil) - return nil - } else { - var err error - assetBytes, err := json.Marshal(testAsset) - require.NoError(t, err) - chaincodeStub.GetPrivateDataReturns(assetBytes, nil) - return assetBytes - } -} - -func setReturnAssetPrivateDetailsInStub(t *testing.T, chaincodeStub *mocks.ChaincodeStub, testAsset *chaincode.AssetPrivateDetails) []byte { - if testAsset == nil { - chaincodeStub.GetPrivateDataReturns(nil, nil) - return nil - } else { - var err error - assetBytes, err := json.Marshal(testAsset) - require.NoError(t, err) - chaincodeStub.GetPrivateDataReturns(assetBytes, nil) - return assetBytes - } -} diff --git a/asset-transfer-private-data/chaincode-go/chaincode/mocks/chaincodestub.go b/asset-transfer-private-data/chaincode-go/chaincode/mocks/chaincodestub.go deleted file mode 100644 index 06248e33..00000000 --- a/asset-transfer-private-data/chaincode-go/chaincode/mocks/chaincodestub.go +++ /dev/null @@ -1,2991 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package mocks - -import ( - "sync" - - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-protos-go-apiv2/peer" - "google.golang.org/protobuf/types/known/timestamppb" -) - -type ChaincodeStub struct { - CreateCompositeKeyStub func(string, []string) (string, error) - createCompositeKeyMutex sync.RWMutex - createCompositeKeyArgsForCall []struct { - arg1 string - arg2 []string - } - createCompositeKeyReturns struct { - result1 string - result2 error - } - createCompositeKeyReturnsOnCall map[int]struct { - result1 string - result2 error - } - DelPrivateDataStub func(string, string) error - delPrivateDataMutex sync.RWMutex - delPrivateDataArgsForCall []struct { - arg1 string - arg2 string - } - delPrivateDataReturns struct { - result1 error - } - delPrivateDataReturnsOnCall map[int]struct { - result1 error - } - DelStateStub func(string) error - delStateMutex sync.RWMutex - delStateArgsForCall []struct { - arg1 string - } - delStateReturns struct { - result1 error - } - delStateReturnsOnCall map[int]struct { - result1 error - } - GetArgsStub func() [][]byte - getArgsMutex sync.RWMutex - getArgsArgsForCall []struct { - } - getArgsReturns struct { - result1 [][]byte - } - getArgsReturnsOnCall map[int]struct { - result1 [][]byte - } - GetArgsSliceStub func() ([]byte, error) - getArgsSliceMutex sync.RWMutex - getArgsSliceArgsForCall []struct { - } - getArgsSliceReturns struct { - result1 []byte - result2 error - } - getArgsSliceReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetBindingStub func() ([]byte, error) - getBindingMutex sync.RWMutex - getBindingArgsForCall []struct { - } - getBindingReturns struct { - result1 []byte - result2 error - } - getBindingReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetChannelIDStub func() string - getChannelIDMutex sync.RWMutex - getChannelIDArgsForCall []struct { - } - getChannelIDReturns struct { - result1 string - } - getChannelIDReturnsOnCall map[int]struct { - result1 string - } - GetCreatorStub func() ([]byte, error) - getCreatorMutex sync.RWMutex - getCreatorArgsForCall []struct { - } - getCreatorReturns struct { - result1 []byte - result2 error - } - getCreatorReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetDecorationsStub func() map[string][]byte - getDecorationsMutex sync.RWMutex - getDecorationsArgsForCall []struct { - } - getDecorationsReturns struct { - result1 map[string][]byte - } - getDecorationsReturnsOnCall map[int]struct { - result1 map[string][]byte - } - GetFunctionAndParametersStub func() (string, []string) - getFunctionAndParametersMutex sync.RWMutex - getFunctionAndParametersArgsForCall []struct { - } - getFunctionAndParametersReturns struct { - result1 string - result2 []string - } - getFunctionAndParametersReturnsOnCall map[int]struct { - result1 string - result2 []string - } - GetHistoryForKeyStub func(string) (shim.HistoryQueryIteratorInterface, error) - getHistoryForKeyMutex sync.RWMutex - getHistoryForKeyArgsForCall []struct { - arg1 string - } - getHistoryForKeyReturns struct { - result1 shim.HistoryQueryIteratorInterface - result2 error - } - getHistoryForKeyReturnsOnCall map[int]struct { - result1 shim.HistoryQueryIteratorInterface - result2 error - } - GetPrivateDataStub func(string, string) ([]byte, error) - getPrivateDataMutex sync.RWMutex - getPrivateDataArgsForCall []struct { - arg1 string - arg2 string - } - getPrivateDataReturns struct { - result1 []byte - result2 error - } - getPrivateDataReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetPrivateDataByPartialCompositeKeyStub func(string, string, []string) (shim.StateQueryIteratorInterface, error) - getPrivateDataByPartialCompositeKeyMutex sync.RWMutex - getPrivateDataByPartialCompositeKeyArgsForCall []struct { - arg1 string - arg2 string - arg3 []string - } - getPrivateDataByPartialCompositeKeyReturns struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - getPrivateDataByPartialCompositeKeyReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - GetPrivateDataByRangeStub func(string, string, string) (shim.StateQueryIteratorInterface, error) - getPrivateDataByRangeMutex sync.RWMutex - getPrivateDataByRangeArgsForCall []struct { - arg1 string - arg2 string - arg3 string - } - getPrivateDataByRangeReturns struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - getPrivateDataByRangeReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - GetPrivateDataHashStub func(string, string) ([]byte, error) - getPrivateDataHashMutex sync.RWMutex - getPrivateDataHashArgsForCall []struct { - arg1 string - arg2 string - } - getPrivateDataHashReturns struct { - result1 []byte - result2 error - } - getPrivateDataHashReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetPrivateDataQueryResultStub func(string, string) (shim.StateQueryIteratorInterface, error) - getPrivateDataQueryResultMutex sync.RWMutex - getPrivateDataQueryResultArgsForCall []struct { - arg1 string - arg2 string - } - getPrivateDataQueryResultReturns struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - getPrivateDataQueryResultReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - GetPrivateDataValidationParameterStub func(string, string) ([]byte, error) - getPrivateDataValidationParameterMutex sync.RWMutex - getPrivateDataValidationParameterArgsForCall []struct { - arg1 string - arg2 string - } - getPrivateDataValidationParameterReturns struct { - result1 []byte - result2 error - } - getPrivateDataValidationParameterReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetQueryResultStub func(string) (shim.StateQueryIteratorInterface, error) - getQueryResultMutex sync.RWMutex - getQueryResultArgsForCall []struct { - arg1 string - } - getQueryResultReturns struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - getQueryResultReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - GetQueryResultWithPaginationStub func(string, int32, string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error) - getQueryResultWithPaginationMutex sync.RWMutex - getQueryResultWithPaginationArgsForCall []struct { - arg1 string - arg2 int32 - arg3 string - } - getQueryResultWithPaginationReturns struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - } - getQueryResultWithPaginationReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - } - GetSignedProposalStub func() (*peer.SignedProposal, error) - getSignedProposalMutex sync.RWMutex - getSignedProposalArgsForCall []struct { - } - getSignedProposalReturns struct { - result1 *peer.SignedProposal - result2 error - } - getSignedProposalReturnsOnCall map[int]struct { - result1 *peer.SignedProposal - result2 error - } - GetStateStub func(string) ([]byte, error) - getStateMutex sync.RWMutex - getStateArgsForCall []struct { - arg1 string - } - getStateReturns struct { - result1 []byte - result2 error - } - getStateReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetStateByPartialCompositeKeyStub func(string, []string) (shim.StateQueryIteratorInterface, error) - getStateByPartialCompositeKeyMutex sync.RWMutex - getStateByPartialCompositeKeyArgsForCall []struct { - arg1 string - arg2 []string - } - getStateByPartialCompositeKeyReturns struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - getStateByPartialCompositeKeyReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - GetStateByPartialCompositeKeyWithPaginationStub func(string, []string, int32, string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error) - getStateByPartialCompositeKeyWithPaginationMutex sync.RWMutex - getStateByPartialCompositeKeyWithPaginationArgsForCall []struct { - arg1 string - arg2 []string - arg3 int32 - arg4 string - } - getStateByPartialCompositeKeyWithPaginationReturns struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - } - getStateByPartialCompositeKeyWithPaginationReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - } - GetStateByRangeStub func(string, string) (shim.StateQueryIteratorInterface, error) - getStateByRangeMutex sync.RWMutex - getStateByRangeArgsForCall []struct { - arg1 string - arg2 string - } - getStateByRangeReturns struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - getStateByRangeReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - } - GetStateByRangeWithPaginationStub func(string, string, int32, string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error) - getStateByRangeWithPaginationMutex sync.RWMutex - getStateByRangeWithPaginationArgsForCall []struct { - arg1 string - arg2 string - arg3 int32 - arg4 string - } - getStateByRangeWithPaginationReturns struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - } - getStateByRangeWithPaginationReturnsOnCall map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - } - GetStateValidationParameterStub func(string) ([]byte, error) - getStateValidationParameterMutex sync.RWMutex - getStateValidationParameterArgsForCall []struct { - arg1 string - } - getStateValidationParameterReturns struct { - result1 []byte - result2 error - } - getStateValidationParameterReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - GetStringArgsStub func() []string - getStringArgsMutex sync.RWMutex - getStringArgsArgsForCall []struct { - } - getStringArgsReturns struct { - result1 []string - } - getStringArgsReturnsOnCall map[int]struct { - result1 []string - } - GetTransientStub func() (map[string][]byte, error) - getTransientMutex sync.RWMutex - getTransientArgsForCall []struct { - } - getTransientReturns struct { - result1 map[string][]byte - result2 error - } - getTransientReturnsOnCall map[int]struct { - result1 map[string][]byte - result2 error - } - GetTxIDStub func() string - getTxIDMutex sync.RWMutex - getTxIDArgsForCall []struct { - } - getTxIDReturns struct { - result1 string - } - getTxIDReturnsOnCall map[int]struct { - result1 string - } - GetTxTimestampStub func() (*timestamppb.Timestamp, error) - getTxTimestampMutex sync.RWMutex - getTxTimestampArgsForCall []struct { - } - getTxTimestampReturns struct { - result1 *timestamppb.Timestamp - result2 error - } - getTxTimestampReturnsOnCall map[int]struct { - result1 *timestamppb.Timestamp - result2 error - } - InvokeChaincodeStub func(string, [][]byte, string) *peer.Response - invokeChaincodeMutex sync.RWMutex - invokeChaincodeArgsForCall []struct { - arg1 string - arg2 [][]byte - arg3 string - } - invokeChaincodeReturns struct { - result1 *peer.Response - } - invokeChaincodeReturnsOnCall map[int]struct { - result1 *peer.Response - } - PurgePrivateDataStub func(string, string) error - purgePrivateDataMutex sync.RWMutex - purgePrivateDataArgsForCall []struct { - arg1 string - arg2 string - } - purgePrivateDataReturns struct { - result1 error - } - purgePrivateDataReturnsOnCall map[int]struct { - result1 error - } - PutPrivateDataStub func(string, string, []byte) error - putPrivateDataMutex sync.RWMutex - putPrivateDataArgsForCall []struct { - arg1 string - arg2 string - arg3 []byte - } - putPrivateDataReturns struct { - result1 error - } - putPrivateDataReturnsOnCall map[int]struct { - result1 error - } - PutStateStub func(string, []byte) error - putStateMutex sync.RWMutex - putStateArgsForCall []struct { - arg1 string - arg2 []byte - } - putStateReturns struct { - result1 error - } - putStateReturnsOnCall map[int]struct { - result1 error - } - SetEventStub func(string, []byte) error - setEventMutex sync.RWMutex - setEventArgsForCall []struct { - arg1 string - arg2 []byte - } - setEventReturns struct { - result1 error - } - setEventReturnsOnCall map[int]struct { - result1 error - } - SetPrivateDataValidationParameterStub func(string, string, []byte) error - setPrivateDataValidationParameterMutex sync.RWMutex - setPrivateDataValidationParameterArgsForCall []struct { - arg1 string - arg2 string - arg3 []byte - } - setPrivateDataValidationParameterReturns struct { - result1 error - } - setPrivateDataValidationParameterReturnsOnCall map[int]struct { - result1 error - } - SetStateValidationParameterStub func(string, []byte) error - setStateValidationParameterMutex sync.RWMutex - setStateValidationParameterArgsForCall []struct { - arg1 string - arg2 []byte - } - setStateValidationParameterReturns struct { - result1 error - } - setStateValidationParameterReturnsOnCall map[int]struct { - result1 error - } - SplitCompositeKeyStub func(string) (string, []string, error) - splitCompositeKeyMutex sync.RWMutex - splitCompositeKeyArgsForCall []struct { - arg1 string - } - splitCompositeKeyReturns struct { - result1 string - result2 []string - result3 error - } - splitCompositeKeyReturnsOnCall map[int]struct { - result1 string - result2 []string - result3 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *ChaincodeStub) CreateCompositeKey(arg1 string, arg2 []string) (string, error) { - var arg2Copy []string - if arg2 != nil { - arg2Copy = make([]string, len(arg2)) - copy(arg2Copy, arg2) - } - fake.createCompositeKeyMutex.Lock() - ret, specificReturn := fake.createCompositeKeyReturnsOnCall[len(fake.createCompositeKeyArgsForCall)] - fake.createCompositeKeyArgsForCall = append(fake.createCompositeKeyArgsForCall, struct { - arg1 string - arg2 []string - }{arg1, arg2Copy}) - stub := fake.CreateCompositeKeyStub - fakeReturns := fake.createCompositeKeyReturns - fake.recordInvocation("CreateCompositeKey", []interface{}{arg1, arg2Copy}) - fake.createCompositeKeyMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) CreateCompositeKeyCallCount() int { - fake.createCompositeKeyMutex.RLock() - defer fake.createCompositeKeyMutex.RUnlock() - return len(fake.createCompositeKeyArgsForCall) -} - -func (fake *ChaincodeStub) CreateCompositeKeyCalls(stub func(string, []string) (string, error)) { - fake.createCompositeKeyMutex.Lock() - defer fake.createCompositeKeyMutex.Unlock() - fake.CreateCompositeKeyStub = stub -} - -func (fake *ChaincodeStub) CreateCompositeKeyArgsForCall(i int) (string, []string) { - fake.createCompositeKeyMutex.RLock() - defer fake.createCompositeKeyMutex.RUnlock() - argsForCall := fake.createCompositeKeyArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) CreateCompositeKeyReturns(result1 string, result2 error) { - fake.createCompositeKeyMutex.Lock() - defer fake.createCompositeKeyMutex.Unlock() - fake.CreateCompositeKeyStub = nil - fake.createCompositeKeyReturns = struct { - result1 string - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) CreateCompositeKeyReturnsOnCall(i int, result1 string, result2 error) { - fake.createCompositeKeyMutex.Lock() - defer fake.createCompositeKeyMutex.Unlock() - fake.CreateCompositeKeyStub = nil - if fake.createCompositeKeyReturnsOnCall == nil { - fake.createCompositeKeyReturnsOnCall = make(map[int]struct { - result1 string - result2 error - }) - } - fake.createCompositeKeyReturnsOnCall[i] = struct { - result1 string - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) DelPrivateData(arg1 string, arg2 string) error { - fake.delPrivateDataMutex.Lock() - ret, specificReturn := fake.delPrivateDataReturnsOnCall[len(fake.delPrivateDataArgsForCall)] - fake.delPrivateDataArgsForCall = append(fake.delPrivateDataArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.DelPrivateDataStub - fakeReturns := fake.delPrivateDataReturns - fake.recordInvocation("DelPrivateData", []interface{}{arg1, arg2}) - fake.delPrivateDataMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) DelPrivateDataCallCount() int { - fake.delPrivateDataMutex.RLock() - defer fake.delPrivateDataMutex.RUnlock() - return len(fake.delPrivateDataArgsForCall) -} - -func (fake *ChaincodeStub) DelPrivateDataCalls(stub func(string, string) error) { - fake.delPrivateDataMutex.Lock() - defer fake.delPrivateDataMutex.Unlock() - fake.DelPrivateDataStub = stub -} - -func (fake *ChaincodeStub) DelPrivateDataArgsForCall(i int) (string, string) { - fake.delPrivateDataMutex.RLock() - defer fake.delPrivateDataMutex.RUnlock() - argsForCall := fake.delPrivateDataArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) DelPrivateDataReturns(result1 error) { - fake.delPrivateDataMutex.Lock() - defer fake.delPrivateDataMutex.Unlock() - fake.DelPrivateDataStub = nil - fake.delPrivateDataReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) DelPrivateDataReturnsOnCall(i int, result1 error) { - fake.delPrivateDataMutex.Lock() - defer fake.delPrivateDataMutex.Unlock() - fake.DelPrivateDataStub = nil - if fake.delPrivateDataReturnsOnCall == nil { - fake.delPrivateDataReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.delPrivateDataReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) DelState(arg1 string) error { - fake.delStateMutex.Lock() - ret, specificReturn := fake.delStateReturnsOnCall[len(fake.delStateArgsForCall)] - fake.delStateArgsForCall = append(fake.delStateArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.DelStateStub - fakeReturns := fake.delStateReturns - fake.recordInvocation("DelState", []interface{}{arg1}) - fake.delStateMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) DelStateCallCount() int { - fake.delStateMutex.RLock() - defer fake.delStateMutex.RUnlock() - return len(fake.delStateArgsForCall) -} - -func (fake *ChaincodeStub) DelStateCalls(stub func(string) error) { - fake.delStateMutex.Lock() - defer fake.delStateMutex.Unlock() - fake.DelStateStub = stub -} - -func (fake *ChaincodeStub) DelStateArgsForCall(i int) string { - fake.delStateMutex.RLock() - defer fake.delStateMutex.RUnlock() - argsForCall := fake.delStateArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ChaincodeStub) DelStateReturns(result1 error) { - fake.delStateMutex.Lock() - defer fake.delStateMutex.Unlock() - fake.DelStateStub = nil - fake.delStateReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) DelStateReturnsOnCall(i int, result1 error) { - fake.delStateMutex.Lock() - defer fake.delStateMutex.Unlock() - fake.DelStateStub = nil - if fake.delStateReturnsOnCall == nil { - fake.delStateReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.delStateReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) GetArgs() [][]byte { - fake.getArgsMutex.Lock() - ret, specificReturn := fake.getArgsReturnsOnCall[len(fake.getArgsArgsForCall)] - fake.getArgsArgsForCall = append(fake.getArgsArgsForCall, struct { - }{}) - stub := fake.GetArgsStub - fakeReturns := fake.getArgsReturns - fake.recordInvocation("GetArgs", []interface{}{}) - fake.getArgsMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) GetArgsCallCount() int { - fake.getArgsMutex.RLock() - defer fake.getArgsMutex.RUnlock() - return len(fake.getArgsArgsForCall) -} - -func (fake *ChaincodeStub) GetArgsCalls(stub func() [][]byte) { - fake.getArgsMutex.Lock() - defer fake.getArgsMutex.Unlock() - fake.GetArgsStub = stub -} - -func (fake *ChaincodeStub) GetArgsReturns(result1 [][]byte) { - fake.getArgsMutex.Lock() - defer fake.getArgsMutex.Unlock() - fake.GetArgsStub = nil - fake.getArgsReturns = struct { - result1 [][]byte - }{result1} -} - -func (fake *ChaincodeStub) GetArgsReturnsOnCall(i int, result1 [][]byte) { - fake.getArgsMutex.Lock() - defer fake.getArgsMutex.Unlock() - fake.GetArgsStub = nil - if fake.getArgsReturnsOnCall == nil { - fake.getArgsReturnsOnCall = make(map[int]struct { - result1 [][]byte - }) - } - fake.getArgsReturnsOnCall[i] = struct { - result1 [][]byte - }{result1} -} - -func (fake *ChaincodeStub) GetArgsSlice() ([]byte, error) { - fake.getArgsSliceMutex.Lock() - ret, specificReturn := fake.getArgsSliceReturnsOnCall[len(fake.getArgsSliceArgsForCall)] - fake.getArgsSliceArgsForCall = append(fake.getArgsSliceArgsForCall, struct { - }{}) - stub := fake.GetArgsSliceStub - fakeReturns := fake.getArgsSliceReturns - fake.recordInvocation("GetArgsSlice", []interface{}{}) - fake.getArgsSliceMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetArgsSliceCallCount() int { - fake.getArgsSliceMutex.RLock() - defer fake.getArgsSliceMutex.RUnlock() - return len(fake.getArgsSliceArgsForCall) -} - -func (fake *ChaincodeStub) GetArgsSliceCalls(stub func() ([]byte, error)) { - fake.getArgsSliceMutex.Lock() - defer fake.getArgsSliceMutex.Unlock() - fake.GetArgsSliceStub = stub -} - -func (fake *ChaincodeStub) GetArgsSliceReturns(result1 []byte, result2 error) { - fake.getArgsSliceMutex.Lock() - defer fake.getArgsSliceMutex.Unlock() - fake.GetArgsSliceStub = nil - fake.getArgsSliceReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetArgsSliceReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getArgsSliceMutex.Lock() - defer fake.getArgsSliceMutex.Unlock() - fake.GetArgsSliceStub = nil - if fake.getArgsSliceReturnsOnCall == nil { - fake.getArgsSliceReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getArgsSliceReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetBinding() ([]byte, error) { - fake.getBindingMutex.Lock() - ret, specificReturn := fake.getBindingReturnsOnCall[len(fake.getBindingArgsForCall)] - fake.getBindingArgsForCall = append(fake.getBindingArgsForCall, struct { - }{}) - stub := fake.GetBindingStub - fakeReturns := fake.getBindingReturns - fake.recordInvocation("GetBinding", []interface{}{}) - fake.getBindingMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetBindingCallCount() int { - fake.getBindingMutex.RLock() - defer fake.getBindingMutex.RUnlock() - return len(fake.getBindingArgsForCall) -} - -func (fake *ChaincodeStub) GetBindingCalls(stub func() ([]byte, error)) { - fake.getBindingMutex.Lock() - defer fake.getBindingMutex.Unlock() - fake.GetBindingStub = stub -} - -func (fake *ChaincodeStub) GetBindingReturns(result1 []byte, result2 error) { - fake.getBindingMutex.Lock() - defer fake.getBindingMutex.Unlock() - fake.GetBindingStub = nil - fake.getBindingReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetBindingReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getBindingMutex.Lock() - defer fake.getBindingMutex.Unlock() - fake.GetBindingStub = nil - if fake.getBindingReturnsOnCall == nil { - fake.getBindingReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getBindingReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetChannelID() string { - fake.getChannelIDMutex.Lock() - ret, specificReturn := fake.getChannelIDReturnsOnCall[len(fake.getChannelIDArgsForCall)] - fake.getChannelIDArgsForCall = append(fake.getChannelIDArgsForCall, struct { - }{}) - stub := fake.GetChannelIDStub - fakeReturns := fake.getChannelIDReturns - fake.recordInvocation("GetChannelID", []interface{}{}) - fake.getChannelIDMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) GetChannelIDCallCount() int { - fake.getChannelIDMutex.RLock() - defer fake.getChannelIDMutex.RUnlock() - return len(fake.getChannelIDArgsForCall) -} - -func (fake *ChaincodeStub) GetChannelIDCalls(stub func() string) { - fake.getChannelIDMutex.Lock() - defer fake.getChannelIDMutex.Unlock() - fake.GetChannelIDStub = stub -} - -func (fake *ChaincodeStub) GetChannelIDReturns(result1 string) { - fake.getChannelIDMutex.Lock() - defer fake.getChannelIDMutex.Unlock() - fake.GetChannelIDStub = nil - fake.getChannelIDReturns = struct { - result1 string - }{result1} -} - -func (fake *ChaincodeStub) GetChannelIDReturnsOnCall(i int, result1 string) { - fake.getChannelIDMutex.Lock() - defer fake.getChannelIDMutex.Unlock() - fake.GetChannelIDStub = nil - if fake.getChannelIDReturnsOnCall == nil { - fake.getChannelIDReturnsOnCall = make(map[int]struct { - result1 string - }) - } - fake.getChannelIDReturnsOnCall[i] = struct { - result1 string - }{result1} -} - -func (fake *ChaincodeStub) GetCreator() ([]byte, error) { - fake.getCreatorMutex.Lock() - ret, specificReturn := fake.getCreatorReturnsOnCall[len(fake.getCreatorArgsForCall)] - fake.getCreatorArgsForCall = append(fake.getCreatorArgsForCall, struct { - }{}) - stub := fake.GetCreatorStub - fakeReturns := fake.getCreatorReturns - fake.recordInvocation("GetCreator", []interface{}{}) - fake.getCreatorMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetCreatorCallCount() int { - fake.getCreatorMutex.RLock() - defer fake.getCreatorMutex.RUnlock() - return len(fake.getCreatorArgsForCall) -} - -func (fake *ChaincodeStub) GetCreatorCalls(stub func() ([]byte, error)) { - fake.getCreatorMutex.Lock() - defer fake.getCreatorMutex.Unlock() - fake.GetCreatorStub = stub -} - -func (fake *ChaincodeStub) GetCreatorReturns(result1 []byte, result2 error) { - fake.getCreatorMutex.Lock() - defer fake.getCreatorMutex.Unlock() - fake.GetCreatorStub = nil - fake.getCreatorReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetCreatorReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getCreatorMutex.Lock() - defer fake.getCreatorMutex.Unlock() - fake.GetCreatorStub = nil - if fake.getCreatorReturnsOnCall == nil { - fake.getCreatorReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getCreatorReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetDecorations() map[string][]byte { - fake.getDecorationsMutex.Lock() - ret, specificReturn := fake.getDecorationsReturnsOnCall[len(fake.getDecorationsArgsForCall)] - fake.getDecorationsArgsForCall = append(fake.getDecorationsArgsForCall, struct { - }{}) - stub := fake.GetDecorationsStub - fakeReturns := fake.getDecorationsReturns - fake.recordInvocation("GetDecorations", []interface{}{}) - fake.getDecorationsMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) GetDecorationsCallCount() int { - fake.getDecorationsMutex.RLock() - defer fake.getDecorationsMutex.RUnlock() - return len(fake.getDecorationsArgsForCall) -} - -func (fake *ChaincodeStub) GetDecorationsCalls(stub func() map[string][]byte) { - fake.getDecorationsMutex.Lock() - defer fake.getDecorationsMutex.Unlock() - fake.GetDecorationsStub = stub -} - -func (fake *ChaincodeStub) GetDecorationsReturns(result1 map[string][]byte) { - fake.getDecorationsMutex.Lock() - defer fake.getDecorationsMutex.Unlock() - fake.GetDecorationsStub = nil - fake.getDecorationsReturns = struct { - result1 map[string][]byte - }{result1} -} - -func (fake *ChaincodeStub) GetDecorationsReturnsOnCall(i int, result1 map[string][]byte) { - fake.getDecorationsMutex.Lock() - defer fake.getDecorationsMutex.Unlock() - fake.GetDecorationsStub = nil - if fake.getDecorationsReturnsOnCall == nil { - fake.getDecorationsReturnsOnCall = make(map[int]struct { - result1 map[string][]byte - }) - } - fake.getDecorationsReturnsOnCall[i] = struct { - result1 map[string][]byte - }{result1} -} - -func (fake *ChaincodeStub) GetFunctionAndParameters() (string, []string) { - fake.getFunctionAndParametersMutex.Lock() - ret, specificReturn := fake.getFunctionAndParametersReturnsOnCall[len(fake.getFunctionAndParametersArgsForCall)] - fake.getFunctionAndParametersArgsForCall = append(fake.getFunctionAndParametersArgsForCall, struct { - }{}) - stub := fake.GetFunctionAndParametersStub - fakeReturns := fake.getFunctionAndParametersReturns - fake.recordInvocation("GetFunctionAndParameters", []interface{}{}) - fake.getFunctionAndParametersMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetFunctionAndParametersCallCount() int { - fake.getFunctionAndParametersMutex.RLock() - defer fake.getFunctionAndParametersMutex.RUnlock() - return len(fake.getFunctionAndParametersArgsForCall) -} - -func (fake *ChaincodeStub) GetFunctionAndParametersCalls(stub func() (string, []string)) { - fake.getFunctionAndParametersMutex.Lock() - defer fake.getFunctionAndParametersMutex.Unlock() - fake.GetFunctionAndParametersStub = stub -} - -func (fake *ChaincodeStub) GetFunctionAndParametersReturns(result1 string, result2 []string) { - fake.getFunctionAndParametersMutex.Lock() - defer fake.getFunctionAndParametersMutex.Unlock() - fake.GetFunctionAndParametersStub = nil - fake.getFunctionAndParametersReturns = struct { - result1 string - result2 []string - }{result1, result2} -} - -func (fake *ChaincodeStub) GetFunctionAndParametersReturnsOnCall(i int, result1 string, result2 []string) { - fake.getFunctionAndParametersMutex.Lock() - defer fake.getFunctionAndParametersMutex.Unlock() - fake.GetFunctionAndParametersStub = nil - if fake.getFunctionAndParametersReturnsOnCall == nil { - fake.getFunctionAndParametersReturnsOnCall = make(map[int]struct { - result1 string - result2 []string - }) - } - fake.getFunctionAndParametersReturnsOnCall[i] = struct { - result1 string - result2 []string - }{result1, result2} -} - -func (fake *ChaincodeStub) GetHistoryForKey(arg1 string) (shim.HistoryQueryIteratorInterface, error) { - fake.getHistoryForKeyMutex.Lock() - ret, specificReturn := fake.getHistoryForKeyReturnsOnCall[len(fake.getHistoryForKeyArgsForCall)] - fake.getHistoryForKeyArgsForCall = append(fake.getHistoryForKeyArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.GetHistoryForKeyStub - fakeReturns := fake.getHistoryForKeyReturns - fake.recordInvocation("GetHistoryForKey", []interface{}{arg1}) - fake.getHistoryForKeyMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetHistoryForKeyCallCount() int { - fake.getHistoryForKeyMutex.RLock() - defer fake.getHistoryForKeyMutex.RUnlock() - return len(fake.getHistoryForKeyArgsForCall) -} - -func (fake *ChaincodeStub) GetHistoryForKeyCalls(stub func(string) (shim.HistoryQueryIteratorInterface, error)) { - fake.getHistoryForKeyMutex.Lock() - defer fake.getHistoryForKeyMutex.Unlock() - fake.GetHistoryForKeyStub = stub -} - -func (fake *ChaincodeStub) GetHistoryForKeyArgsForCall(i int) string { - fake.getHistoryForKeyMutex.RLock() - defer fake.getHistoryForKeyMutex.RUnlock() - argsForCall := fake.getHistoryForKeyArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ChaincodeStub) GetHistoryForKeyReturns(result1 shim.HistoryQueryIteratorInterface, result2 error) { - fake.getHistoryForKeyMutex.Lock() - defer fake.getHistoryForKeyMutex.Unlock() - fake.GetHistoryForKeyStub = nil - fake.getHistoryForKeyReturns = struct { - result1 shim.HistoryQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetHistoryForKeyReturnsOnCall(i int, result1 shim.HistoryQueryIteratorInterface, result2 error) { - fake.getHistoryForKeyMutex.Lock() - defer fake.getHistoryForKeyMutex.Unlock() - fake.GetHistoryForKeyStub = nil - if fake.getHistoryForKeyReturnsOnCall == nil { - fake.getHistoryForKeyReturnsOnCall = make(map[int]struct { - result1 shim.HistoryQueryIteratorInterface - result2 error - }) - } - fake.getHistoryForKeyReturnsOnCall[i] = struct { - result1 shim.HistoryQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateData(arg1 string, arg2 string) ([]byte, error) { - fake.getPrivateDataMutex.Lock() - ret, specificReturn := fake.getPrivateDataReturnsOnCall[len(fake.getPrivateDataArgsForCall)] - fake.getPrivateDataArgsForCall = append(fake.getPrivateDataArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.GetPrivateDataStub - fakeReturns := fake.getPrivateDataReturns - fake.recordInvocation("GetPrivateData", []interface{}{arg1, arg2}) - fake.getPrivateDataMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetPrivateDataCallCount() int { - fake.getPrivateDataMutex.RLock() - defer fake.getPrivateDataMutex.RUnlock() - return len(fake.getPrivateDataArgsForCall) -} - -func (fake *ChaincodeStub) GetPrivateDataCalls(stub func(string, string) ([]byte, error)) { - fake.getPrivateDataMutex.Lock() - defer fake.getPrivateDataMutex.Unlock() - fake.GetPrivateDataStub = stub -} - -func (fake *ChaincodeStub) GetPrivateDataArgsForCall(i int) (string, string) { - fake.getPrivateDataMutex.RLock() - defer fake.getPrivateDataMutex.RUnlock() - argsForCall := fake.getPrivateDataArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) GetPrivateDataReturns(result1 []byte, result2 error) { - fake.getPrivateDataMutex.Lock() - defer fake.getPrivateDataMutex.Unlock() - fake.GetPrivateDataStub = nil - fake.getPrivateDataReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getPrivateDataMutex.Lock() - defer fake.getPrivateDataMutex.Unlock() - fake.GetPrivateDataStub = nil - if fake.getPrivateDataReturnsOnCall == nil { - fake.getPrivateDataReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getPrivateDataReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataByPartialCompositeKey(arg1 string, arg2 string, arg3 []string) (shim.StateQueryIteratorInterface, error) { - var arg3Copy []string - if arg3 != nil { - arg3Copy = make([]string, len(arg3)) - copy(arg3Copy, arg3) - } - fake.getPrivateDataByPartialCompositeKeyMutex.Lock() - ret, specificReturn := fake.getPrivateDataByPartialCompositeKeyReturnsOnCall[len(fake.getPrivateDataByPartialCompositeKeyArgsForCall)] - fake.getPrivateDataByPartialCompositeKeyArgsForCall = append(fake.getPrivateDataByPartialCompositeKeyArgsForCall, struct { - arg1 string - arg2 string - arg3 []string - }{arg1, arg2, arg3Copy}) - stub := fake.GetPrivateDataByPartialCompositeKeyStub - fakeReturns := fake.getPrivateDataByPartialCompositeKeyReturns - fake.recordInvocation("GetPrivateDataByPartialCompositeKey", []interface{}{arg1, arg2, arg3Copy}) - fake.getPrivateDataByPartialCompositeKeyMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetPrivateDataByPartialCompositeKeyCallCount() int { - fake.getPrivateDataByPartialCompositeKeyMutex.RLock() - defer fake.getPrivateDataByPartialCompositeKeyMutex.RUnlock() - return len(fake.getPrivateDataByPartialCompositeKeyArgsForCall) -} - -func (fake *ChaincodeStub) GetPrivateDataByPartialCompositeKeyCalls(stub func(string, string, []string) (shim.StateQueryIteratorInterface, error)) { - fake.getPrivateDataByPartialCompositeKeyMutex.Lock() - defer fake.getPrivateDataByPartialCompositeKeyMutex.Unlock() - fake.GetPrivateDataByPartialCompositeKeyStub = stub -} - -func (fake *ChaincodeStub) GetPrivateDataByPartialCompositeKeyArgsForCall(i int) (string, string, []string) { - fake.getPrivateDataByPartialCompositeKeyMutex.RLock() - defer fake.getPrivateDataByPartialCompositeKeyMutex.RUnlock() - argsForCall := fake.getPrivateDataByPartialCompositeKeyArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *ChaincodeStub) GetPrivateDataByPartialCompositeKeyReturns(result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getPrivateDataByPartialCompositeKeyMutex.Lock() - defer fake.getPrivateDataByPartialCompositeKeyMutex.Unlock() - fake.GetPrivateDataByPartialCompositeKeyStub = nil - fake.getPrivateDataByPartialCompositeKeyReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataByPartialCompositeKeyReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getPrivateDataByPartialCompositeKeyMutex.Lock() - defer fake.getPrivateDataByPartialCompositeKeyMutex.Unlock() - fake.GetPrivateDataByPartialCompositeKeyStub = nil - if fake.getPrivateDataByPartialCompositeKeyReturnsOnCall == nil { - fake.getPrivateDataByPartialCompositeKeyReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - }) - } - fake.getPrivateDataByPartialCompositeKeyReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataByRange(arg1 string, arg2 string, arg3 string) (shim.StateQueryIteratorInterface, error) { - fake.getPrivateDataByRangeMutex.Lock() - ret, specificReturn := fake.getPrivateDataByRangeReturnsOnCall[len(fake.getPrivateDataByRangeArgsForCall)] - fake.getPrivateDataByRangeArgsForCall = append(fake.getPrivateDataByRangeArgsForCall, struct { - arg1 string - arg2 string - arg3 string - }{arg1, arg2, arg3}) - stub := fake.GetPrivateDataByRangeStub - fakeReturns := fake.getPrivateDataByRangeReturns - fake.recordInvocation("GetPrivateDataByRange", []interface{}{arg1, arg2, arg3}) - fake.getPrivateDataByRangeMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetPrivateDataByRangeCallCount() int { - fake.getPrivateDataByRangeMutex.RLock() - defer fake.getPrivateDataByRangeMutex.RUnlock() - return len(fake.getPrivateDataByRangeArgsForCall) -} - -func (fake *ChaincodeStub) GetPrivateDataByRangeCalls(stub func(string, string, string) (shim.StateQueryIteratorInterface, error)) { - fake.getPrivateDataByRangeMutex.Lock() - defer fake.getPrivateDataByRangeMutex.Unlock() - fake.GetPrivateDataByRangeStub = stub -} - -func (fake *ChaincodeStub) GetPrivateDataByRangeArgsForCall(i int) (string, string, string) { - fake.getPrivateDataByRangeMutex.RLock() - defer fake.getPrivateDataByRangeMutex.RUnlock() - argsForCall := fake.getPrivateDataByRangeArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *ChaincodeStub) GetPrivateDataByRangeReturns(result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getPrivateDataByRangeMutex.Lock() - defer fake.getPrivateDataByRangeMutex.Unlock() - fake.GetPrivateDataByRangeStub = nil - fake.getPrivateDataByRangeReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataByRangeReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getPrivateDataByRangeMutex.Lock() - defer fake.getPrivateDataByRangeMutex.Unlock() - fake.GetPrivateDataByRangeStub = nil - if fake.getPrivateDataByRangeReturnsOnCall == nil { - fake.getPrivateDataByRangeReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - }) - } - fake.getPrivateDataByRangeReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataHash(arg1 string, arg2 string) ([]byte, error) { - fake.getPrivateDataHashMutex.Lock() - ret, specificReturn := fake.getPrivateDataHashReturnsOnCall[len(fake.getPrivateDataHashArgsForCall)] - fake.getPrivateDataHashArgsForCall = append(fake.getPrivateDataHashArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.GetPrivateDataHashStub - fakeReturns := fake.getPrivateDataHashReturns - fake.recordInvocation("GetPrivateDataHash", []interface{}{arg1, arg2}) - fake.getPrivateDataHashMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetPrivateDataHashCallCount() int { - fake.getPrivateDataHashMutex.RLock() - defer fake.getPrivateDataHashMutex.RUnlock() - return len(fake.getPrivateDataHashArgsForCall) -} - -func (fake *ChaincodeStub) GetPrivateDataHashCalls(stub func(string, string) ([]byte, error)) { - fake.getPrivateDataHashMutex.Lock() - defer fake.getPrivateDataHashMutex.Unlock() - fake.GetPrivateDataHashStub = stub -} - -func (fake *ChaincodeStub) GetPrivateDataHashArgsForCall(i int) (string, string) { - fake.getPrivateDataHashMutex.RLock() - defer fake.getPrivateDataHashMutex.RUnlock() - argsForCall := fake.getPrivateDataHashArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) GetPrivateDataHashReturns(result1 []byte, result2 error) { - fake.getPrivateDataHashMutex.Lock() - defer fake.getPrivateDataHashMutex.Unlock() - fake.GetPrivateDataHashStub = nil - fake.getPrivateDataHashReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataHashReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getPrivateDataHashMutex.Lock() - defer fake.getPrivateDataHashMutex.Unlock() - fake.GetPrivateDataHashStub = nil - if fake.getPrivateDataHashReturnsOnCall == nil { - fake.getPrivateDataHashReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getPrivateDataHashReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataQueryResult(arg1 string, arg2 string) (shim.StateQueryIteratorInterface, error) { - fake.getPrivateDataQueryResultMutex.Lock() - ret, specificReturn := fake.getPrivateDataQueryResultReturnsOnCall[len(fake.getPrivateDataQueryResultArgsForCall)] - fake.getPrivateDataQueryResultArgsForCall = append(fake.getPrivateDataQueryResultArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.GetPrivateDataQueryResultStub - fakeReturns := fake.getPrivateDataQueryResultReturns - fake.recordInvocation("GetPrivateDataQueryResult", []interface{}{arg1, arg2}) - fake.getPrivateDataQueryResultMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetPrivateDataQueryResultCallCount() int { - fake.getPrivateDataQueryResultMutex.RLock() - defer fake.getPrivateDataQueryResultMutex.RUnlock() - return len(fake.getPrivateDataQueryResultArgsForCall) -} - -func (fake *ChaincodeStub) GetPrivateDataQueryResultCalls(stub func(string, string) (shim.StateQueryIteratorInterface, error)) { - fake.getPrivateDataQueryResultMutex.Lock() - defer fake.getPrivateDataQueryResultMutex.Unlock() - fake.GetPrivateDataQueryResultStub = stub -} - -func (fake *ChaincodeStub) GetPrivateDataQueryResultArgsForCall(i int) (string, string) { - fake.getPrivateDataQueryResultMutex.RLock() - defer fake.getPrivateDataQueryResultMutex.RUnlock() - argsForCall := fake.getPrivateDataQueryResultArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) GetPrivateDataQueryResultReturns(result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getPrivateDataQueryResultMutex.Lock() - defer fake.getPrivateDataQueryResultMutex.Unlock() - fake.GetPrivateDataQueryResultStub = nil - fake.getPrivateDataQueryResultReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataQueryResultReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getPrivateDataQueryResultMutex.Lock() - defer fake.getPrivateDataQueryResultMutex.Unlock() - fake.GetPrivateDataQueryResultStub = nil - if fake.getPrivateDataQueryResultReturnsOnCall == nil { - fake.getPrivateDataQueryResultReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - }) - } - fake.getPrivateDataQueryResultReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataValidationParameter(arg1 string, arg2 string) ([]byte, error) { - fake.getPrivateDataValidationParameterMutex.Lock() - ret, specificReturn := fake.getPrivateDataValidationParameterReturnsOnCall[len(fake.getPrivateDataValidationParameterArgsForCall)] - fake.getPrivateDataValidationParameterArgsForCall = append(fake.getPrivateDataValidationParameterArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.GetPrivateDataValidationParameterStub - fakeReturns := fake.getPrivateDataValidationParameterReturns - fake.recordInvocation("GetPrivateDataValidationParameter", []interface{}{arg1, arg2}) - fake.getPrivateDataValidationParameterMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetPrivateDataValidationParameterCallCount() int { - fake.getPrivateDataValidationParameterMutex.RLock() - defer fake.getPrivateDataValidationParameterMutex.RUnlock() - return len(fake.getPrivateDataValidationParameterArgsForCall) -} - -func (fake *ChaincodeStub) GetPrivateDataValidationParameterCalls(stub func(string, string) ([]byte, error)) { - fake.getPrivateDataValidationParameterMutex.Lock() - defer fake.getPrivateDataValidationParameterMutex.Unlock() - fake.GetPrivateDataValidationParameterStub = stub -} - -func (fake *ChaincodeStub) GetPrivateDataValidationParameterArgsForCall(i int) (string, string) { - fake.getPrivateDataValidationParameterMutex.RLock() - defer fake.getPrivateDataValidationParameterMutex.RUnlock() - argsForCall := fake.getPrivateDataValidationParameterArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) GetPrivateDataValidationParameterReturns(result1 []byte, result2 error) { - fake.getPrivateDataValidationParameterMutex.Lock() - defer fake.getPrivateDataValidationParameterMutex.Unlock() - fake.GetPrivateDataValidationParameterStub = nil - fake.getPrivateDataValidationParameterReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetPrivateDataValidationParameterReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getPrivateDataValidationParameterMutex.Lock() - defer fake.getPrivateDataValidationParameterMutex.Unlock() - fake.GetPrivateDataValidationParameterStub = nil - if fake.getPrivateDataValidationParameterReturnsOnCall == nil { - fake.getPrivateDataValidationParameterReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getPrivateDataValidationParameterReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetQueryResult(arg1 string) (shim.StateQueryIteratorInterface, error) { - fake.getQueryResultMutex.Lock() - ret, specificReturn := fake.getQueryResultReturnsOnCall[len(fake.getQueryResultArgsForCall)] - fake.getQueryResultArgsForCall = append(fake.getQueryResultArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.GetQueryResultStub - fakeReturns := fake.getQueryResultReturns - fake.recordInvocation("GetQueryResult", []interface{}{arg1}) - fake.getQueryResultMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetQueryResultCallCount() int { - fake.getQueryResultMutex.RLock() - defer fake.getQueryResultMutex.RUnlock() - return len(fake.getQueryResultArgsForCall) -} - -func (fake *ChaincodeStub) GetQueryResultCalls(stub func(string) (shim.StateQueryIteratorInterface, error)) { - fake.getQueryResultMutex.Lock() - defer fake.getQueryResultMutex.Unlock() - fake.GetQueryResultStub = stub -} - -func (fake *ChaincodeStub) GetQueryResultArgsForCall(i int) string { - fake.getQueryResultMutex.RLock() - defer fake.getQueryResultMutex.RUnlock() - argsForCall := fake.getQueryResultArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ChaincodeStub) GetQueryResultReturns(result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getQueryResultMutex.Lock() - defer fake.getQueryResultMutex.Unlock() - fake.GetQueryResultStub = nil - fake.getQueryResultReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetQueryResultReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getQueryResultMutex.Lock() - defer fake.getQueryResultMutex.Unlock() - fake.GetQueryResultStub = nil - if fake.getQueryResultReturnsOnCall == nil { - fake.getQueryResultReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - }) - } - fake.getQueryResultReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetQueryResultWithPagination(arg1 string, arg2 int32, arg3 string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error) { - fake.getQueryResultWithPaginationMutex.Lock() - ret, specificReturn := fake.getQueryResultWithPaginationReturnsOnCall[len(fake.getQueryResultWithPaginationArgsForCall)] - fake.getQueryResultWithPaginationArgsForCall = append(fake.getQueryResultWithPaginationArgsForCall, struct { - arg1 string - arg2 int32 - arg3 string - }{arg1, arg2, arg3}) - stub := fake.GetQueryResultWithPaginationStub - fakeReturns := fake.getQueryResultWithPaginationReturns - fake.recordInvocation("GetQueryResultWithPagination", []interface{}{arg1, arg2, arg3}) - fake.getQueryResultWithPaginationMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *ChaincodeStub) GetQueryResultWithPaginationCallCount() int { - fake.getQueryResultWithPaginationMutex.RLock() - defer fake.getQueryResultWithPaginationMutex.RUnlock() - return len(fake.getQueryResultWithPaginationArgsForCall) -} - -func (fake *ChaincodeStub) GetQueryResultWithPaginationCalls(stub func(string, int32, string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error)) { - fake.getQueryResultWithPaginationMutex.Lock() - defer fake.getQueryResultWithPaginationMutex.Unlock() - fake.GetQueryResultWithPaginationStub = stub -} - -func (fake *ChaincodeStub) GetQueryResultWithPaginationArgsForCall(i int) (string, int32, string) { - fake.getQueryResultWithPaginationMutex.RLock() - defer fake.getQueryResultWithPaginationMutex.RUnlock() - argsForCall := fake.getQueryResultWithPaginationArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *ChaincodeStub) GetQueryResultWithPaginationReturns(result1 shim.StateQueryIteratorInterface, result2 *peer.QueryResponseMetadata, result3 error) { - fake.getQueryResultWithPaginationMutex.Lock() - defer fake.getQueryResultWithPaginationMutex.Unlock() - fake.GetQueryResultWithPaginationStub = nil - fake.getQueryResultWithPaginationReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) GetQueryResultWithPaginationReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 *peer.QueryResponseMetadata, result3 error) { - fake.getQueryResultWithPaginationMutex.Lock() - defer fake.getQueryResultWithPaginationMutex.Unlock() - fake.GetQueryResultWithPaginationStub = nil - if fake.getQueryResultWithPaginationReturnsOnCall == nil { - fake.getQueryResultWithPaginationReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }) - } - fake.getQueryResultWithPaginationReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) GetSignedProposal() (*peer.SignedProposal, error) { - fake.getSignedProposalMutex.Lock() - ret, specificReturn := fake.getSignedProposalReturnsOnCall[len(fake.getSignedProposalArgsForCall)] - fake.getSignedProposalArgsForCall = append(fake.getSignedProposalArgsForCall, struct { - }{}) - stub := fake.GetSignedProposalStub - fakeReturns := fake.getSignedProposalReturns - fake.recordInvocation("GetSignedProposal", []interface{}{}) - fake.getSignedProposalMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetSignedProposalCallCount() int { - fake.getSignedProposalMutex.RLock() - defer fake.getSignedProposalMutex.RUnlock() - return len(fake.getSignedProposalArgsForCall) -} - -func (fake *ChaincodeStub) GetSignedProposalCalls(stub func() (*peer.SignedProposal, error)) { - fake.getSignedProposalMutex.Lock() - defer fake.getSignedProposalMutex.Unlock() - fake.GetSignedProposalStub = stub -} - -func (fake *ChaincodeStub) GetSignedProposalReturns(result1 *peer.SignedProposal, result2 error) { - fake.getSignedProposalMutex.Lock() - defer fake.getSignedProposalMutex.Unlock() - fake.GetSignedProposalStub = nil - fake.getSignedProposalReturns = struct { - result1 *peer.SignedProposal - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetSignedProposalReturnsOnCall(i int, result1 *peer.SignedProposal, result2 error) { - fake.getSignedProposalMutex.Lock() - defer fake.getSignedProposalMutex.Unlock() - fake.GetSignedProposalStub = nil - if fake.getSignedProposalReturnsOnCall == nil { - fake.getSignedProposalReturnsOnCall = make(map[int]struct { - result1 *peer.SignedProposal - result2 error - }) - } - fake.getSignedProposalReturnsOnCall[i] = struct { - result1 *peer.SignedProposal - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetState(arg1 string) ([]byte, error) { - fake.getStateMutex.Lock() - ret, specificReturn := fake.getStateReturnsOnCall[len(fake.getStateArgsForCall)] - fake.getStateArgsForCall = append(fake.getStateArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.GetStateStub - fakeReturns := fake.getStateReturns - fake.recordInvocation("GetState", []interface{}{arg1}) - fake.getStateMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetStateCallCount() int { - fake.getStateMutex.RLock() - defer fake.getStateMutex.RUnlock() - return len(fake.getStateArgsForCall) -} - -func (fake *ChaincodeStub) GetStateCalls(stub func(string) ([]byte, error)) { - fake.getStateMutex.Lock() - defer fake.getStateMutex.Unlock() - fake.GetStateStub = stub -} - -func (fake *ChaincodeStub) GetStateArgsForCall(i int) string { - fake.getStateMutex.RLock() - defer fake.getStateMutex.RUnlock() - argsForCall := fake.getStateArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ChaincodeStub) GetStateReturns(result1 []byte, result2 error) { - fake.getStateMutex.Lock() - defer fake.getStateMutex.Unlock() - fake.GetStateStub = nil - fake.getStateReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getStateMutex.Lock() - defer fake.getStateMutex.Unlock() - fake.GetStateStub = nil - if fake.getStateReturnsOnCall == nil { - fake.getStateReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getStateReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKey(arg1 string, arg2 []string) (shim.StateQueryIteratorInterface, error) { - var arg2Copy []string - if arg2 != nil { - arg2Copy = make([]string, len(arg2)) - copy(arg2Copy, arg2) - } - fake.getStateByPartialCompositeKeyMutex.Lock() - ret, specificReturn := fake.getStateByPartialCompositeKeyReturnsOnCall[len(fake.getStateByPartialCompositeKeyArgsForCall)] - fake.getStateByPartialCompositeKeyArgsForCall = append(fake.getStateByPartialCompositeKeyArgsForCall, struct { - arg1 string - arg2 []string - }{arg1, arg2Copy}) - stub := fake.GetStateByPartialCompositeKeyStub - fakeReturns := fake.getStateByPartialCompositeKeyReturns - fake.recordInvocation("GetStateByPartialCompositeKey", []interface{}{arg1, arg2Copy}) - fake.getStateByPartialCompositeKeyMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyCallCount() int { - fake.getStateByPartialCompositeKeyMutex.RLock() - defer fake.getStateByPartialCompositeKeyMutex.RUnlock() - return len(fake.getStateByPartialCompositeKeyArgsForCall) -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyCalls(stub func(string, []string) (shim.StateQueryIteratorInterface, error)) { - fake.getStateByPartialCompositeKeyMutex.Lock() - defer fake.getStateByPartialCompositeKeyMutex.Unlock() - fake.GetStateByPartialCompositeKeyStub = stub -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyArgsForCall(i int) (string, []string) { - fake.getStateByPartialCompositeKeyMutex.RLock() - defer fake.getStateByPartialCompositeKeyMutex.RUnlock() - argsForCall := fake.getStateByPartialCompositeKeyArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyReturns(result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getStateByPartialCompositeKeyMutex.Lock() - defer fake.getStateByPartialCompositeKeyMutex.Unlock() - fake.GetStateByPartialCompositeKeyStub = nil - fake.getStateByPartialCompositeKeyReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getStateByPartialCompositeKeyMutex.Lock() - defer fake.getStateByPartialCompositeKeyMutex.Unlock() - fake.GetStateByPartialCompositeKeyStub = nil - if fake.getStateByPartialCompositeKeyReturnsOnCall == nil { - fake.getStateByPartialCompositeKeyReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - }) - } - fake.getStateByPartialCompositeKeyReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyWithPagination(arg1 string, arg2 []string, arg3 int32, arg4 string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error) { - var arg2Copy []string - if arg2 != nil { - arg2Copy = make([]string, len(arg2)) - copy(arg2Copy, arg2) - } - fake.getStateByPartialCompositeKeyWithPaginationMutex.Lock() - ret, specificReturn := fake.getStateByPartialCompositeKeyWithPaginationReturnsOnCall[len(fake.getStateByPartialCompositeKeyWithPaginationArgsForCall)] - fake.getStateByPartialCompositeKeyWithPaginationArgsForCall = append(fake.getStateByPartialCompositeKeyWithPaginationArgsForCall, struct { - arg1 string - arg2 []string - arg3 int32 - arg4 string - }{arg1, arg2Copy, arg3, arg4}) - stub := fake.GetStateByPartialCompositeKeyWithPaginationStub - fakeReturns := fake.getStateByPartialCompositeKeyWithPaginationReturns - fake.recordInvocation("GetStateByPartialCompositeKeyWithPagination", []interface{}{arg1, arg2Copy, arg3, arg4}) - fake.getStateByPartialCompositeKeyWithPaginationMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyWithPaginationCallCount() int { - fake.getStateByPartialCompositeKeyWithPaginationMutex.RLock() - defer fake.getStateByPartialCompositeKeyWithPaginationMutex.RUnlock() - return len(fake.getStateByPartialCompositeKeyWithPaginationArgsForCall) -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyWithPaginationCalls(stub func(string, []string, int32, string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error)) { - fake.getStateByPartialCompositeKeyWithPaginationMutex.Lock() - defer fake.getStateByPartialCompositeKeyWithPaginationMutex.Unlock() - fake.GetStateByPartialCompositeKeyWithPaginationStub = stub -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyWithPaginationArgsForCall(i int) (string, []string, int32, string) { - fake.getStateByPartialCompositeKeyWithPaginationMutex.RLock() - defer fake.getStateByPartialCompositeKeyWithPaginationMutex.RUnlock() - argsForCall := fake.getStateByPartialCompositeKeyWithPaginationArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyWithPaginationReturns(result1 shim.StateQueryIteratorInterface, result2 *peer.QueryResponseMetadata, result3 error) { - fake.getStateByPartialCompositeKeyWithPaginationMutex.Lock() - defer fake.getStateByPartialCompositeKeyWithPaginationMutex.Unlock() - fake.GetStateByPartialCompositeKeyWithPaginationStub = nil - fake.getStateByPartialCompositeKeyWithPaginationReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) GetStateByPartialCompositeKeyWithPaginationReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 *peer.QueryResponseMetadata, result3 error) { - fake.getStateByPartialCompositeKeyWithPaginationMutex.Lock() - defer fake.getStateByPartialCompositeKeyWithPaginationMutex.Unlock() - fake.GetStateByPartialCompositeKeyWithPaginationStub = nil - if fake.getStateByPartialCompositeKeyWithPaginationReturnsOnCall == nil { - fake.getStateByPartialCompositeKeyWithPaginationReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }) - } - fake.getStateByPartialCompositeKeyWithPaginationReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) GetStateByRange(arg1 string, arg2 string) (shim.StateQueryIteratorInterface, error) { - fake.getStateByRangeMutex.Lock() - ret, specificReturn := fake.getStateByRangeReturnsOnCall[len(fake.getStateByRangeArgsForCall)] - fake.getStateByRangeArgsForCall = append(fake.getStateByRangeArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.GetStateByRangeStub - fakeReturns := fake.getStateByRangeReturns - fake.recordInvocation("GetStateByRange", []interface{}{arg1, arg2}) - fake.getStateByRangeMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetStateByRangeCallCount() int { - fake.getStateByRangeMutex.RLock() - defer fake.getStateByRangeMutex.RUnlock() - return len(fake.getStateByRangeArgsForCall) -} - -func (fake *ChaincodeStub) GetStateByRangeCalls(stub func(string, string) (shim.StateQueryIteratorInterface, error)) { - fake.getStateByRangeMutex.Lock() - defer fake.getStateByRangeMutex.Unlock() - fake.GetStateByRangeStub = stub -} - -func (fake *ChaincodeStub) GetStateByRangeArgsForCall(i int) (string, string) { - fake.getStateByRangeMutex.RLock() - defer fake.getStateByRangeMutex.RUnlock() - argsForCall := fake.getStateByRangeArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) GetStateByRangeReturns(result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getStateByRangeMutex.Lock() - defer fake.getStateByRangeMutex.Unlock() - fake.GetStateByRangeStub = nil - fake.getStateByRangeReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateByRangeReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 error) { - fake.getStateByRangeMutex.Lock() - defer fake.getStateByRangeMutex.Unlock() - fake.GetStateByRangeStub = nil - if fake.getStateByRangeReturnsOnCall == nil { - fake.getStateByRangeReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 error - }) - } - fake.getStateByRangeReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateByRangeWithPagination(arg1 string, arg2 string, arg3 int32, arg4 string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error) { - fake.getStateByRangeWithPaginationMutex.Lock() - ret, specificReturn := fake.getStateByRangeWithPaginationReturnsOnCall[len(fake.getStateByRangeWithPaginationArgsForCall)] - fake.getStateByRangeWithPaginationArgsForCall = append(fake.getStateByRangeWithPaginationArgsForCall, struct { - arg1 string - arg2 string - arg3 int32 - arg4 string - }{arg1, arg2, arg3, arg4}) - stub := fake.GetStateByRangeWithPaginationStub - fakeReturns := fake.getStateByRangeWithPaginationReturns - fake.recordInvocation("GetStateByRangeWithPagination", []interface{}{arg1, arg2, arg3, arg4}) - fake.getStateByRangeWithPaginationMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *ChaincodeStub) GetStateByRangeWithPaginationCallCount() int { - fake.getStateByRangeWithPaginationMutex.RLock() - defer fake.getStateByRangeWithPaginationMutex.RUnlock() - return len(fake.getStateByRangeWithPaginationArgsForCall) -} - -func (fake *ChaincodeStub) GetStateByRangeWithPaginationCalls(stub func(string, string, int32, string) (shim.StateQueryIteratorInterface, *peer.QueryResponseMetadata, error)) { - fake.getStateByRangeWithPaginationMutex.Lock() - defer fake.getStateByRangeWithPaginationMutex.Unlock() - fake.GetStateByRangeWithPaginationStub = stub -} - -func (fake *ChaincodeStub) GetStateByRangeWithPaginationArgsForCall(i int) (string, string, int32, string) { - fake.getStateByRangeWithPaginationMutex.RLock() - defer fake.getStateByRangeWithPaginationMutex.RUnlock() - argsForCall := fake.getStateByRangeWithPaginationArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *ChaincodeStub) GetStateByRangeWithPaginationReturns(result1 shim.StateQueryIteratorInterface, result2 *peer.QueryResponseMetadata, result3 error) { - fake.getStateByRangeWithPaginationMutex.Lock() - defer fake.getStateByRangeWithPaginationMutex.Unlock() - fake.GetStateByRangeWithPaginationStub = nil - fake.getStateByRangeWithPaginationReturns = struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) GetStateByRangeWithPaginationReturnsOnCall(i int, result1 shim.StateQueryIteratorInterface, result2 *peer.QueryResponseMetadata, result3 error) { - fake.getStateByRangeWithPaginationMutex.Lock() - defer fake.getStateByRangeWithPaginationMutex.Unlock() - fake.GetStateByRangeWithPaginationStub = nil - if fake.getStateByRangeWithPaginationReturnsOnCall == nil { - fake.getStateByRangeWithPaginationReturnsOnCall = make(map[int]struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }) - } - fake.getStateByRangeWithPaginationReturnsOnCall[i] = struct { - result1 shim.StateQueryIteratorInterface - result2 *peer.QueryResponseMetadata - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) GetStateValidationParameter(arg1 string) ([]byte, error) { - fake.getStateValidationParameterMutex.Lock() - ret, specificReturn := fake.getStateValidationParameterReturnsOnCall[len(fake.getStateValidationParameterArgsForCall)] - fake.getStateValidationParameterArgsForCall = append(fake.getStateValidationParameterArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.GetStateValidationParameterStub - fakeReturns := fake.getStateValidationParameterReturns - fake.recordInvocation("GetStateValidationParameter", []interface{}{arg1}) - fake.getStateValidationParameterMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetStateValidationParameterCallCount() int { - fake.getStateValidationParameterMutex.RLock() - defer fake.getStateValidationParameterMutex.RUnlock() - return len(fake.getStateValidationParameterArgsForCall) -} - -func (fake *ChaincodeStub) GetStateValidationParameterCalls(stub func(string) ([]byte, error)) { - fake.getStateValidationParameterMutex.Lock() - defer fake.getStateValidationParameterMutex.Unlock() - fake.GetStateValidationParameterStub = stub -} - -func (fake *ChaincodeStub) GetStateValidationParameterArgsForCall(i int) string { - fake.getStateValidationParameterMutex.RLock() - defer fake.getStateValidationParameterMutex.RUnlock() - argsForCall := fake.getStateValidationParameterArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ChaincodeStub) GetStateValidationParameterReturns(result1 []byte, result2 error) { - fake.getStateValidationParameterMutex.Lock() - defer fake.getStateValidationParameterMutex.Unlock() - fake.GetStateValidationParameterStub = nil - fake.getStateValidationParameterReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStateValidationParameterReturnsOnCall(i int, result1 []byte, result2 error) { - fake.getStateValidationParameterMutex.Lock() - defer fake.getStateValidationParameterMutex.Unlock() - fake.GetStateValidationParameterStub = nil - if fake.getStateValidationParameterReturnsOnCall == nil { - fake.getStateValidationParameterReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.getStateValidationParameterReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetStringArgs() []string { - fake.getStringArgsMutex.Lock() - ret, specificReturn := fake.getStringArgsReturnsOnCall[len(fake.getStringArgsArgsForCall)] - fake.getStringArgsArgsForCall = append(fake.getStringArgsArgsForCall, struct { - }{}) - stub := fake.GetStringArgsStub - fakeReturns := fake.getStringArgsReturns - fake.recordInvocation("GetStringArgs", []interface{}{}) - fake.getStringArgsMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) GetStringArgsCallCount() int { - fake.getStringArgsMutex.RLock() - defer fake.getStringArgsMutex.RUnlock() - return len(fake.getStringArgsArgsForCall) -} - -func (fake *ChaincodeStub) GetStringArgsCalls(stub func() []string) { - fake.getStringArgsMutex.Lock() - defer fake.getStringArgsMutex.Unlock() - fake.GetStringArgsStub = stub -} - -func (fake *ChaincodeStub) GetStringArgsReturns(result1 []string) { - fake.getStringArgsMutex.Lock() - defer fake.getStringArgsMutex.Unlock() - fake.GetStringArgsStub = nil - fake.getStringArgsReturns = struct { - result1 []string - }{result1} -} - -func (fake *ChaincodeStub) GetStringArgsReturnsOnCall(i int, result1 []string) { - fake.getStringArgsMutex.Lock() - defer fake.getStringArgsMutex.Unlock() - fake.GetStringArgsStub = nil - if fake.getStringArgsReturnsOnCall == nil { - fake.getStringArgsReturnsOnCall = make(map[int]struct { - result1 []string - }) - } - fake.getStringArgsReturnsOnCall[i] = struct { - result1 []string - }{result1} -} - -func (fake *ChaincodeStub) GetTransient() (map[string][]byte, error) { - fake.getTransientMutex.Lock() - ret, specificReturn := fake.getTransientReturnsOnCall[len(fake.getTransientArgsForCall)] - fake.getTransientArgsForCall = append(fake.getTransientArgsForCall, struct { - }{}) - stub := fake.GetTransientStub - fakeReturns := fake.getTransientReturns - fake.recordInvocation("GetTransient", []interface{}{}) - fake.getTransientMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetTransientCallCount() int { - fake.getTransientMutex.RLock() - defer fake.getTransientMutex.RUnlock() - return len(fake.getTransientArgsForCall) -} - -func (fake *ChaincodeStub) GetTransientCalls(stub func() (map[string][]byte, error)) { - fake.getTransientMutex.Lock() - defer fake.getTransientMutex.Unlock() - fake.GetTransientStub = stub -} - -func (fake *ChaincodeStub) GetTransientReturns(result1 map[string][]byte, result2 error) { - fake.getTransientMutex.Lock() - defer fake.getTransientMutex.Unlock() - fake.GetTransientStub = nil - fake.getTransientReturns = struct { - result1 map[string][]byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetTransientReturnsOnCall(i int, result1 map[string][]byte, result2 error) { - fake.getTransientMutex.Lock() - defer fake.getTransientMutex.Unlock() - fake.GetTransientStub = nil - if fake.getTransientReturnsOnCall == nil { - fake.getTransientReturnsOnCall = make(map[int]struct { - result1 map[string][]byte - result2 error - }) - } - fake.getTransientReturnsOnCall[i] = struct { - result1 map[string][]byte - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetTxID() string { - fake.getTxIDMutex.Lock() - ret, specificReturn := fake.getTxIDReturnsOnCall[len(fake.getTxIDArgsForCall)] - fake.getTxIDArgsForCall = append(fake.getTxIDArgsForCall, struct { - }{}) - stub := fake.GetTxIDStub - fakeReturns := fake.getTxIDReturns - fake.recordInvocation("GetTxID", []interface{}{}) - fake.getTxIDMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) GetTxIDCallCount() int { - fake.getTxIDMutex.RLock() - defer fake.getTxIDMutex.RUnlock() - return len(fake.getTxIDArgsForCall) -} - -func (fake *ChaincodeStub) GetTxIDCalls(stub func() string) { - fake.getTxIDMutex.Lock() - defer fake.getTxIDMutex.Unlock() - fake.GetTxIDStub = stub -} - -func (fake *ChaincodeStub) GetTxIDReturns(result1 string) { - fake.getTxIDMutex.Lock() - defer fake.getTxIDMutex.Unlock() - fake.GetTxIDStub = nil - fake.getTxIDReturns = struct { - result1 string - }{result1} -} - -func (fake *ChaincodeStub) GetTxIDReturnsOnCall(i int, result1 string) { - fake.getTxIDMutex.Lock() - defer fake.getTxIDMutex.Unlock() - fake.GetTxIDStub = nil - if fake.getTxIDReturnsOnCall == nil { - fake.getTxIDReturnsOnCall = make(map[int]struct { - result1 string - }) - } - fake.getTxIDReturnsOnCall[i] = struct { - result1 string - }{result1} -} - -func (fake *ChaincodeStub) GetTxTimestamp() (*timestamppb.Timestamp, error) { - fake.getTxTimestampMutex.Lock() - ret, specificReturn := fake.getTxTimestampReturnsOnCall[len(fake.getTxTimestampArgsForCall)] - fake.getTxTimestampArgsForCall = append(fake.getTxTimestampArgsForCall, struct { - }{}) - stub := fake.GetTxTimestampStub - fakeReturns := fake.getTxTimestampReturns - fake.recordInvocation("GetTxTimestamp", []interface{}{}) - fake.getTxTimestampMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ChaincodeStub) GetTxTimestampCallCount() int { - fake.getTxTimestampMutex.RLock() - defer fake.getTxTimestampMutex.RUnlock() - return len(fake.getTxTimestampArgsForCall) -} - -func (fake *ChaincodeStub) GetTxTimestampCalls(stub func() (*timestamppb.Timestamp, error)) { - fake.getTxTimestampMutex.Lock() - defer fake.getTxTimestampMutex.Unlock() - fake.GetTxTimestampStub = stub -} - -func (fake *ChaincodeStub) GetTxTimestampReturns(result1 *timestamppb.Timestamp, result2 error) { - fake.getTxTimestampMutex.Lock() - defer fake.getTxTimestampMutex.Unlock() - fake.GetTxTimestampStub = nil - fake.getTxTimestampReturns = struct { - result1 *timestamppb.Timestamp - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) GetTxTimestampReturnsOnCall(i int, result1 *timestamppb.Timestamp, result2 error) { - fake.getTxTimestampMutex.Lock() - defer fake.getTxTimestampMutex.Unlock() - fake.GetTxTimestampStub = nil - if fake.getTxTimestampReturnsOnCall == nil { - fake.getTxTimestampReturnsOnCall = make(map[int]struct { - result1 *timestamppb.Timestamp - result2 error - }) - } - fake.getTxTimestampReturnsOnCall[i] = struct { - result1 *timestamppb.Timestamp - result2 error - }{result1, result2} -} - -func (fake *ChaincodeStub) InvokeChaincode(arg1 string, arg2 [][]byte, arg3 string) *peer.Response { - var arg2Copy [][]byte - if arg2 != nil { - arg2Copy = make([][]byte, len(arg2)) - copy(arg2Copy, arg2) - } - fake.invokeChaincodeMutex.Lock() - ret, specificReturn := fake.invokeChaincodeReturnsOnCall[len(fake.invokeChaincodeArgsForCall)] - fake.invokeChaincodeArgsForCall = append(fake.invokeChaincodeArgsForCall, struct { - arg1 string - arg2 [][]byte - arg3 string - }{arg1, arg2Copy, arg3}) - stub := fake.InvokeChaincodeStub - fakeReturns := fake.invokeChaincodeReturns - fake.recordInvocation("InvokeChaincode", []interface{}{arg1, arg2Copy, arg3}) - fake.invokeChaincodeMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) InvokeChaincodeCallCount() int { - fake.invokeChaincodeMutex.RLock() - defer fake.invokeChaincodeMutex.RUnlock() - return len(fake.invokeChaincodeArgsForCall) -} - -func (fake *ChaincodeStub) InvokeChaincodeCalls(stub func(string, [][]byte, string) *peer.Response) { - fake.invokeChaincodeMutex.Lock() - defer fake.invokeChaincodeMutex.Unlock() - fake.InvokeChaincodeStub = stub -} - -func (fake *ChaincodeStub) InvokeChaincodeArgsForCall(i int) (string, [][]byte, string) { - fake.invokeChaincodeMutex.RLock() - defer fake.invokeChaincodeMutex.RUnlock() - argsForCall := fake.invokeChaincodeArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *ChaincodeStub) InvokeChaincodeReturns(result1 *peer.Response) { - fake.invokeChaincodeMutex.Lock() - defer fake.invokeChaincodeMutex.Unlock() - fake.InvokeChaincodeStub = nil - fake.invokeChaincodeReturns = struct { - result1 *peer.Response - }{result1} -} - -func (fake *ChaincodeStub) InvokeChaincodeReturnsOnCall(i int, result1 *peer.Response) { - fake.invokeChaincodeMutex.Lock() - defer fake.invokeChaincodeMutex.Unlock() - fake.InvokeChaincodeStub = nil - if fake.invokeChaincodeReturnsOnCall == nil { - fake.invokeChaincodeReturnsOnCall = make(map[int]struct { - result1 *peer.Response - }) - } - fake.invokeChaincodeReturnsOnCall[i] = struct { - result1 *peer.Response - }{result1} -} - -func (fake *ChaincodeStub) PurgePrivateData(arg1 string, arg2 string) error { - fake.purgePrivateDataMutex.Lock() - ret, specificReturn := fake.purgePrivateDataReturnsOnCall[len(fake.purgePrivateDataArgsForCall)] - fake.purgePrivateDataArgsForCall = append(fake.purgePrivateDataArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.PurgePrivateDataStub - fakeReturns := fake.purgePrivateDataReturns - fake.recordInvocation("PurgePrivateData", []interface{}{arg1, arg2}) - fake.purgePrivateDataMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) PurgePrivateDataCallCount() int { - fake.purgePrivateDataMutex.RLock() - defer fake.purgePrivateDataMutex.RUnlock() - return len(fake.purgePrivateDataArgsForCall) -} - -func (fake *ChaincodeStub) PurgePrivateDataCalls(stub func(string, string) error) { - fake.purgePrivateDataMutex.Lock() - defer fake.purgePrivateDataMutex.Unlock() - fake.PurgePrivateDataStub = stub -} - -func (fake *ChaincodeStub) PurgePrivateDataArgsForCall(i int) (string, string) { - fake.purgePrivateDataMutex.RLock() - defer fake.purgePrivateDataMutex.RUnlock() - argsForCall := fake.purgePrivateDataArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) PurgePrivateDataReturns(result1 error) { - fake.purgePrivateDataMutex.Lock() - defer fake.purgePrivateDataMutex.Unlock() - fake.PurgePrivateDataStub = nil - fake.purgePrivateDataReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) PurgePrivateDataReturnsOnCall(i int, result1 error) { - fake.purgePrivateDataMutex.Lock() - defer fake.purgePrivateDataMutex.Unlock() - fake.PurgePrivateDataStub = nil - if fake.purgePrivateDataReturnsOnCall == nil { - fake.purgePrivateDataReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.purgePrivateDataReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) PutPrivateData(arg1 string, arg2 string, arg3 []byte) error { - var arg3Copy []byte - if arg3 != nil { - arg3Copy = make([]byte, len(arg3)) - copy(arg3Copy, arg3) - } - fake.putPrivateDataMutex.Lock() - ret, specificReturn := fake.putPrivateDataReturnsOnCall[len(fake.putPrivateDataArgsForCall)] - fake.putPrivateDataArgsForCall = append(fake.putPrivateDataArgsForCall, struct { - arg1 string - arg2 string - arg3 []byte - }{arg1, arg2, arg3Copy}) - stub := fake.PutPrivateDataStub - fakeReturns := fake.putPrivateDataReturns - fake.recordInvocation("PutPrivateData", []interface{}{arg1, arg2, arg3Copy}) - fake.putPrivateDataMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) PutPrivateDataCallCount() int { - fake.putPrivateDataMutex.RLock() - defer fake.putPrivateDataMutex.RUnlock() - return len(fake.putPrivateDataArgsForCall) -} - -func (fake *ChaincodeStub) PutPrivateDataCalls(stub func(string, string, []byte) error) { - fake.putPrivateDataMutex.Lock() - defer fake.putPrivateDataMutex.Unlock() - fake.PutPrivateDataStub = stub -} - -func (fake *ChaincodeStub) PutPrivateDataArgsForCall(i int) (string, string, []byte) { - fake.putPrivateDataMutex.RLock() - defer fake.putPrivateDataMutex.RUnlock() - argsForCall := fake.putPrivateDataArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *ChaincodeStub) PutPrivateDataReturns(result1 error) { - fake.putPrivateDataMutex.Lock() - defer fake.putPrivateDataMutex.Unlock() - fake.PutPrivateDataStub = nil - fake.putPrivateDataReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) PutPrivateDataReturnsOnCall(i int, result1 error) { - fake.putPrivateDataMutex.Lock() - defer fake.putPrivateDataMutex.Unlock() - fake.PutPrivateDataStub = nil - if fake.putPrivateDataReturnsOnCall == nil { - fake.putPrivateDataReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.putPrivateDataReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) PutState(arg1 string, arg2 []byte) error { - var arg2Copy []byte - if arg2 != nil { - arg2Copy = make([]byte, len(arg2)) - copy(arg2Copy, arg2) - } - fake.putStateMutex.Lock() - ret, specificReturn := fake.putStateReturnsOnCall[len(fake.putStateArgsForCall)] - fake.putStateArgsForCall = append(fake.putStateArgsForCall, struct { - arg1 string - arg2 []byte - }{arg1, arg2Copy}) - stub := fake.PutStateStub - fakeReturns := fake.putStateReturns - fake.recordInvocation("PutState", []interface{}{arg1, arg2Copy}) - fake.putStateMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) PutStateCallCount() int { - fake.putStateMutex.RLock() - defer fake.putStateMutex.RUnlock() - return len(fake.putStateArgsForCall) -} - -func (fake *ChaincodeStub) PutStateCalls(stub func(string, []byte) error) { - fake.putStateMutex.Lock() - defer fake.putStateMutex.Unlock() - fake.PutStateStub = stub -} - -func (fake *ChaincodeStub) PutStateArgsForCall(i int) (string, []byte) { - fake.putStateMutex.RLock() - defer fake.putStateMutex.RUnlock() - argsForCall := fake.putStateArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) PutStateReturns(result1 error) { - fake.putStateMutex.Lock() - defer fake.putStateMutex.Unlock() - fake.PutStateStub = nil - fake.putStateReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) PutStateReturnsOnCall(i int, result1 error) { - fake.putStateMutex.Lock() - defer fake.putStateMutex.Unlock() - fake.PutStateStub = nil - if fake.putStateReturnsOnCall == nil { - fake.putStateReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.putStateReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SetEvent(arg1 string, arg2 []byte) error { - var arg2Copy []byte - if arg2 != nil { - arg2Copy = make([]byte, len(arg2)) - copy(arg2Copy, arg2) - } - fake.setEventMutex.Lock() - ret, specificReturn := fake.setEventReturnsOnCall[len(fake.setEventArgsForCall)] - fake.setEventArgsForCall = append(fake.setEventArgsForCall, struct { - arg1 string - arg2 []byte - }{arg1, arg2Copy}) - stub := fake.SetEventStub - fakeReturns := fake.setEventReturns - fake.recordInvocation("SetEvent", []interface{}{arg1, arg2Copy}) - fake.setEventMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) SetEventCallCount() int { - fake.setEventMutex.RLock() - defer fake.setEventMutex.RUnlock() - return len(fake.setEventArgsForCall) -} - -func (fake *ChaincodeStub) SetEventCalls(stub func(string, []byte) error) { - fake.setEventMutex.Lock() - defer fake.setEventMutex.Unlock() - fake.SetEventStub = stub -} - -func (fake *ChaincodeStub) SetEventArgsForCall(i int) (string, []byte) { - fake.setEventMutex.RLock() - defer fake.setEventMutex.RUnlock() - argsForCall := fake.setEventArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) SetEventReturns(result1 error) { - fake.setEventMutex.Lock() - defer fake.setEventMutex.Unlock() - fake.SetEventStub = nil - fake.setEventReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SetEventReturnsOnCall(i int, result1 error) { - fake.setEventMutex.Lock() - defer fake.setEventMutex.Unlock() - fake.SetEventStub = nil - if fake.setEventReturnsOnCall == nil { - fake.setEventReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.setEventReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SetPrivateDataValidationParameter(arg1 string, arg2 string, arg3 []byte) error { - var arg3Copy []byte - if arg3 != nil { - arg3Copy = make([]byte, len(arg3)) - copy(arg3Copy, arg3) - } - fake.setPrivateDataValidationParameterMutex.Lock() - ret, specificReturn := fake.setPrivateDataValidationParameterReturnsOnCall[len(fake.setPrivateDataValidationParameterArgsForCall)] - fake.setPrivateDataValidationParameterArgsForCall = append(fake.setPrivateDataValidationParameterArgsForCall, struct { - arg1 string - arg2 string - arg3 []byte - }{arg1, arg2, arg3Copy}) - stub := fake.SetPrivateDataValidationParameterStub - fakeReturns := fake.setPrivateDataValidationParameterReturns - fake.recordInvocation("SetPrivateDataValidationParameter", []interface{}{arg1, arg2, arg3Copy}) - fake.setPrivateDataValidationParameterMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) SetPrivateDataValidationParameterCallCount() int { - fake.setPrivateDataValidationParameterMutex.RLock() - defer fake.setPrivateDataValidationParameterMutex.RUnlock() - return len(fake.setPrivateDataValidationParameterArgsForCall) -} - -func (fake *ChaincodeStub) SetPrivateDataValidationParameterCalls(stub func(string, string, []byte) error) { - fake.setPrivateDataValidationParameterMutex.Lock() - defer fake.setPrivateDataValidationParameterMutex.Unlock() - fake.SetPrivateDataValidationParameterStub = stub -} - -func (fake *ChaincodeStub) SetPrivateDataValidationParameterArgsForCall(i int) (string, string, []byte) { - fake.setPrivateDataValidationParameterMutex.RLock() - defer fake.setPrivateDataValidationParameterMutex.RUnlock() - argsForCall := fake.setPrivateDataValidationParameterArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *ChaincodeStub) SetPrivateDataValidationParameterReturns(result1 error) { - fake.setPrivateDataValidationParameterMutex.Lock() - defer fake.setPrivateDataValidationParameterMutex.Unlock() - fake.SetPrivateDataValidationParameterStub = nil - fake.setPrivateDataValidationParameterReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SetPrivateDataValidationParameterReturnsOnCall(i int, result1 error) { - fake.setPrivateDataValidationParameterMutex.Lock() - defer fake.setPrivateDataValidationParameterMutex.Unlock() - fake.SetPrivateDataValidationParameterStub = nil - if fake.setPrivateDataValidationParameterReturnsOnCall == nil { - fake.setPrivateDataValidationParameterReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.setPrivateDataValidationParameterReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SetStateValidationParameter(arg1 string, arg2 []byte) error { - var arg2Copy []byte - if arg2 != nil { - arg2Copy = make([]byte, len(arg2)) - copy(arg2Copy, arg2) - } - fake.setStateValidationParameterMutex.Lock() - ret, specificReturn := fake.setStateValidationParameterReturnsOnCall[len(fake.setStateValidationParameterArgsForCall)] - fake.setStateValidationParameterArgsForCall = append(fake.setStateValidationParameterArgsForCall, struct { - arg1 string - arg2 []byte - }{arg1, arg2Copy}) - stub := fake.SetStateValidationParameterStub - fakeReturns := fake.setStateValidationParameterReturns - fake.recordInvocation("SetStateValidationParameter", []interface{}{arg1, arg2Copy}) - fake.setStateValidationParameterMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ChaincodeStub) SetStateValidationParameterCallCount() int { - fake.setStateValidationParameterMutex.RLock() - defer fake.setStateValidationParameterMutex.RUnlock() - return len(fake.setStateValidationParameterArgsForCall) -} - -func (fake *ChaincodeStub) SetStateValidationParameterCalls(stub func(string, []byte) error) { - fake.setStateValidationParameterMutex.Lock() - defer fake.setStateValidationParameterMutex.Unlock() - fake.SetStateValidationParameterStub = stub -} - -func (fake *ChaincodeStub) SetStateValidationParameterArgsForCall(i int) (string, []byte) { - fake.setStateValidationParameterMutex.RLock() - defer fake.setStateValidationParameterMutex.RUnlock() - argsForCall := fake.setStateValidationParameterArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ChaincodeStub) SetStateValidationParameterReturns(result1 error) { - fake.setStateValidationParameterMutex.Lock() - defer fake.setStateValidationParameterMutex.Unlock() - fake.SetStateValidationParameterStub = nil - fake.setStateValidationParameterReturns = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SetStateValidationParameterReturnsOnCall(i int, result1 error) { - fake.setStateValidationParameterMutex.Lock() - defer fake.setStateValidationParameterMutex.Unlock() - fake.SetStateValidationParameterStub = nil - if fake.setStateValidationParameterReturnsOnCall == nil { - fake.setStateValidationParameterReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.setStateValidationParameterReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ChaincodeStub) SplitCompositeKey(arg1 string) (string, []string, error) { - fake.splitCompositeKeyMutex.Lock() - ret, specificReturn := fake.splitCompositeKeyReturnsOnCall[len(fake.splitCompositeKeyArgsForCall)] - fake.splitCompositeKeyArgsForCall = append(fake.splitCompositeKeyArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.SplitCompositeKeyStub - fakeReturns := fake.splitCompositeKeyReturns - fake.recordInvocation("SplitCompositeKey", []interface{}{arg1}) - fake.splitCompositeKeyMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *ChaincodeStub) SplitCompositeKeyCallCount() int { - fake.splitCompositeKeyMutex.RLock() - defer fake.splitCompositeKeyMutex.RUnlock() - return len(fake.splitCompositeKeyArgsForCall) -} - -func (fake *ChaincodeStub) SplitCompositeKeyCalls(stub func(string) (string, []string, error)) { - fake.splitCompositeKeyMutex.Lock() - defer fake.splitCompositeKeyMutex.Unlock() - fake.SplitCompositeKeyStub = stub -} - -func (fake *ChaincodeStub) SplitCompositeKeyArgsForCall(i int) string { - fake.splitCompositeKeyMutex.RLock() - defer fake.splitCompositeKeyMutex.RUnlock() - argsForCall := fake.splitCompositeKeyArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ChaincodeStub) SplitCompositeKeyReturns(result1 string, result2 []string, result3 error) { - fake.splitCompositeKeyMutex.Lock() - defer fake.splitCompositeKeyMutex.Unlock() - fake.SplitCompositeKeyStub = nil - fake.splitCompositeKeyReturns = struct { - result1 string - result2 []string - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) SplitCompositeKeyReturnsOnCall(i int, result1 string, result2 []string, result3 error) { - fake.splitCompositeKeyMutex.Lock() - defer fake.splitCompositeKeyMutex.Unlock() - fake.SplitCompositeKeyStub = nil - if fake.splitCompositeKeyReturnsOnCall == nil { - fake.splitCompositeKeyReturnsOnCall = make(map[int]struct { - result1 string - result2 []string - result3 error - }) - } - fake.splitCompositeKeyReturnsOnCall[i] = struct { - result1 string - result2 []string - result3 error - }{result1, result2, result3} -} - -func (fake *ChaincodeStub) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.createCompositeKeyMutex.RLock() - defer fake.createCompositeKeyMutex.RUnlock() - fake.delPrivateDataMutex.RLock() - defer fake.delPrivateDataMutex.RUnlock() - fake.delStateMutex.RLock() - defer fake.delStateMutex.RUnlock() - fake.getArgsMutex.RLock() - defer fake.getArgsMutex.RUnlock() - fake.getArgsSliceMutex.RLock() - defer fake.getArgsSliceMutex.RUnlock() - fake.getBindingMutex.RLock() - defer fake.getBindingMutex.RUnlock() - fake.getChannelIDMutex.RLock() - defer fake.getChannelIDMutex.RUnlock() - fake.getCreatorMutex.RLock() - defer fake.getCreatorMutex.RUnlock() - fake.getDecorationsMutex.RLock() - defer fake.getDecorationsMutex.RUnlock() - fake.getFunctionAndParametersMutex.RLock() - defer fake.getFunctionAndParametersMutex.RUnlock() - fake.getHistoryForKeyMutex.RLock() - defer fake.getHistoryForKeyMutex.RUnlock() - fake.getPrivateDataMutex.RLock() - defer fake.getPrivateDataMutex.RUnlock() - fake.getPrivateDataByPartialCompositeKeyMutex.RLock() - defer fake.getPrivateDataByPartialCompositeKeyMutex.RUnlock() - fake.getPrivateDataByRangeMutex.RLock() - defer fake.getPrivateDataByRangeMutex.RUnlock() - fake.getPrivateDataHashMutex.RLock() - defer fake.getPrivateDataHashMutex.RUnlock() - fake.getPrivateDataQueryResultMutex.RLock() - defer fake.getPrivateDataQueryResultMutex.RUnlock() - fake.getPrivateDataValidationParameterMutex.RLock() - defer fake.getPrivateDataValidationParameterMutex.RUnlock() - fake.getQueryResultMutex.RLock() - defer fake.getQueryResultMutex.RUnlock() - fake.getQueryResultWithPaginationMutex.RLock() - defer fake.getQueryResultWithPaginationMutex.RUnlock() - fake.getSignedProposalMutex.RLock() - defer fake.getSignedProposalMutex.RUnlock() - fake.getStateMutex.RLock() - defer fake.getStateMutex.RUnlock() - fake.getStateByPartialCompositeKeyMutex.RLock() - defer fake.getStateByPartialCompositeKeyMutex.RUnlock() - fake.getStateByPartialCompositeKeyWithPaginationMutex.RLock() - defer fake.getStateByPartialCompositeKeyWithPaginationMutex.RUnlock() - fake.getStateByRangeMutex.RLock() - defer fake.getStateByRangeMutex.RUnlock() - fake.getStateByRangeWithPaginationMutex.RLock() - defer fake.getStateByRangeWithPaginationMutex.RUnlock() - fake.getStateValidationParameterMutex.RLock() - defer fake.getStateValidationParameterMutex.RUnlock() - fake.getStringArgsMutex.RLock() - defer fake.getStringArgsMutex.RUnlock() - fake.getTransientMutex.RLock() - defer fake.getTransientMutex.RUnlock() - fake.getTxIDMutex.RLock() - defer fake.getTxIDMutex.RUnlock() - fake.getTxTimestampMutex.RLock() - defer fake.getTxTimestampMutex.RUnlock() - fake.invokeChaincodeMutex.RLock() - defer fake.invokeChaincodeMutex.RUnlock() - fake.purgePrivateDataMutex.RLock() - defer fake.purgePrivateDataMutex.RUnlock() - fake.putPrivateDataMutex.RLock() - defer fake.putPrivateDataMutex.RUnlock() - fake.putStateMutex.RLock() - defer fake.putStateMutex.RUnlock() - fake.setEventMutex.RLock() - defer fake.setEventMutex.RUnlock() - fake.setPrivateDataValidationParameterMutex.RLock() - defer fake.setPrivateDataValidationParameterMutex.RUnlock() - fake.setStateValidationParameterMutex.RLock() - defer fake.setStateValidationParameterMutex.RUnlock() - fake.splitCompositeKeyMutex.RLock() - defer fake.splitCompositeKeyMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *ChaincodeStub) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} diff --git a/asset-transfer-private-data/chaincode-go/chaincode/mocks/clientIdentity.go b/asset-transfer-private-data/chaincode-go/chaincode/mocks/clientIdentity.go deleted file mode 100644 index 79bf75dd..00000000 --- a/asset-transfer-private-data/chaincode-go/chaincode/mocks/clientIdentity.go +++ /dev/null @@ -1,404 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package mocks - -import ( - "crypto/x509" - "sync" -) - -type ClientIdentity struct { - AssertAttributeValueStub func(string, string) error - assertAttributeValueMutex sync.RWMutex - assertAttributeValueArgsForCall []struct { - arg1 string - arg2 string - } - assertAttributeValueReturns struct { - result1 error - } - assertAttributeValueReturnsOnCall map[int]struct { - result1 error - } - GetAttributeValueStub func(string) (string, bool, error) - getAttributeValueMutex sync.RWMutex - getAttributeValueArgsForCall []struct { - arg1 string - } - getAttributeValueReturns struct { - result1 string - result2 bool - result3 error - } - getAttributeValueReturnsOnCall map[int]struct { - result1 string - result2 bool - result3 error - } - GetIDStub func() (string, error) - getIDMutex sync.RWMutex - getIDArgsForCall []struct { - } - getIDReturns struct { - result1 string - result2 error - } - getIDReturnsOnCall map[int]struct { - result1 string - result2 error - } - GetMSPIDStub func() (string, error) - getMSPIDMutex sync.RWMutex - getMSPIDArgsForCall []struct { - } - getMSPIDReturns struct { - result1 string - result2 error - } - getMSPIDReturnsOnCall map[int]struct { - result1 string - result2 error - } - GetX509CertificateStub func() (*x509.Certificate, error) - getX509CertificateMutex sync.RWMutex - getX509CertificateArgsForCall []struct { - } - getX509CertificateReturns struct { - result1 *x509.Certificate - result2 error - } - getX509CertificateReturnsOnCall map[int]struct { - result1 *x509.Certificate - result2 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *ClientIdentity) AssertAttributeValue(arg1 string, arg2 string) error { - fake.assertAttributeValueMutex.Lock() - ret, specificReturn := fake.assertAttributeValueReturnsOnCall[len(fake.assertAttributeValueArgsForCall)] - fake.assertAttributeValueArgsForCall = append(fake.assertAttributeValueArgsForCall, struct { - arg1 string - arg2 string - }{arg1, arg2}) - stub := fake.AssertAttributeValueStub - fakeReturns := fake.assertAttributeValueReturns - fake.recordInvocation("AssertAttributeValue", []interface{}{arg1, arg2}) - fake.assertAttributeValueMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *ClientIdentity) AssertAttributeValueCallCount() int { - fake.assertAttributeValueMutex.RLock() - defer fake.assertAttributeValueMutex.RUnlock() - return len(fake.assertAttributeValueArgsForCall) -} - -func (fake *ClientIdentity) AssertAttributeValueCalls(stub func(string, string) error) { - fake.assertAttributeValueMutex.Lock() - defer fake.assertAttributeValueMutex.Unlock() - fake.AssertAttributeValueStub = stub -} - -func (fake *ClientIdentity) AssertAttributeValueArgsForCall(i int) (string, string) { - fake.assertAttributeValueMutex.RLock() - defer fake.assertAttributeValueMutex.RUnlock() - argsForCall := fake.assertAttributeValueArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *ClientIdentity) AssertAttributeValueReturns(result1 error) { - fake.assertAttributeValueMutex.Lock() - defer fake.assertAttributeValueMutex.Unlock() - fake.AssertAttributeValueStub = nil - fake.assertAttributeValueReturns = struct { - result1 error - }{result1} -} - -func (fake *ClientIdentity) AssertAttributeValueReturnsOnCall(i int, result1 error) { - fake.assertAttributeValueMutex.Lock() - defer fake.assertAttributeValueMutex.Unlock() - fake.AssertAttributeValueStub = nil - if fake.assertAttributeValueReturnsOnCall == nil { - fake.assertAttributeValueReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.assertAttributeValueReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *ClientIdentity) GetAttributeValue(arg1 string) (string, bool, error) { - fake.getAttributeValueMutex.Lock() - ret, specificReturn := fake.getAttributeValueReturnsOnCall[len(fake.getAttributeValueArgsForCall)] - fake.getAttributeValueArgsForCall = append(fake.getAttributeValueArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.GetAttributeValueStub - fakeReturns := fake.getAttributeValueReturns - fake.recordInvocation("GetAttributeValue", []interface{}{arg1}) - fake.getAttributeValueMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *ClientIdentity) GetAttributeValueCallCount() int { - fake.getAttributeValueMutex.RLock() - defer fake.getAttributeValueMutex.RUnlock() - return len(fake.getAttributeValueArgsForCall) -} - -func (fake *ClientIdentity) GetAttributeValueCalls(stub func(string) (string, bool, error)) { - fake.getAttributeValueMutex.Lock() - defer fake.getAttributeValueMutex.Unlock() - fake.GetAttributeValueStub = stub -} - -func (fake *ClientIdentity) GetAttributeValueArgsForCall(i int) string { - fake.getAttributeValueMutex.RLock() - defer fake.getAttributeValueMutex.RUnlock() - argsForCall := fake.getAttributeValueArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ClientIdentity) GetAttributeValueReturns(result1 string, result2 bool, result3 error) { - fake.getAttributeValueMutex.Lock() - defer fake.getAttributeValueMutex.Unlock() - fake.GetAttributeValueStub = nil - fake.getAttributeValueReturns = struct { - result1 string - result2 bool - result3 error - }{result1, result2, result3} -} - -func (fake *ClientIdentity) GetAttributeValueReturnsOnCall(i int, result1 string, result2 bool, result3 error) { - fake.getAttributeValueMutex.Lock() - defer fake.getAttributeValueMutex.Unlock() - fake.GetAttributeValueStub = nil - if fake.getAttributeValueReturnsOnCall == nil { - fake.getAttributeValueReturnsOnCall = make(map[int]struct { - result1 string - result2 bool - result3 error - }) - } - fake.getAttributeValueReturnsOnCall[i] = struct { - result1 string - result2 bool - result3 error - }{result1, result2, result3} -} - -func (fake *ClientIdentity) GetID() (string, error) { - fake.getIDMutex.Lock() - ret, specificReturn := fake.getIDReturnsOnCall[len(fake.getIDArgsForCall)] - fake.getIDArgsForCall = append(fake.getIDArgsForCall, struct { - }{}) - stub := fake.GetIDStub - fakeReturns := fake.getIDReturns - fake.recordInvocation("GetID", []interface{}{}) - fake.getIDMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ClientIdentity) GetIDCallCount() int { - fake.getIDMutex.RLock() - defer fake.getIDMutex.RUnlock() - return len(fake.getIDArgsForCall) -} - -func (fake *ClientIdentity) GetIDCalls(stub func() (string, error)) { - fake.getIDMutex.Lock() - defer fake.getIDMutex.Unlock() - fake.GetIDStub = stub -} - -func (fake *ClientIdentity) GetIDReturns(result1 string, result2 error) { - fake.getIDMutex.Lock() - defer fake.getIDMutex.Unlock() - fake.GetIDStub = nil - fake.getIDReturns = struct { - result1 string - result2 error - }{result1, result2} -} - -func (fake *ClientIdentity) GetIDReturnsOnCall(i int, result1 string, result2 error) { - fake.getIDMutex.Lock() - defer fake.getIDMutex.Unlock() - fake.GetIDStub = nil - if fake.getIDReturnsOnCall == nil { - fake.getIDReturnsOnCall = make(map[int]struct { - result1 string - result2 error - }) - } - fake.getIDReturnsOnCall[i] = struct { - result1 string - result2 error - }{result1, result2} -} - -func (fake *ClientIdentity) GetMSPID() (string, error) { - fake.getMSPIDMutex.Lock() - ret, specificReturn := fake.getMSPIDReturnsOnCall[len(fake.getMSPIDArgsForCall)] - fake.getMSPIDArgsForCall = append(fake.getMSPIDArgsForCall, struct { - }{}) - stub := fake.GetMSPIDStub - fakeReturns := fake.getMSPIDReturns - fake.recordInvocation("GetMSPID", []interface{}{}) - fake.getMSPIDMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ClientIdentity) GetMSPIDCallCount() int { - fake.getMSPIDMutex.RLock() - defer fake.getMSPIDMutex.RUnlock() - return len(fake.getMSPIDArgsForCall) -} - -func (fake *ClientIdentity) GetMSPIDCalls(stub func() (string, error)) { - fake.getMSPIDMutex.Lock() - defer fake.getMSPIDMutex.Unlock() - fake.GetMSPIDStub = stub -} - -func (fake *ClientIdentity) GetMSPIDReturns(result1 string, result2 error) { - fake.getMSPIDMutex.Lock() - defer fake.getMSPIDMutex.Unlock() - fake.GetMSPIDStub = nil - fake.getMSPIDReturns = struct { - result1 string - result2 error - }{result1, result2} -} - -func (fake *ClientIdentity) GetMSPIDReturnsOnCall(i int, result1 string, result2 error) { - fake.getMSPIDMutex.Lock() - defer fake.getMSPIDMutex.Unlock() - fake.GetMSPIDStub = nil - if fake.getMSPIDReturnsOnCall == nil { - fake.getMSPIDReturnsOnCall = make(map[int]struct { - result1 string - result2 error - }) - } - fake.getMSPIDReturnsOnCall[i] = struct { - result1 string - result2 error - }{result1, result2} -} - -func (fake *ClientIdentity) GetX509Certificate() (*x509.Certificate, error) { - fake.getX509CertificateMutex.Lock() - ret, specificReturn := fake.getX509CertificateReturnsOnCall[len(fake.getX509CertificateArgsForCall)] - fake.getX509CertificateArgsForCall = append(fake.getX509CertificateArgsForCall, struct { - }{}) - stub := fake.GetX509CertificateStub - fakeReturns := fake.getX509CertificateReturns - fake.recordInvocation("GetX509Certificate", []interface{}{}) - fake.getX509CertificateMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *ClientIdentity) GetX509CertificateCallCount() int { - fake.getX509CertificateMutex.RLock() - defer fake.getX509CertificateMutex.RUnlock() - return len(fake.getX509CertificateArgsForCall) -} - -func (fake *ClientIdentity) GetX509CertificateCalls(stub func() (*x509.Certificate, error)) { - fake.getX509CertificateMutex.Lock() - defer fake.getX509CertificateMutex.Unlock() - fake.GetX509CertificateStub = stub -} - -func (fake *ClientIdentity) GetX509CertificateReturns(result1 *x509.Certificate, result2 error) { - fake.getX509CertificateMutex.Lock() - defer fake.getX509CertificateMutex.Unlock() - fake.GetX509CertificateStub = nil - fake.getX509CertificateReturns = struct { - result1 *x509.Certificate - result2 error - }{result1, result2} -} - -func (fake *ClientIdentity) GetX509CertificateReturnsOnCall(i int, result1 *x509.Certificate, result2 error) { - fake.getX509CertificateMutex.Lock() - defer fake.getX509CertificateMutex.Unlock() - fake.GetX509CertificateStub = nil - if fake.getX509CertificateReturnsOnCall == nil { - fake.getX509CertificateReturnsOnCall = make(map[int]struct { - result1 *x509.Certificate - result2 error - }) - } - fake.getX509CertificateReturnsOnCall[i] = struct { - result1 *x509.Certificate - result2 error - }{result1, result2} -} - -func (fake *ClientIdentity) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.assertAttributeValueMutex.RLock() - defer fake.assertAttributeValueMutex.RUnlock() - fake.getAttributeValueMutex.RLock() - defer fake.getAttributeValueMutex.RUnlock() - fake.getIDMutex.RLock() - defer fake.getIDMutex.RUnlock() - fake.getMSPIDMutex.RLock() - defer fake.getMSPIDMutex.RUnlock() - fake.getX509CertificateMutex.RLock() - defer fake.getX509CertificateMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *ClientIdentity) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} diff --git a/asset-transfer-private-data/chaincode-go/chaincode/mocks/statequeryiterator.go b/asset-transfer-private-data/chaincode-go/chaincode/mocks/statequeryiterator.go deleted file mode 100644 index 76cdcaa1..00000000 --- a/asset-transfer-private-data/chaincode-go/chaincode/mocks/statequeryiterator.go +++ /dev/null @@ -1,235 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package mocks - -import ( - "sync" - - "github.com/hyperledger/fabric-protos-go-apiv2/ledger/queryresult" -) - -type StateQueryIterator struct { - CloseStub func() error - closeMutex sync.RWMutex - closeArgsForCall []struct { - } - closeReturns struct { - result1 error - } - closeReturnsOnCall map[int]struct { - result1 error - } - HasNextStub func() bool - hasNextMutex sync.RWMutex - hasNextArgsForCall []struct { - } - hasNextReturns struct { - result1 bool - } - hasNextReturnsOnCall map[int]struct { - result1 bool - } - NextStub func() (*queryresult.KV, error) - nextMutex sync.RWMutex - nextArgsForCall []struct { - } - nextReturns struct { - result1 *queryresult.KV - result2 error - } - nextReturnsOnCall map[int]struct { - result1 *queryresult.KV - result2 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *StateQueryIterator) Close() error { - fake.closeMutex.Lock() - ret, specificReturn := fake.closeReturnsOnCall[len(fake.closeArgsForCall)] - fake.closeArgsForCall = append(fake.closeArgsForCall, struct { - }{}) - stub := fake.CloseStub - fakeReturns := fake.closeReturns - fake.recordInvocation("Close", []interface{}{}) - fake.closeMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *StateQueryIterator) CloseCallCount() int { - fake.closeMutex.RLock() - defer fake.closeMutex.RUnlock() - return len(fake.closeArgsForCall) -} - -func (fake *StateQueryIterator) CloseCalls(stub func() error) { - fake.closeMutex.Lock() - defer fake.closeMutex.Unlock() - fake.CloseStub = stub -} - -func (fake *StateQueryIterator) CloseReturns(result1 error) { - fake.closeMutex.Lock() - defer fake.closeMutex.Unlock() - fake.CloseStub = nil - fake.closeReturns = struct { - result1 error - }{result1} -} - -func (fake *StateQueryIterator) CloseReturnsOnCall(i int, result1 error) { - fake.closeMutex.Lock() - defer fake.closeMutex.Unlock() - fake.CloseStub = nil - if fake.closeReturnsOnCall == nil { - fake.closeReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.closeReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *StateQueryIterator) HasNext() bool { - fake.hasNextMutex.Lock() - ret, specificReturn := fake.hasNextReturnsOnCall[len(fake.hasNextArgsForCall)] - fake.hasNextArgsForCall = append(fake.hasNextArgsForCall, struct { - }{}) - stub := fake.HasNextStub - fakeReturns := fake.hasNextReturns - fake.recordInvocation("HasNext", []interface{}{}) - fake.hasNextMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *StateQueryIterator) HasNextCallCount() int { - fake.hasNextMutex.RLock() - defer fake.hasNextMutex.RUnlock() - return len(fake.hasNextArgsForCall) -} - -func (fake *StateQueryIterator) HasNextCalls(stub func() bool) { - fake.hasNextMutex.Lock() - defer fake.hasNextMutex.Unlock() - fake.HasNextStub = stub -} - -func (fake *StateQueryIterator) HasNextReturns(result1 bool) { - fake.hasNextMutex.Lock() - defer fake.hasNextMutex.Unlock() - fake.HasNextStub = nil - fake.hasNextReturns = struct { - result1 bool - }{result1} -} - -func (fake *StateQueryIterator) HasNextReturnsOnCall(i int, result1 bool) { - fake.hasNextMutex.Lock() - defer fake.hasNextMutex.Unlock() - fake.HasNextStub = nil - if fake.hasNextReturnsOnCall == nil { - fake.hasNextReturnsOnCall = make(map[int]struct { - result1 bool - }) - } - fake.hasNextReturnsOnCall[i] = struct { - result1 bool - }{result1} -} - -func (fake *StateQueryIterator) Next() (*queryresult.KV, error) { - fake.nextMutex.Lock() - ret, specificReturn := fake.nextReturnsOnCall[len(fake.nextArgsForCall)] - fake.nextArgsForCall = append(fake.nextArgsForCall, struct { - }{}) - stub := fake.NextStub - fakeReturns := fake.nextReturns - fake.recordInvocation("Next", []interface{}{}) - fake.nextMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *StateQueryIterator) NextCallCount() int { - fake.nextMutex.RLock() - defer fake.nextMutex.RUnlock() - return len(fake.nextArgsForCall) -} - -func (fake *StateQueryIterator) NextCalls(stub func() (*queryresult.KV, error)) { - fake.nextMutex.Lock() - defer fake.nextMutex.Unlock() - fake.NextStub = stub -} - -func (fake *StateQueryIterator) NextReturns(result1 *queryresult.KV, result2 error) { - fake.nextMutex.Lock() - defer fake.nextMutex.Unlock() - fake.NextStub = nil - fake.nextReturns = struct { - result1 *queryresult.KV - result2 error - }{result1, result2} -} - -func (fake *StateQueryIterator) NextReturnsOnCall(i int, result1 *queryresult.KV, result2 error) { - fake.nextMutex.Lock() - defer fake.nextMutex.Unlock() - fake.NextStub = nil - if fake.nextReturnsOnCall == nil { - fake.nextReturnsOnCall = make(map[int]struct { - result1 *queryresult.KV - result2 error - }) - } - fake.nextReturnsOnCall[i] = struct { - result1 *queryresult.KV - result2 error - }{result1, result2} -} - -func (fake *StateQueryIterator) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.closeMutex.RLock() - defer fake.closeMutex.RUnlock() - fake.hasNextMutex.RLock() - defer fake.hasNextMutex.RUnlock() - fake.nextMutex.RLock() - defer fake.nextMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *StateQueryIterator) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} diff --git a/asset-transfer-private-data/chaincode-go/chaincode/mocks/transaction.go b/asset-transfer-private-data/chaincode-go/chaincode/mocks/transaction.go deleted file mode 100644 index 5e98d069..00000000 --- a/asset-transfer-private-data/chaincode-go/chaincode/mocks/transaction.go +++ /dev/null @@ -1,166 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package mocks - -import ( - "sync" - - "github.com/hyperledger/fabric-chaincode-go/v2/pkg/cid" - "github.com/hyperledger/fabric-chaincode-go/v2/shim" -) - -type TransactionContext struct { - GetClientIdentityStub func() cid.ClientIdentity - getClientIdentityMutex sync.RWMutex - getClientIdentityArgsForCall []struct { - } - getClientIdentityReturns struct { - result1 cid.ClientIdentity - } - getClientIdentityReturnsOnCall map[int]struct { - result1 cid.ClientIdentity - } - GetStubStub func() shim.ChaincodeStubInterface - getStubMutex sync.RWMutex - getStubArgsForCall []struct { - } - getStubReturns struct { - result1 shim.ChaincodeStubInterface - } - getStubReturnsOnCall map[int]struct { - result1 shim.ChaincodeStubInterface - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *TransactionContext) GetClientIdentity() cid.ClientIdentity { - fake.getClientIdentityMutex.Lock() - ret, specificReturn := fake.getClientIdentityReturnsOnCall[len(fake.getClientIdentityArgsForCall)] - fake.getClientIdentityArgsForCall = append(fake.getClientIdentityArgsForCall, struct { - }{}) - stub := fake.GetClientIdentityStub - fakeReturns := fake.getClientIdentityReturns - fake.recordInvocation("GetClientIdentity", []interface{}{}) - fake.getClientIdentityMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *TransactionContext) GetClientIdentityCallCount() int { - fake.getClientIdentityMutex.RLock() - defer fake.getClientIdentityMutex.RUnlock() - return len(fake.getClientIdentityArgsForCall) -} - -func (fake *TransactionContext) GetClientIdentityCalls(stub func() cid.ClientIdentity) { - fake.getClientIdentityMutex.Lock() - defer fake.getClientIdentityMutex.Unlock() - fake.GetClientIdentityStub = stub -} - -func (fake *TransactionContext) GetClientIdentityReturns(result1 cid.ClientIdentity) { - fake.getClientIdentityMutex.Lock() - defer fake.getClientIdentityMutex.Unlock() - fake.GetClientIdentityStub = nil - fake.getClientIdentityReturns = struct { - result1 cid.ClientIdentity - }{result1} -} - -func (fake *TransactionContext) GetClientIdentityReturnsOnCall(i int, result1 cid.ClientIdentity) { - fake.getClientIdentityMutex.Lock() - defer fake.getClientIdentityMutex.Unlock() - fake.GetClientIdentityStub = nil - if fake.getClientIdentityReturnsOnCall == nil { - fake.getClientIdentityReturnsOnCall = make(map[int]struct { - result1 cid.ClientIdentity - }) - } - fake.getClientIdentityReturnsOnCall[i] = struct { - result1 cid.ClientIdentity - }{result1} -} - -func (fake *TransactionContext) GetStub() shim.ChaincodeStubInterface { - fake.getStubMutex.Lock() - ret, specificReturn := fake.getStubReturnsOnCall[len(fake.getStubArgsForCall)] - fake.getStubArgsForCall = append(fake.getStubArgsForCall, struct { - }{}) - stub := fake.GetStubStub - fakeReturns := fake.getStubReturns - fake.recordInvocation("GetStub", []interface{}{}) - fake.getStubMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *TransactionContext) GetStubCallCount() int { - fake.getStubMutex.RLock() - defer fake.getStubMutex.RUnlock() - return len(fake.getStubArgsForCall) -} - -func (fake *TransactionContext) GetStubCalls(stub func() shim.ChaincodeStubInterface) { - fake.getStubMutex.Lock() - defer fake.getStubMutex.Unlock() - fake.GetStubStub = stub -} - -func (fake *TransactionContext) GetStubReturns(result1 shim.ChaincodeStubInterface) { - fake.getStubMutex.Lock() - defer fake.getStubMutex.Unlock() - fake.GetStubStub = nil - fake.getStubReturns = struct { - result1 shim.ChaincodeStubInterface - }{result1} -} - -func (fake *TransactionContext) GetStubReturnsOnCall(i int, result1 shim.ChaincodeStubInterface) { - fake.getStubMutex.Lock() - defer fake.getStubMutex.Unlock() - fake.GetStubStub = nil - if fake.getStubReturnsOnCall == nil { - fake.getStubReturnsOnCall = make(map[int]struct { - result1 shim.ChaincodeStubInterface - }) - } - fake.getStubReturnsOnCall[i] = struct { - result1 shim.ChaincodeStubInterface - }{result1} -} - -func (fake *TransactionContext) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.getClientIdentityMutex.RLock() - defer fake.getClientIdentityMutex.RUnlock() - fake.getStubMutex.RLock() - defer fake.getStubMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *TransactionContext) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} diff --git a/asset-transfer-private-data/chaincode-go/collections_config.json b/asset-transfer-private-data/chaincode-go/collections_config.json deleted file mode 100644 index 993bbd31..00000000 --- a/asset-transfer-private-data/chaincode-go/collections_config.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "name": "assetCollection", - "policy": "OR('Org1MSP.member', 'Org2MSP.member')", - "requiredPeerCount": 1, - "maxPeerCount": 1, - "blockToLive":1000000, - "memberOnlyRead": true, - "memberOnlyWrite": true, - "endorsementPolicy": { - "signaturePolicy":"OR('Org1MSP.member','Org2MSP.member')" - } -}, - { - "name": "Org1MSPPrivateCollection", - "policy": "OR('Org1MSP.member')", - "requiredPeerCount": 0, - "maxPeerCount": 1, - "blockToLive":3, - "memberOnlyRead": true, - "memberOnlyWrite": false, - "endorsementPolicy": { - "signaturePolicy": "OR('Org1MSP.member')" - } - }, - { - "name": "Org2MSPPrivateCollection", - "policy": "OR('Org2MSP.member')", - "requiredPeerCount": 0, - "maxPeerCount": 1, - "blockToLive":3, - "memberOnlyRead": true, - "memberOnlyWrite": false, - "endorsementPolicy": { - "signaturePolicy": "OR('Org2MSP.member')" - } - } -] diff --git a/asset-transfer-private-data/chaincode-go/go.mod b/asset-transfer-private-data/chaincode-go/go.mod deleted file mode 100644 index 15836147..00000000 --- a/asset-transfer-private-data/chaincode-go/go.mod +++ /dev/null @@ -1,31 +0,0 @@ -module github.com/hyperledger/fabric-samples/asset-transfer-private-data/chaincode-go - -go 1.22.0 - -require ( - github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 - github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 - github.com/stretchr/testify v1.10.0 - google.golang.org/protobuf v1.36.1 -) - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/asset-transfer-private-data/chaincode-go/go.sum b/asset-transfer-private-data/chaincode-go/go.sum deleted file mode 100644 index fa4d3b24..00000000 --- a/asset-transfer-private-data/chaincode-go/go.sum +++ /dev/null @@ -1,61 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 h1:IhkHfrl5X/fVnmB6pWeCYCdIJRi9bxj+WTnVN8DtW3c= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0/go.mod h1:PHHaFffjw7p7n9bmCfcm7RqDqYdivNEsJdiNIKZo5Lk= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 h1:rmUoBmciB0GL/miqcbJmJbgp5QTWoJUrZo+CNxrNLF4= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0/go.mod h1:FeWeO/jwGjiME7ak3GufqKIcwkejtzrDG4QxbfKydWs= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/asset-transfer-private-data/chaincode-go/main.go b/asset-transfer-private-data/chaincode-go/main.go deleted file mode 100644 index 8f4032c7..00000000 --- a/asset-transfer-private-data/chaincode-go/main.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "log" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" - "github.com/hyperledger/fabric-samples/asset-transfer-private-data/chaincode-go/chaincode" -) - -func main() { - assetChaincode, err := contractapi.NewChaincode(&chaincode.SmartContract{}) - if err != nil { - log.Panicf("Error creating asset-transfer-private-data chaincode: %v", err) - } - - if err := assetChaincode.Start(); err != nil { - log.Panicf("Error starting asset-transfer-private-data chaincode: %v", err) - } -} diff --git a/asset-transfer-private-data/chaincode-java/.gitattributes b/asset-transfer-private-data/chaincode-java/.gitattributes deleted file mode 100644 index 00a51aff..00000000 --- a/asset-transfer-private-data/chaincode-java/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# These are explicitly windows files and should use crlf -*.bat text eol=crlf - diff --git a/asset-transfer-private-data/chaincode-java/META-INF/statedb/couchdb/collections/assetCollection/indexes/indexOwner.json b/asset-transfer-private-data/chaincode-java/META-INF/statedb/couchdb/collections/assetCollection/indexes/indexOwner.json deleted file mode 100644 index 2e2a5c6d..00000000 --- a/asset-transfer-private-data/chaincode-java/META-INF/statedb/couchdb/collections/assetCollection/indexes/indexOwner.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "index": { - "fields": [ - "objectType", - "owner" - ] - }, - "ddoc": "indexOwnerDoc", - "name": "indexOwner", - "type": "json" -} diff --git a/asset-transfer-private-data/chaincode-java/build.gradle b/asset-transfer-private-data/chaincode-java/build.gradle deleted file mode 100644 index ec6a602c..00000000 --- a/asset-transfer-private-data/chaincode-java/build.gradle +++ /dev/null @@ -1,79 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -plugins { - id 'com.gradleup.shadow' version '8.3.5' - id 'application' - id 'checkstyle' - id 'jacoco' -} - -group 'org.hyperledger.fabric.samples' -version '1.0-SNAPSHOT' - -dependencies { - - implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.+' - implementation 'org.json:json:+' - - testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2' - testImplementation 'org.assertj:assertj-core:3.25.3' - testImplementation 'org.mockito:mockito-core:5.12.0' -} - -repositories { - mavenCentral() - maven { - url 'https://jitpack.io' - } -} - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(11) - } -} - -application { - mainClass = 'org.hyperledger.fabric.contract.ContractRouter' -} - -checkstyle { - toolVersion '8.21' - configFile file("config/checkstyle/checkstyle.xml") -} - -checkstyleMain { - source ='src/main/java' -} - -checkstyleTest { - source ='src/test/java' -} - -jacocoTestReport { - dependsOn test -} - -test { - useJUnitPlatform() - testLogging { - events "passed", "skipped", "failed" - } -} - -mainClassName = 'org.hyperledger.fabric.contract.ContractRouter' - -shadowJar { - archiveBaseName = 'chaincode' - archiveVersion = '' - archiveClassifier = '' - mergeServiceFiles() - - manifest { - attributes 'Main-Class': 'org.hyperledger.fabric.contract.ContractRouter' - } -} - -installDist.dependsOn check diff --git a/asset-transfer-private-data/chaincode-java/collections_config.json b/asset-transfer-private-data/chaincode-java/collections_config.json deleted file mode 100644 index 6d67f3c3..00000000 --- a/asset-transfer-private-data/chaincode-java/collections_config.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "name": "assetCollection", - "policy": "OR('Org1MSP.member', 'Org2MSP.member')", - "requiredPeerCount": 1, - "maxPeerCount": 1, - "blockToLive":1000000, - "memberOnlyRead": true, - "memberOnlyWrite": true, - "endorsementPolicy": { - "signaturePolicy":"OR('Org1MSP.member','Org2MSP.member')" - } -}, - { - "name": "Org1MSPPrivateCollection", - "policy": "OR('Org1MSP.member')", - "requiredPeerCount": 0, - "maxPeerCount": 1, - "blockToLive":3, - "memberOnlyRead": true, - "memberOnlyWrite": false, - "endorsementPolicy": { - "signaturePolicy": "OR('Org1MSP.member')" - } - }, - { - "name": "Org2MSPPrivateCollection", - "policy": "OR('Org2MSP.member')", - "requiredPeerCount": 0, - "maxPeerCount": 1, - "blockToLive":3, - "memberOnlyRead": true, - "memberOnlyWrite": false, - "endorsementPolicy": { - "signaturePolicy": "OR('Org2MSP.member')" - } - } -] diff --git a/asset-transfer-private-data/chaincode-java/config/checkstyle/checkstyle.xml b/asset-transfer-private-data/chaincode-java/config/checkstyle/checkstyle.xml deleted file mode 100644 index acd5df44..00000000 --- a/asset-transfer-private-data/chaincode-java/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/asset-transfer-private-data/chaincode-java/config/checkstyle/suppressions.xml b/asset-transfer-private-data/chaincode-java/config/checkstyle/suppressions.xml deleted file mode 100644 index 33dda041..00000000 --- a/asset-transfer-private-data/chaincode-java/config/checkstyle/suppressions.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/asset-transfer-private-data/chaincode-java/gradle/wrapper/gradle-wrapper.jar b/asset-transfer-private-data/chaincode-java/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index d64cd491..00000000 Binary files a/asset-transfer-private-data/chaincode-java/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/asset-transfer-private-data/chaincode-java/gradle/wrapper/gradle-wrapper.properties b/asset-transfer-private-data/chaincode-java/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e2847c82..00000000 --- a/asset-transfer-private-data/chaincode-java/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/asset-transfer-private-data/chaincode-java/gradlew b/asset-transfer-private-data/chaincode-java/gradlew deleted file mode 100755 index 1aa94a42..00000000 --- a/asset-transfer-private-data/chaincode-java/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/asset-transfer-private-data/chaincode-java/gradlew.bat b/asset-transfer-private-data/chaincode-java/gradlew.bat deleted file mode 100644 index 25da30db..00000000 --- a/asset-transfer-private-data/chaincode-java/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/asset-transfer-private-data/chaincode-java/settings.gradle b/asset-transfer-private-data/chaincode-java/settings.gradle deleted file mode 100644 index 59cbbbca..00000000 --- a/asset-transfer-private-data/chaincode-java/settings.gradle +++ /dev/null @@ -1,5 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -rootProject.name = 'private' diff --git a/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/Asset.java b/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/Asset.java deleted file mode 100644 index 11b29101..00000000 --- a/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/Asset.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.privatedata; - -import java.util.Objects; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.hyperledger.fabric.contract.annotation.DataType; -import org.hyperledger.fabric.contract.annotation.Property; - -import org.hyperledger.fabric.shim.ChaincodeException; -import org.json.JSONObject; - -@DataType() -public final class Asset { - - @Property() - private final String assetID; - - @Property() - private final String objectType; - - @Property() - private final String color; - - @Property() - private final int size; - - @Property() - private String owner; - - public String getAssetID() { - return assetID; - } - - public String getColor() { - return color; - } - - public int getSize() { - return size; - } - - public String getOwner() { - return owner; - } - - public String getObjectType() { - return objectType; - } - - public void setOwner(final String newowner) { - owner = newowner; - } - - public Asset(final String type, - final String assetID, final String color, - final int size, final String owner) { - this.objectType = type; - this.assetID = assetID; - this.color = color; - this.size = size; - this.owner = owner; - } - - public byte[] serialize() { - String jsonStr = new JSONObject(this).toString(); - return jsonStr.getBytes(UTF_8); - } - - public static Asset deserialize(final byte[] assetJSON) { - return deserialize(new String(assetJSON, UTF_8)); - } - - public static Asset deserialize(final String assetJSON) { - try { - JSONObject json = new JSONObject(assetJSON); - final String id = json.getString("assetID"); - final String type = json.getString("objectType"); - final String color = json.getString("color"); - final String owner = json.getString("owner"); - final int size = json.getInt("size"); - return new Asset(type, id, color, size, owner); - } catch (Exception e) { - throw new ChaincodeException("Deserialize error: " + e.getMessage(), "DATA_ERROR"); - } - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - - Asset other = (Asset) obj; - - return Objects.deepEquals( - new String[]{getAssetID(), getColor(), getOwner()}, - new String[]{other.getAssetID(), other.getColor(), other.getOwner()}) - && - Objects.deepEquals( - new int[]{getSize()}, - new int[]{other.getSize()}); - } - - @Override - public int hashCode() { - return Objects.hash(getObjectType(), getAssetID(), getColor(), getSize(), getOwner()); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()) - + " [assetID=" + assetID + ", type=" + objectType + ", color=" - + color + ", size=" + size + ", owner=" + owner + "]"; - } - - -} diff --git a/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetPrivateDetails.java b/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetPrivateDetails.java deleted file mode 100644 index da1c6e24..00000000 --- a/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetPrivateDetails.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.hyperledger.fabric.samples.privatedata; - -import org.hyperledger.fabric.contract.annotation.DataType; -import org.hyperledger.fabric.contract.annotation.Property; - -import org.hyperledger.fabric.shim.ChaincodeException; -import org.json.JSONObject; - -import static java.nio.charset.StandardCharsets.UTF_8; - -@DataType() -public final class AssetPrivateDetails { - - @Property() - private final String assetID; - - @Property() - private int appraisedValue; - - public String getAssetID() { - return assetID; - } - - public int getAppraisedValue() { - return appraisedValue; - } - - public AssetPrivateDetails(final String assetID, - final int appraisedValue) { - this.assetID = assetID; - this.appraisedValue = appraisedValue; - } - - public byte[] serialize() { - String jsonStr = new JSONObject(this).toString(); - return jsonStr.getBytes(UTF_8); - } - - public static AssetPrivateDetails deserialize(final byte[] assetJSON) { - try { - JSONObject json = new JSONObject(new String(assetJSON, UTF_8)); - final String id = json.getString("assetID"); - final int appraisedValue = json.getInt("appraisedValue"); - return new AssetPrivateDetails(id, appraisedValue); - } catch (Exception e) { - throw new ChaincodeException("Deserialize error: " + e.getMessage(), "DATA_ERROR"); - } - } - - -} diff --git a/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetTransfer.java b/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetTransfer.java deleted file mode 100644 index 3bc17862..00000000 --- a/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/AssetTransfer.java +++ /dev/null @@ -1,643 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.privatedata; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.contract.ContractInterface; -import org.hyperledger.fabric.contract.annotation.Contact; -import org.hyperledger.fabric.contract.annotation.Contract; -import org.hyperledger.fabric.contract.annotation.Default; -import org.hyperledger.fabric.contract.annotation.Info; -import org.hyperledger.fabric.contract.annotation.License; -import org.hyperledger.fabric.contract.annotation.Transaction; -import org.hyperledger.fabric.shim.ChaincodeException; -import org.hyperledger.fabric.shim.ChaincodeStub; -import org.hyperledger.fabric.shim.ledger.CompositeKey; - -import org.hyperledger.fabric.shim.ledger.KeyValue; -import org.hyperledger.fabric.shim.ledger.QueryResultsIterator; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -/** - * Main Chaincode class. A ContractInterface gets converted to Chaincode internally. - * @see org.hyperledger.fabric.shim.Chaincode - * - * Each chaincode transaction function must take, Context as first parameter. - * Unless specified otherwise via annotation (@Contract or @Transaction), the contract name - * is the class name (without package) - * and the transaction name is the method name. - * - * To create fabric test-network - * cd fabric-samples/test-network - * ./network.sh up createChannel -ca -s couchdb - * To deploy this chaincode to test-network, use the collection config as described in - * See - * Change both -ccs sequence & -ccv version args for iterative deployment - * ./network.sh deployCC -ccn private -ccp ../asset-transfer-private-data/chaincode-java/ -ccl java -ccep "OR('Org1MSP.peer','Org2MSP.peer')" -cccg ../asset-transfer-private-data/chaincode-go/collections_config.json -ccs 1 -ccv 1 - */ -@Contract( - name = "private", - info = @Info( - title = "Asset Transfer Private Data", - description = "The hyperlegendary asset transfer private data", - version = "0.0.1-SNAPSHOT", - license = @License( - name = "Apache 2.0 License", - url = "http://www.apache.org/licenses/LICENSE-2.0.html"), - contact = @Contact( - email = "a.transfer@example.com", - name = "Private Transfer", - url = "https://hyperledger.example.com"))) -@Default -public final class AssetTransfer implements ContractInterface { - - static final String ASSET_COLLECTION_NAME = "assetCollection"; - static final String AGREEMENT_KEYPREFIX = "transferAgreement"; - - private enum AssetTransferErrors { - INCOMPLETE_INPUT, - INVALID_ACCESS, - ASSET_NOT_FOUND, - ASSET_ALREADY_EXISTS - } - - /** - * Retrieves the asset public details with the specified ID from the AssetCollection. - * - * @param ctx the transaction context - * @param assetID the ID of the asset - * @return the asset found on the ledger if there was one - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public Asset ReadAsset(final Context ctx, final String assetID) { - ChaincodeStub stub = ctx.getStub(); - System.out.printf("ReadAsset: collection %s, ID %s\n", ASSET_COLLECTION_NAME, assetID); - byte[] assetJSON = stub.getPrivateData(ASSET_COLLECTION_NAME, assetID); - - if (assetJSON == null || assetJSON.length == 0) { - System.out.printf("Asset not found: ID %s\n", assetID); - return null; - } - - Asset asset = Asset.deserialize(assetJSON); - return asset; - } - - /** - * Retrieves the asset's AssetPrivateDetails details with the specified ID from the Collection. - * - * @param ctx the transaction context - * @param collection the org's collection containing asset private details - * @param assetID the ID of the asset - * @return the AssetPrivateDetails from the collection, if there was one - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public AssetPrivateDetails ReadAssetPrivateDetails(final Context ctx, final String collection, final String assetID) { - ChaincodeStub stub = ctx.getStub(); - System.out.printf("ReadAssetPrivateDetails: collection %s, ID %s\n", collection, assetID); - byte[] assetPrvJSON = stub.getPrivateData(collection, assetID); - - if (assetPrvJSON == null || assetPrvJSON.length == 0) { - String errorMessage = String.format("AssetPrivateDetails %s does not exist in collection %s", assetID, collection); - System.out.println(errorMessage); - return null; - } - - AssetPrivateDetails assetpd = AssetPrivateDetails.deserialize(assetPrvJSON); - return assetpd; - } - - /** - * ReadTransferAgreement gets the buyer's identity from the transfer agreement from collection - * - * @param ctx the transaction context - * @param assetID the ID of the asset - * @return the AssetPrivateDetails from the collection, if there was one - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public TransferAgreement ReadTransferAgreement(final Context ctx, final String assetID) { - ChaincodeStub stub = ctx.getStub(); - - CompositeKey aggKey = stub.createCompositeKey(AGREEMENT_KEYPREFIX, assetID); - System.out.printf("ReadTransferAgreement Get: collection %s, ID %s, Key %s\n", ASSET_COLLECTION_NAME, assetID, aggKey); - byte[] buyerIdentity = stub.getPrivateData(ASSET_COLLECTION_NAME, aggKey.toString()); - - if (buyerIdentity == null || buyerIdentity.length == 0) { - String errorMessage = String.format("BuyerIdentity for asset %s does not exist in TransferAgreement ", assetID); - System.out.println(errorMessage); - return null; - } - - return new TransferAgreement(assetID, new String(buyerIdentity, UTF_8)); - } - - /** - * GetAssetByRange performs a range query based on the start and end keys provided. Range - * queries can be used to read data from private data collections, but can not be used in - * a transaction that also writes to private collection, since transaction may not get endorsed - * on some peers that do not have the collection. - * - * @param ctx the transaction context - * @param startKey for ID range of the asset - * @param endKey for ID range of the asset - * @return the asset found on the ledger if there was one - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public Asset[] GetAssetByRange(final Context ctx, final String startKey, final String endKey) throws Exception { - ChaincodeStub stub = ctx.getStub(); - System.out.printf("GetAssetByRange: start %s, end %s\n", startKey, endKey); - - List queryResults = new ArrayList<>(); - // retrieve asset with keys between startKey (inclusive) and endKey(exclusive) in lexical order. - try (QueryResultsIterator results = stub.getPrivateDataByRange(ASSET_COLLECTION_NAME, startKey, endKey)) { - for (KeyValue result : results) { - if (result.getStringValue() == null || result.getStringValue().length() == 0) { - System.err.printf("Invalid Asset json: %s\n", result.getStringValue()); - continue; - } - Asset asset = Asset.deserialize(result.getStringValue()); - queryResults.add(asset); - System.out.println("QueryResult: " + asset.toString()); - } - } - return queryResults.toArray(new Asset[0]); - } - - // =======Rich queries ========================================================================= - // Two examples of rich queries are provided below (parameterized query and ad hoc query). - // Rich queries pass a query string to the state database. - // Rich queries are only supported by state database implementations - // that support rich query (e.g. CouchDB). - // The query string is in the syntax of the underlying state database. - // With rich queries there is no guarantee that the result set hasn't changed between - // endorsement time and commit time, aka 'phantom reads'. - // Therefore, rich queries should not be used in update transactions, unless the - // application handles the possibility of result set changes between endorsement and commit time. - // Rich queries can be used for point-in-time queries against a peer. - // ============================================================================================ - - /** - * QueryAssetByOwner queries for assets based on assetType, owner. - * This is an example of a parameterized query where the query logic is baked into the chaincode, - * and accepting a single query parameter (owner). - * - * @param ctx the transaction context - * @param assetType type to query for - * @param owner asset owner to query for - * @return the asset found on the ledger if there was one - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public Asset[] QueryAssetByOwner(final Context ctx, final String assetType, final String owner) throws Exception { - String queryString = String.format("{\"selector\":{\"objectType\":\"%s\",\"owner\":\"%s\"}}", assetType, owner); - return getQueryResult(ctx, queryString); - } - - /** - * QueryAssets uses a query string to perform a query for assets. - * Query string matching state database syntax is passed in and executed as is. - * Supports ad hoc queries that can be defined at runtime by the client. - * - * @param ctx the transaction context - * @param queryString query string matching state database syntax - * @return the asset found on the ledger if there was one - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public Asset[] QueryAssets(final Context ctx, final String queryString) throws Exception { - return getQueryResult(ctx, queryString); - } - - private Asset[] getQueryResult(final Context ctx, final String queryString) throws Exception { - ChaincodeStub stub = ctx.getStub(); - System.out.printf("QueryAssets: %s\n", queryString); - - List queryResults = new ArrayList(); - // retrieve asset with keys between startKey (inclusive) and endKey(exclusive) in lexical order. - try (QueryResultsIterator results = stub.getPrivateDataQueryResult(ASSET_COLLECTION_NAME, queryString)) { - for (KeyValue result : results) { - if (result.getStringValue() == null || result.getStringValue().length() == 0) { - System.err.printf("Invalid Asset json: %s\n", result.getStringValue()); - continue; - } - Asset asset = Asset.deserialize(result.getStringValue()); - queryResults.add(asset); - System.out.println("QueryResult: " + asset.toString()); - } - } - return queryResults.toArray(new Asset[0]); - } - - - /** - * Creates a new asset on the ledger from asset properties passed in as transient map. - * Asset owner will be inferred from the ClientId via stub api - * - * @param ctx the transaction context - * Transient map with asset_properties key with asset json as value - * @return the created asset - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public Asset CreateAsset(final Context ctx) { - ChaincodeStub stub = ctx.getStub(); - Map transientMap = ctx.getStub().getTransient(); - if (!transientMap.containsKey("asset_properties")) { - String errorMessage = String.format("CreateAsset call must specify asset_properties in Transient map input"); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - byte[] transientAssetJSON = transientMap.get("asset_properties"); - final String assetID; - final String type; - final String color; - int appraisedValue = 0; - int size = 0; - try { - JSONObject json = new JSONObject(new String(transientAssetJSON, UTF_8)); - Map tMap = json.toMap(); - - type = (String) tMap.get("objectType"); - assetID = (String) tMap.get("assetID"); - color = (String) tMap.get("color"); - if (tMap.containsKey("size")) { - size = (Integer) tMap.get("size"); - } - if (tMap.containsKey("appraisedValue")) { - appraisedValue = (Integer) tMap.get("appraisedValue"); - } - } catch (Exception err) { - String errorMessage = String.format("TransientMap deserialized error: %s ", err); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - //input validations - String errorMessage = null; - if (assetID.equals("")) { - errorMessage = String.format("Empty input in Transient map: assetID"); - } - if (type.equals("")) { - errorMessage = String.format("Empty input in Transient map: objectType"); - } - if (color.equals("")) { - errorMessage = String.format("Empty input in Transient map: color"); - } - if (size <= 0) { - errorMessage = String.format("Empty input in Transient map: size"); - } - if (appraisedValue <= 0) { - errorMessage = String.format("Empty input in Transient map: appraisedValue"); - } - - if (errorMessage != null) { - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - Asset asset = new Asset(type, assetID, color, size, ""); - // Check if asset already exists - byte[] assetJSON = ctx.getStub().getPrivateData(ASSET_COLLECTION_NAME, assetID); - if (assetJSON != null && assetJSON.length > 0) { - errorMessage = String.format("Asset %s already exists", assetID); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_ALREADY_EXISTS.toString()); - } - - // Get ID of submitting client identity - String clientID = ctx.getClientIdentity().getId(); - - // Verify that the client is submitting request to peer in their organization - // This is to ensure that a client from another org doesn't attempt to read or - // write private data from this peer. - verifyClientOrgMatchesPeerOrg(ctx); - - // Make submitting client the owner - asset.setOwner(clientID); - System.out.printf("CreateAsset Put: collection %s, ID %s\n", ASSET_COLLECTION_NAME, assetID); - System.out.printf("Put: collection %s, ID %s\n", ASSET_COLLECTION_NAME, new String(asset.serialize())); - stub.putPrivateData(ASSET_COLLECTION_NAME, assetID, asset.serialize()); - - // Get collection name for this organization. - String orgCollectionName = getCollectionName(ctx); - - // Save AssetPrivateDetails to org collection - AssetPrivateDetails assetPriv = new AssetPrivateDetails(assetID, appraisedValue); - System.out.printf("Put AssetPrivateDetails: collection %s, ID %s\n", orgCollectionName, assetID); - stub.putPrivateData(orgCollectionName, assetID, assetPriv.serialize()); - - return asset; - } - - /** - * AgreeToTransfer is used by the potential buyer of the asset to agree to the - * asset value. The agreed to appraisal value is stored in the buying orgs - * org specifc collection, while the buyer client ID is stored in the asset collection - * using a composite key - * Uses transient map with key asset_value - * - * @param ctx the transaction context - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public void AgreeToTransfer(final Context ctx) { - ChaincodeStub stub = ctx.getStub(); - Map transientMap = ctx.getStub().getTransient(); - if (!transientMap.containsKey("asset_value")) { - String errorMessage = String.format("AgreeToTransfer call must specify \"asset_value\" in Transient map input"); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - byte[] transientAssetJSON = transientMap.get("asset_value"); - AssetPrivateDetails assetPriv; - String assetID; - try { - JSONObject json = new JSONObject(new String(transientAssetJSON, UTF_8)); - assetID = json.getString("assetID"); - final int appraisedValue = json.getInt("appraisedValue"); - - assetPriv = new AssetPrivateDetails(assetID, appraisedValue); - } catch (Exception err) { - String errorMessage = String.format("TransientMap deserialized error %s ", err); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - if (assetID.equals("")) { - String errorMessage = String.format("Invalid input in Transient map: assetID"); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - if (assetPriv.getAppraisedValue() <= 0) { // appraisedValue field must be a positive integer - String errorMessage = String.format("Input must be positive integer: appraisedValue"); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - System.out.printf("AgreeToTransfer: verify asset %s exists\n", assetID); - Asset existing = ReadAsset(ctx, assetID); - if (existing == null) { - String errorMessage = String.format("Asset does not exist in the collection: ", assetID); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - // Get collection name for this organization. - String orgCollectionName = getCollectionName(ctx); - - verifyClientOrgMatchesPeerOrg(ctx); - - // Save AssetPrivateDetails to org collection - System.out.printf("Put AssetPrivateDetails: collection %s, ID %s\n", orgCollectionName, assetID); - stub.putPrivateData(orgCollectionName, assetID, assetPriv.serialize()); - - String clientID = ctx.getClientIdentity().getId(); - // Write the AgreeToTransfer key in assetCollection - CompositeKey aggKey = stub.createCompositeKey(AGREEMENT_KEYPREFIX, assetID); - System.out.printf("AgreeToTransfer Put: collection %s, ID %s, Key %s\n", ASSET_COLLECTION_NAME, assetID, aggKey); - stub.putPrivateData(ASSET_COLLECTION_NAME, aggKey.toString(), clientID); - } - - /** - * TransferAsset transfers the asset to the new owner by setting a new owner ID based on - * AgreeToTransfer data - * - * @param ctx the transaction context - * @return none - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public void TransferAsset(final Context ctx) { - ChaincodeStub stub = ctx.getStub(); - Map transientMap = ctx.getStub().getTransient(); - if (!transientMap.containsKey("asset_owner")) { - String errorMessage = "TransferAsset call must specify \"asset_owner\" in Transient map input"; - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - byte[] transientAssetJSON = transientMap.get("asset_owner"); - final String assetID; - final String buyerMSP; - try { - JSONObject json = new JSONObject(new String(transientAssetJSON, UTF_8)); - assetID = json.getString("assetID"); - buyerMSP = json.getString("buyerMSP"); - - } catch (Exception err) { - String errorMessage = String.format("TransientMap deserialized error %s ", err); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - if (assetID.equals("")) { - String errorMessage = String.format("Invalid input in Transient map: " + "assetID"); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - if (buyerMSP.equals("")) { - String errorMessage = String.format("Invalid input in Transient map: " + "buyerMSP"); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - System.out.printf("TransferAsset: verify asset %s exists\n", assetID); - byte[] assetJSON = stub.getPrivateData(ASSET_COLLECTION_NAME, assetID); - - if (assetJSON == null || assetJSON.length == 0) { - String errorMessage = String.format("Asset %s does not exist in the collection", assetID); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - verifyClientOrgMatchesPeerOrg(ctx); - Asset thisAsset = Asset.deserialize(assetJSON); - // Verify transfer details and transfer owner - verifyAgreement(ctx, assetID, thisAsset.getOwner(), buyerMSP); - - TransferAgreement transferAgreement = ReadTransferAgreement(ctx, assetID); - if (transferAgreement == null) { - String errorMessage = String.format("TransferAgreement does not exist for asset: %s", assetID); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - // Transfer asset in private data collection to new owner - String newOwner = transferAgreement.getBuyerID(); - thisAsset.setOwner(newOwner); - - // Save updated Asset to collection - System.out.printf("Transfer Asset: collection %s, ID %s to owner %s\n", ASSET_COLLECTION_NAME, assetID, newOwner); - stub.putPrivateData(ASSET_COLLECTION_NAME, assetID, thisAsset.serialize()); - - // Delete the key from owners collection - String ownersCollectionName = getCollectionName(ctx); - stub.delPrivateData(ownersCollectionName, assetID); - - // Delete the transfer agreement from the asset collection - CompositeKey aggKey = stub.createCompositeKey(AGREEMENT_KEYPREFIX, assetID); - System.out.printf("AgreeToTransfer deleteKey: collection %s, ID %s, Key %s\n", ASSET_COLLECTION_NAME, assetID, aggKey); - stub.delPrivateData(ASSET_COLLECTION_NAME, aggKey.toString()); - } - - /** - * Deletes a asset & related details from the ledger. - * Input in transient map: asset_delete - * - * This deletes the private data, but does not trigger an immediate cleanup - * of the history. To specifically force removal right now use purge - * - * @param ctx the transaction context - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public void DeleteAsset(final Context ctx) { - ChaincodeStub stub = ctx.getStub(); - Map transientMap = ctx.getStub().getTransient(); - if (!transientMap.containsKey("asset_delete")) { - String errorMessage = String.format("DeleteAsset call must specify 'asset_delete' in Transient map input"); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - byte[] transientAssetJSON = transientMap.get("asset_delete"); - final String assetID; - - try { - JSONObject json = new JSONObject(new String(transientAssetJSON, UTF_8)); - assetID = json.getString("assetID"); - - } catch (Exception err) { - String errorMessage = String.format("TransientMap deserialized error: %s ", err); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - System.out.printf("DeleteAsset: verify asset %s exists\n", assetID); - byte[] assetJSON = stub.getPrivateData(ASSET_COLLECTION_NAME, assetID); - - if (assetJSON == null || assetJSON.length == 0) { - String errorMessage = String.format("Asset %s does not exist", assetID); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - String ownersCollectionName = getCollectionName(ctx); - byte[] apdJSON = stub.getPrivateData(ownersCollectionName, assetID); - - if (apdJSON == null || apdJSON.length == 0) { - String errorMessage = String.format("Failed to read asset from owner's Collection %s", ownersCollectionName); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - verifyClientOrgMatchesPeerOrg(ctx); - - // delete the key from asset collection - System.out.printf("DeleteAsset: collection %s, ID %s\n", ASSET_COLLECTION_NAME, assetID); - stub.delPrivateData(ASSET_COLLECTION_NAME, assetID); - - // Finally, delete private details of asset - stub.delPrivateData(ownersCollectionName, assetID); - } - - /** - * Purges the history of the asset from Private Data - * (delete does not need to be called as well) - * Input in transient map: asset_delete - * - * @param ctx the transaction context - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public void PurgeAsset(final Context ctx) { - ChaincodeStub stub = ctx.getStub(); - Map transientMap = ctx.getStub().getTransient(); - if (!transientMap.containsKey("asset_purge")) { - String errorMessage = String.format("PurgeAsset call must specify 'asset_purge' in Transient map input"); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - byte[] transientAssetJSON = transientMap.get("asset_purge"); - final String assetID; - - try { - JSONObject json = new JSONObject(new String(transientAssetJSON, UTF_8)); - assetID = json.getString("assetID"); - - } catch (Exception err) { - String errorMessage = String.format("TransientMap deserialized error: %s ", err); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INCOMPLETE_INPUT.toString()); - } - - // Note that there is no check here to see if the id exist; it might have been 'deleted' already - // so a check here is pointless. We would need to call purge irrespective of the result - // A delete can be called before purge, but is not essential - - String ownersCollectionName = getCollectionName(ctx); - verifyClientOrgMatchesPeerOrg(ctx); - - // delete the key from asset collection - System.out.printf("PurgeAsset: collection %s, ID %s\n", ASSET_COLLECTION_NAME, assetID); - stub.purgePrivateData(ASSET_COLLECTION_NAME, assetID); - - // Finally, delete private details of asset - System.out.printf("PurgeAsset: collection %s, ID %s\n", ownersCollectionName, assetID); - stub.purgePrivateData(ownersCollectionName, assetID); - } - - - // Used by TransferAsset to verify that the transfer is being initiated by the owner and that - // the buyer has agreed to the same appraisal value as the owner - private void verifyAgreement(final Context ctx, final String assetID, final String owner, final String buyerMSP) { - String clienID = ctx.getClientIdentity().getId(); - - // Check 1: verify that the transfer is being initiatied by the owner - if (!clienID.equals(owner)) { - throw new ChaincodeException("Submitting client identity does not own the asset", AssetTransferErrors.INVALID_ACCESS.toString()); - } - - // Check 2: verify that the buyer has agreed to the appraised value - String collectionOwner = getCollectionName(ctx); // get owner collection from caller identity - String collectionBuyer = buyerMSP + "PrivateCollection"; - - // Get hash of owners agreed to value - byte[] ownerAppraisedValueHash = ctx.getStub().getPrivateDataHash(collectionOwner, assetID); - if (ownerAppraisedValueHash == null) { - throw new ChaincodeException(String.format("Hash of appraised value for %s does not exist in collection %s", assetID, collectionOwner)); - } - - // Get hash of buyers agreed to value - byte[] buyerAppraisedValueHash = ctx.getStub().getPrivateDataHash(collectionBuyer, assetID); - if (buyerAppraisedValueHash == null) { - throw new ChaincodeException(String.format("Hash of appraised value for %s does not exist in collection %s. AgreeToTransfer must be called by the buyer first.", assetID, collectionBuyer)); - } - - // Verify that the two hashes match - if (!Arrays.equals(ownerAppraisedValueHash, buyerAppraisedValueHash)) { - throw new ChaincodeException(String.format("Hash for appraised value for owner %x does not match value for seller %x", ownerAppraisedValueHash, buyerAppraisedValueHash)); - } - } - - private void verifyClientOrgMatchesPeerOrg(final Context ctx) { - String clientMSPID = ctx.getClientIdentity().getMSPID(); - String peerMSPID = ctx.getStub().getMspId(); - - if (!peerMSPID.equals(clientMSPID)) { - String errorMessage = String.format("Client from org %s is not authorized to read or write private data from an org %s peer", clientMSPID, peerMSPID); - System.err.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.INVALID_ACCESS.toString()); - } - } - - private String getCollectionName(final Context ctx) { - - // Get the MSP ID of submitting client identity - String clientMSPID = ctx.getClientIdentity().getMSPID(); - // Create the collection name - return clientMSPID + "PrivateCollection"; - } - -} diff --git a/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/TransferAgreement.java b/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/TransferAgreement.java deleted file mode 100644 index 2082d978..00000000 --- a/asset-transfer-private-data/chaincode-java/src/main/java/org/hyperledger/fabric/samples/privatedata/TransferAgreement.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.hyperledger.fabric.samples.privatedata; - -import org.hyperledger.fabric.contract.annotation.DataType; -import org.hyperledger.fabric.contract.annotation.Property; -import org.hyperledger.fabric.shim.ChaincodeException; -import org.json.JSONObject; - -import static java.nio.charset.StandardCharsets.UTF_8; - -@DataType() -public final class TransferAgreement { - - @Property() - private final String assetID; - - - @Property() - private String buyerID; - - public String getAssetID() { - return assetID; - } - - public String getBuyerID() { - return buyerID; - } - - public TransferAgreement(final String assetID, - final String buyer) { - this.assetID = assetID; - this.buyerID = buyer; - } - - public byte[] serialize() { - String jsonStr = new JSONObject(this).toString(); - return jsonStr.getBytes(UTF_8); - } - - public static TransferAgreement deserialize(final byte[] assetJSON) { - try { - JSONObject json = new JSONObject(new String(assetJSON, UTF_8)); - final String id = json.getString("assetID"); - final String buyerID = json.getString("buyerID"); - return new TransferAgreement(id, buyerID); - } catch (Exception e) { - throw new ChaincodeException("Deserialize error: " + e.getMessage(), "DATA_ERROR"); - } - } - - -} diff --git a/asset-transfer-private-data/chaincode-java/src/test/java/org/hyperledger/fabric/samples/privatedata/AssetTransferTest.java b/asset-transfer-private-data/chaincode-java/src/test/java/org/hyperledger/fabric/samples/privatedata/AssetTransferTest.java deleted file mode 100644 index 171efe68..00000000 --- a/asset-transfer-private-data/chaincode-java/src/test/java/org/hyperledger/fabric/samples/privatedata/AssetTransferTest.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.privatedata; - -import org.hyperledger.fabric.contract.ClientIdentity; -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.shim.ChaincodeException; -import org.hyperledger.fabric.shim.ChaincodeStub; -import org.hyperledger.fabric.shim.ledger.CompositeKey; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; -import java.util.Map; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.ThrowableAssert.catchThrowable; -import static org.hyperledger.fabric.samples.privatedata.AssetTransfer.AGREEMENT_KEYPREFIX; -import static org.hyperledger.fabric.samples.privatedata.AssetTransfer.ASSET_COLLECTION_NAME; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.when; - -public final class AssetTransferTest { - - @Nested - class InvokeWriteTransaction { - - @Test - public void createAssetWhenAssetExists() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - Map m = new HashMap<>(); - m.put("asset_properties", DATA_ASSET_1_BYTES); - when(ctx.getStub().getTransient()).thenReturn(m); - when(stub.getPrivateData(ASSET_COLLECTION_NAME, TEST_ASSET_1_ID)) - .thenReturn(DATA_ASSET_1_BYTES); - - Throwable thrown = catchThrowable(() -> { - contract.CreateAsset(ctx); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Asset asset1 already exists"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("ASSET_ALREADY_EXISTS".getBytes()); - } - - @Test - public void createAssetWhenNewAssetIsCreated() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getMspId()).thenReturn(TEST_ORG_1_MSP); - ClientIdentity ci = mock(ClientIdentity.class); - when(ci.getId()).thenReturn(TEST_ORG_1_USER); - when(ci.getMSPID()).thenReturn(TEST_ORG_1_MSP); - when(ctx.getClientIdentity()).thenReturn(ci); - - Map m = new HashMap<>(); - m.put("asset_properties", DATA_ASSET_1_BYTES); - when(ctx.getStub().getTransient()).thenReturn(m); - - when(stub.getPrivateData(ASSET_COLLECTION_NAME, TEST_ASSET_1_ID)) - .thenReturn(new byte[0]); - - Asset created = contract.CreateAsset(ctx); - assertThat(created).isEqualTo(TEST_ASSET_1); - - verify(stub).putPrivateData(ASSET_COLLECTION_NAME, TEST_ASSET_1_ID, created.serialize()); - } - - @Test - public void transferAssetWhenExistingAssetIsTransferred() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getMspId()).thenReturn(TEST_ORG_1_MSP); - ClientIdentity ci = mock(ClientIdentity.class); - when(ci.getId()).thenReturn(TEST_ORG_1_USER); - when(ctx.getClientIdentity()).thenReturn(ci); - when(ci.getMSPID()).thenReturn(TEST_ORG_1_MSP); - final String recipientOrgMsp = "TestOrg2"; - final String buyerIdentity = "TestOrg2User"; - Map m = new HashMap<>(); - m.put("asset_owner", ("{ \"buyerMSP\": \"" + recipientOrgMsp + "\", \"assetID\": \"" + TEST_ASSET_1_ID + "\" }").getBytes()); - when(ctx.getStub().getTransient()).thenReturn(m); - - when(stub.getPrivateDataHash(anyString(), anyString())).thenReturn("TestHashValue".getBytes()); - when(stub.getPrivateData(ASSET_COLLECTION_NAME, TEST_ASSET_1_ID)) - .thenReturn(DATA_ASSET_1_BYTES); - CompositeKey ck = mock(CompositeKey.class); - when(ck.toString()).thenReturn(AGREEMENT_KEYPREFIX + TEST_ASSET_1_ID); - when(stub.createCompositeKey(AGREEMENT_KEYPREFIX, TEST_ASSET_1_ID)).thenReturn(ck); - when(stub.getPrivateData(ASSET_COLLECTION_NAME, AGREEMENT_KEYPREFIX + TEST_ASSET_1_ID)).thenReturn(buyerIdentity.getBytes(UTF_8)); - contract.TransferAsset(ctx); - - Asset exptectedAfterTransfer = Asset.deserialize("{ \"objectType\": \"testasset\", \"assetID\": \"asset1\", \"color\": \"blue\", \"size\": 5, \"owner\": \"" + buyerIdentity + "\", \"appraisedValue\": 300 }"); - - verify(stub).putPrivateData(ASSET_COLLECTION_NAME, TEST_ASSET_1_ID, exptectedAfterTransfer.serialize()); - String collectionOwner = TEST_ORG_1_MSP + "PrivateCollection"; - verify(stub).delPrivateData(collectionOwner, TEST_ASSET_1_ID); - verify(stub).delPrivateData(ASSET_COLLECTION_NAME, AGREEMENT_KEYPREFIX + TEST_ASSET_1_ID); - } - } - - @Nested - class QueryReadAssetTransaction { - - @Test - public void whenAssetExists() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getPrivateData(ASSET_COLLECTION_NAME, TEST_ASSET_1_ID)) - .thenReturn(DATA_ASSET_1_BYTES); - - Asset asset = contract.ReadAsset(ctx, TEST_ASSET_1_ID); - - assertThat(asset).isEqualTo(TEST_ASSET_1); - } - - @Test - public void whenAssetDoesNotExist() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState(TEST_ASSET_1_ID)).thenReturn(null); - - Asset asset = contract.ReadAsset(ctx, TEST_ASSET_1_ID); - assertThat(asset).isNull(); - } - - @Test - public void invokeUnknownTransaction() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - - Throwable thrown = catchThrowable(() -> { - contract.unknownTransaction(ctx); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Undefined contract method called"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo(null); - - verifyNoInteractions(ctx); - } - - } - - private static final String TEST_ORG_1_MSP = "TestOrg1"; - private static final String TEST_ORG_1_USER = "testOrg1User"; - - private static final String TEST_ASSET_1_ID = "asset1"; - private static final Asset TEST_ASSET_1 = new Asset("testasset", "asset1", "blue", 5, TEST_ORG_1_USER); - private static final byte[] DATA_ASSET_1_BYTES = "{ \"objectType\": \"testasset\", \"assetID\": \"asset1\", \"color\": \"blue\", \"size\": 5, \"owner\": \"testOrg1User\", \"appraisedValue\": 300 }".getBytes(); -} diff --git a/asset-transfer-private-data/chaincode-java/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/asset-transfer-private-data/chaincode-java/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index 1f0955d4..00000000 --- a/asset-transfer-private-data/chaincode-java/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline diff --git a/asset-transfer-private-data/chaincode-typescript/.dockerignore b/asset-transfer-private-data/chaincode-typescript/.dockerignore deleted file mode 100644 index b512c09d..00000000 --- a/asset-transfer-private-data/chaincode-typescript/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -node_modules \ No newline at end of file diff --git a/asset-transfer-private-data/chaincode-typescript/.gitignore b/asset-transfer-private-data/chaincode-typescript/.gitignore deleted file mode 100644 index 79bfe1a3..00000000 --- a/asset-transfer-private-data/chaincode-typescript/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - - -# Coverage directory used by tools like istanbul -coverage - -# Dependency directories -node_modules/ -jspm_packages/ -package-lock.json - -# Compiled TypeScript files -dist - diff --git a/asset-transfer-private-data/chaincode-typescript/Dockerfile b/asset-transfer-private-data/chaincode-typescript/Dockerfile deleted file mode 100644 index 98c90e77..00000000 --- a/asset-transfer-private-data/chaincode-typescript/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# -FROM node:16 AS builder - -WORKDIR /usr/src/app - -# Copy node.js source and build, changing owner as well -COPY --chown=node:node . /usr/src/app -ENV npm_config_cache=/usr/src/app -RUN npm ci && npm run package - - -FROM node:16 AS production -ARG CC_SERVER_PORT - -# Setup tini to work better handle signals -ENV TINI_VERSION v0.19.0 -ENV PLATFORM=amd64 -ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${PLATFORM} /tini -RUN chmod +x /tini - -WORKDIR /usr/src/app -COPY --chown=node:node --from=builder /usr/src/app/dist ./dist -COPY --chown=node:node --from=builder /usr/src/app/package.json ./ -COPY --chown=node:node --from=builder /usr/src/app/npm-shrinkwrap.json ./ -COPY --chown=node:node docker/docker-entrypoint.sh /usr/src/app/docker-entrypoint.sh - -RUN npm ci --omit=dev && npm cache clean --force - -ENV PORT $CC_SERVER_PORT -EXPOSE $CC_SERVER_PORT -ENV NODE_ENV=production - -USER node -ENTRYPOINT [ "/tini", "--", "/usr/src/app/docker-entrypoint.sh" ] diff --git a/asset-transfer-private-data/chaincode-typescript/Readme.md b/asset-transfer-private-data/chaincode-typescript/Readme.md deleted file mode 100644 index 3a81fe77..00000000 --- a/asset-transfer-private-data/chaincode-typescript/Readme.md +++ /dev/null @@ -1,9 +0,0 @@ -## Usage -This chaincode written for Hyperledger Fabric private data tutorial(https://hyperledger-fabric.readthedocs.io/en/latest/private_data_tutorial.html). - -### Deploy chaincode with: -1. ``` cd fabric-samples/asset-transfer-private-data/chaincode-typescript/ ``` -2. ``` npm install ``` -3. ``` npm run build ``` -4. ``` cd fabric-samples/test-network/ ``` -5. ``` ./network.sh deployCC -ccn private -ccp ../asset-transfer-private-data/chaincode-typescript/ -ccl typescript -ccep "OR('Org1MSP.peer','Org2MSP.peer')" -cccg ../asset-transfer-private-data/chaincode-typescript/collections_config.json ``` \ No newline at end of file diff --git a/asset-transfer-private-data/chaincode-typescript/collections_config.json b/asset-transfer-private-data/chaincode-typescript/collections_config.json deleted file mode 100644 index 993bbd31..00000000 --- a/asset-transfer-private-data/chaincode-typescript/collections_config.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "name": "assetCollection", - "policy": "OR('Org1MSP.member', 'Org2MSP.member')", - "requiredPeerCount": 1, - "maxPeerCount": 1, - "blockToLive":1000000, - "memberOnlyRead": true, - "memberOnlyWrite": true, - "endorsementPolicy": { - "signaturePolicy":"OR('Org1MSP.member','Org2MSP.member')" - } -}, - { - "name": "Org1MSPPrivateCollection", - "policy": "OR('Org1MSP.member')", - "requiredPeerCount": 0, - "maxPeerCount": 1, - "blockToLive":3, - "memberOnlyRead": true, - "memberOnlyWrite": false, - "endorsementPolicy": { - "signaturePolicy": "OR('Org1MSP.member')" - } - }, - { - "name": "Org2MSPPrivateCollection", - "policy": "OR('Org2MSP.member')", - "requiredPeerCount": 0, - "maxPeerCount": 1, - "blockToLive":3, - "memberOnlyRead": true, - "memberOnlyWrite": false, - "endorsementPolicy": { - "signaturePolicy": "OR('Org2MSP.member')" - } - } -] diff --git a/asset-transfer-private-data/chaincode-typescript/docker/docker-entrypoint.sh b/asset-transfer-private-data/chaincode-typescript/docker/docker-entrypoint.sh deleted file mode 100644 index 2fd8fcf6..00000000 --- a/asset-transfer-private-data/chaincode-typescript/docker/docker-entrypoint.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -# -# SPDX-License-Identifier: Apache-2.0 -# -set -euo pipefail -: ${CORE_PEER_TLS_ENABLED:="false"} -: ${DEBUG:="false"} - -if [ "${DEBUG,,}" = "true" ]; then - npm run start:server-debug -elif [ "${CORE_PEER_TLS_ENABLED,,}" = "true" ]; then - npm run start:server -else - npm run start:server-nontls -fi - diff --git a/asset-transfer-private-data/chaincode-typescript/eslint.config.mjs b/asset-transfer-private-data/chaincode-typescript/eslint.config.mjs deleted file mode 100644 index 9ef6b243..00000000 --- a/asset-transfer-private-data/chaincode-typescript/eslint.config.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import js from '@eslint/js'; -import tseslint from 'typescript-eslint'; - -export default tseslint.config(js.configs.recommended, ...tseslint.configs.strictTypeChecked, { - languageOptions: { - ecmaVersion: 2023, - sourceType: 'module', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: import.meta.dirname, - }, - }, -}); diff --git a/asset-transfer-private-data/chaincode-typescript/npm-shrinkwrap.json b/asset-transfer-private-data/chaincode-typescript/npm-shrinkwrap.json deleted file mode 100644 index 940936a8..00000000 --- a/asset-transfer-private-data/chaincode-typescript/npm-shrinkwrap.json +++ /dev/null @@ -1,2256 +0,0 @@ -{ - "name": "asset-transfer-private-data", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "asset-transfer-private-data", - "version": "1.0.0", - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "~2.5", - "fabric-shim": "~2.5", - "json-stringify-deterministic": "^1.0.0", - "sort-keys-recursive": "^2.1.0" - }, - "devDependencies": { - "@eslint/js": "^9.3.0", - "@tsconfig/node18": "^18.2.4", - "@types/node": "^18.19.33", - "eslint": "^8.57.0", - "typescript": "~5.4.5", - "typescript-eslint": "^7.11.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.4.0.tgz", - "integrity": "sha512-fdI7VJjP3Rvc70lC4xkFXHB0fiPeojiL1PxVG6t1ZvXQrarj893PweuBTujxDUFk0Fxj4R7PIIAZ/aiiyZPZcg==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@fidm/asn1": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@fidm/asn1/-/asn1-1.0.4.tgz", - "integrity": "sha512-esd1jyNvRb2HVaQGq2Gg8Z0kbQPXzV9Tq5Z14KNIov6KfFD6PTaRIO8UpcsYiTNzOqJpmyzWgVTrUwFV3UF4TQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@fidm/x509": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@fidm/x509/-/x509-1.2.1.tgz", - "integrity": "sha512-nwc2iesjyc9hkuzcrMCBXQRn653XuAUKorfWM8PZyJawiy1QzLj4vahwzaI25+pfpwOLvMzbJ0uKpWLDNmo16w==", - "dependencies": { - "@fidm/asn1": "^1.0.4", - "tweetnacl": "^1.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.10.9", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.9.tgz", - "integrity": "sha512-5tcgUctCG0qoNyfChZifz2tJqbRbXVO9J7X6duFcOjY3HUNCxg5D0ZCK7EP9vIcZ0zRpLU9bWkyCqVCLZ46IbQ==", - "dependencies": { - "@grpc/proto-loader": "^0.7.13", - "@js-sdsl/ordered-map": "^4.4.2" - }, - "engines": { - "node": ">=12.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@hyperledger/fabric-protos": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@hyperledger/fabric-protos/-/fabric-protos-0.2.1.tgz", - "integrity": "sha512-qjm0vIQIfCall804tWDeA8p/mUfu14sl5Sj+PbOn2yDKJq+7ThoIhNsLAqf+BCxUfqsoqQq6AojhqQeTFyOOqg==", - "dependencies": { - "@grpc/grpc-js": "^1.9.0", - "google-protobuf": "^3.21.0" - }, - "engines": { - "node": ">=14.15.0" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@tsconfig/node18": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node18/-/node18-18.2.4.tgz", - "integrity": "sha512-5xxU8vVs9/FNcvm3gE07fPbn9tl6tqGGWA9tSlwsUEkBxtRnTsNmwrV8gasZ9F/EobaSv9+nu8AxUKccw77JpQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.19.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.34.tgz", - "integrity": "sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/triple-beam": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.0.tgz", - "integrity": "sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.13.0", - "@typescript-eslint/type-utils": "7.13.0", - "@typescript-eslint/utils": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.0.tgz", - "integrity": "sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "7.13.0", - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/typescript-estree": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz", - "integrity": "sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.0.tgz", - "integrity": "sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "7.13.0", - "@typescript-eslint/utils": "7.13.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz", - "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz", - "integrity": "sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.0.tgz", - "integrity": "sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.13.0", - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/typescript-estree": "7.13.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz", - "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/class-transformer": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", - "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==" - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fabric-contract-api": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-contract-api/-/fabric-contract-api-2.5.6.tgz", - "integrity": "sha512-AosGb8tA+Jgt+pqMEgYNB3/J/P5QuWOC7yhXbhDmAAwUzn4Sc7pdWDICH1YyrFGZNFxMGQmqJmLVWUX8BKHy0w==", - "dependencies": { - "class-transformer": "^0.4.0", - "fabric-shim-api": "2.5.6", - "fast-safe-stringify": "^2.1.1", - "get-params": "^0.1.2", - "reflect-metadata": "^0.1.13", - "winston": "^3.7.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fabric-shim": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-shim/-/fabric-shim-2.5.6.tgz", - "integrity": "sha512-4Y8WNFhYuQ9QYSEgPXWdlXnrXjwOlM10sQQzE4kJ7cDh8a4LX0rn44FxtxTCB18lnzrSLMZ8/8Cr5m0c9NeXWA==", - "dependencies": { - "@fidm/x509": "^1.2.1", - "@grpc/grpc-js": "~1.10.9", - "@hyperledger/fabric-protos": "~0.2.1", - "@types/node": "^16.11.1", - "ajv": "^6.12.2", - "fabric-contract-api": "2.5.6", - "fabric-shim-api": "2.5.6", - "fast-safe-stringify": "^2.1.1", - "long": "^5.2.3", - "reflect-metadata": "^0.1.13", - "winston": "^3.7.2", - "yargs": "^17.4.0", - "yargs-parser": "^21.0.1" - }, - "bin": { - "fabric-chaincode-node": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fabric-shim-api": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-shim-api/-/fabric-shim-api-2.5.6.tgz", - "integrity": "sha512-1L0nO7CJ31/gEOWKWHEeCqgB5HkqPVfRbpcS7L9eTscT7tffjg2OkZISvC+a7RiqihL0iyrXNBgBg5MwlSSN9g==", - "engines": { - "eslint": "^6.6.0", - "node": ">=18" - } - }, - "node_modules/fabric-shim/node_modules/@types/node": { - "version": "16.18.98", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.98.tgz", - "integrity": "sha512-fpiC20NvLpTLAzo3oVBKIqBGR6Fx/8oAK/SSf7G+fydnXMY1x4x9RZ6sBXhqKlCU21g2QapUsbLlhv3+a7wS+Q==" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-params": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/get-params/-/get-params-0.1.2.tgz", - "integrity": "sha512-41eOxtlGgHQRbFyA8KTH+w+32Em3cRdfBud7j67ulzmIfmaHX9doq47s0fa4P5o9H64BZX9nrYI6sJvk46Op+Q==" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/google-protobuf": { - "version": "3.21.2", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz", - "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json-stringify-deterministic": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/json-stringify-deterministic/-/json-stringify-deterministic-1.0.12.tgz", - "integrity": "sha512-q3PN0lbUdv0pmurkBNdJH3pfFvOTL/Zp0lquqpvcjfKzt6Y0j49EPHAmVHCAS4Ceq/Y+PejWTzyiVpoY71+D6g==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/logform": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", - "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", - "dependencies": { - "@colors/colors": "1.6.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/protobufjs": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.2.tgz", - "integrity": "sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/reflect-metadata": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", - "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==" - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/sort-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-4.2.0.tgz", - "integrity": "sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==", - "dependencies": { - "is-plain-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sort-keys-recursive": { - "version": "2.1.10", - "resolved": "https://registry.npmjs.org/sort-keys-recursive/-/sort-keys-recursive-2.1.10.tgz", - "integrity": "sha512-yRLJbEER/PjU7hSRwXvP+NyXiORufu8rbSbp+3wFRuJZXoi/AhuKczbjuipqn7Le0SsTXK4VUeri2+Ni6WS8Hg==", - "dependencies": { - "kind-of": "~6.0.2", - "sort-keys": "~4.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "engines": { - "node": "*" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/triple-beam": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", - "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.13.0.tgz", - "integrity": "sha512-upO0AXxyBwJ4BbiC6CRgAJKtGYha2zw4m1g7TIVPSonwYEuf7vCicw3syjS1OxdDMTz96sZIXl3Jx3vWJLLKFw==", - "dev": true, - "dependencies": { - "@typescript-eslint/eslint-plugin": "7.13.0", - "@typescript-eslint/parser": "7.13.0", - "@typescript-eslint/utils": "7.13.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/winston": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.0.tgz", - "integrity": "sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==", - "dependencies": { - "@colors/colors": "^1.6.0", - "@dabh/diagnostics": "^2.0.2", - "async": "^3.2.3", - "is-stream": "^2.0.0", - "logform": "^2.4.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "safe-stable-stringify": "^2.3.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/winston-transport": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", - "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", - "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/asset-transfer-private-data/chaincode-typescript/package.json b/asset-transfer-private-data/chaincode-typescript/package.json deleted file mode 100755 index 204a1e84..00000000 --- a/asset-transfer-private-data/chaincode-typescript/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "asset-transfer-private-data", - "version": "1.0.0", - "description": "Asset Transfer(Private Data Tutorial) contract implemented in TypeScript.", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "engines": { - "node": ">=18" - }, - "scripts": { - "lint": "eslint src", - "pretest": "npm run lint", - "test": "", - "start": "set -x && fabric-chaincode-node start", - "build": "tsc", - "build:watch": "tsc -w", - "prepublishOnly": "npm run build", - "docker": "docker build -f ./Dockerfile -t asset-transfer-private-data .", - "package": "npm run build && npm shrinkwrap", - "start:server-nontls": "set -x && fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID", - "start:server-debug": "set -x && NODE_OPTIONS='--inspect=0.0.0.0:9229' fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID", - "start:server": "set -x && fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID --chaincode-tls-key-file=/hyperledger/privatekey.pem --chaincode-tls-client-cacert-file=/hyperledger/rootcert.pem --chaincode-tls-cert-file=/hyperledger/cert.pem" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "~2.5", - "fabric-shim": "~2.5", - "json-stringify-deterministic": "^1.0.0", - "sort-keys-recursive": "^2.1.0" - }, - "devDependencies": { - "@types/node": "^18.19.33", - "@eslint/js": "^9.3.0", - "@tsconfig/node18": "^18.2.4", - "eslint": "^8.57.0", - "typescript": "~5.4.5", - "typescript-eslint": "^7.11.0" - } -} diff --git a/asset-transfer-private-data/chaincode-typescript/src/asset.ts b/asset-transfer-private-data/chaincode-typescript/src/asset.ts deleted file mode 100644 index 02c1347d..00000000 --- a/asset-transfer-private-data/chaincode-typescript/src/asset.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - SPDX-License-Identifier: Apache-2.0 -*/ - -import { Object, Property } from "fabric-contract-api"; -import { nonEmptyString, positiveNumber } from "./utils"; - -@Object() -// Asset describes main asset details that are visible to all organizations -export class Asset { - @Property() - docType?: string; - - @Property() - ID: string = ""; - - @Property() - Color: string = ""; - - @Property() - Size: number = 0; - - @Property() - Owner: string = ""; - - static fromBytes(bytes: Uint8Array): Asset { - if (bytes.length === 0) { - throw new Error("no asset data"); - } - const json = Buffer.from(bytes).toString(); - const properties = JSON.parse(json) as Partial; - - const result = new Asset(); - result.docType = properties.docType; - result.ID = nonEmptyString(properties.ID, "ID field must be a non-empty string"); - result.Color = nonEmptyString(properties.Color, "Color field must be a non-empty string"); - result.Size = positiveNumber(properties.Size, "Size field must be a positive integer"); - result.Owner = nonEmptyString(properties.Owner, "appraiseOwner field must be a non-empty string"); - - return result; - } -} diff --git a/asset-transfer-private-data/chaincode-typescript/src/assetTransfer.ts b/asset-transfer-private-data/chaincode-typescript/src/assetTransfer.ts deleted file mode 100644 index fab116bd..00000000 --- a/asset-transfer-private-data/chaincode-typescript/src/assetTransfer.ts +++ /dev/null @@ -1,374 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ -import { Context, Contract, Info, Transaction } from 'fabric-contract-api'; -import stringify from 'json-stringify-deterministic'; -import sortKeysRecursive from 'sort-keys-recursive'; -import { Asset } from './asset'; -import { AssetPrivateDetails } from './assetTransferDetails'; -import { TransientAssetDelete, TransientAssetOwner, TransientAssetProperties, TransientAssetPurge, TransientAssetValue } from './assetTransferTransientInput'; -import { TransferAgreement } from './transferAgreement'; - -const assetCollection = 'assetCollection'; -const transferAgreementObjectType = 'transferAgreement'; - -@Info({ title: 'AssetTransfer', description: 'Smart contract for trading assets' }) -export class AssetTransfer extends Contract { - - // CreateAsset issues a new asset to the world state with given details. - @Transaction() - public async CreateAsset(ctx: Context): Promise { - const transientMap = ctx.stub.getTransient(); - const assetProperties = new TransientAssetProperties(transientMap); - - // Check if asset already exists - const assetAsBytes = await ctx.stub.getPrivateData(assetCollection, assetProperties.assetID); - if (assetAsBytes.length !== 0) { - throw new Error('this asset already exists: ' + assetProperties.assetID); - } - - // Get ID of submitting client identity - const clientID = ctx.clientIdentity.getID(); - - // Verify that the client is submitting request to peer in their organization - // This is to ensure that a client from another org doesn't attempt to read or - // write private data from this peer. - this.verifyClientOrgMatchesPeerOrg(ctx); - - const asset: Asset = { - ID: assetProperties.assetID, - Color: assetProperties.color, - Size: assetProperties.size, - Owner: clientID, - }; - - // Save asset to private data collection - // Typical logger, logs to stdout/file in the fabric managed docker container, running this chaincode - // Look for container name like dev-peer0.org1.example.com-{chaincodename_version}-xyz - await ctx.stub.putPrivateData(assetCollection, asset.ID, Buffer.from(stringify(sortKeysRecursive(asset)))); - - // Save asset details to collection visible to owning organization - const assetPrivateDetails: AssetPrivateDetails = { - ID: assetProperties.assetID, - AppraisedValue: assetProperties.appraisedValue, - }; - // Get collection name for this organization. - const orgCollection = this.getCollectionName(ctx); - // Put asset appraised value into owners org specific private data collection - console.log('Put: collection %v, ID %v', orgCollection, assetProperties.assetID); - await ctx.stub.putPrivateData(orgCollection, asset.ID, Buffer.from(stringify(sortKeysRecursive(assetPrivateDetails)))); - } - - // AgreeToTransfer is used by the potential buyer of the asset to agree to the - // asset value. The agreed to appraisal value is stored in the buying orgs - // org specifc collection, while the buyer client ID is stored in the asset collection - // using a composite key - @Transaction() - public async AgreeToTransfer(ctx: Context): Promise { - // Get ID of submitting client identity - const clientID = ctx.clientIdentity.getID(); - // Value is private, therefore it gets passed in transient field - const transientMap = ctx.stub.getTransient(); - const assetValue = new TransientAssetValue(transientMap); - - const valueJSON: AssetPrivateDetails = { - ID: assetValue.assetID, - AppraisedValue: assetValue.appraisedValue, - }; - // Read asset from the private data collection - const asset = await this.ReadAsset(ctx, valueJSON.ID); - // Verify that the client is submitting request to peer in their organization - this.verifyClientOrgMatchesPeerOrg(ctx); - - // Get collection name for this organization. Needs to be read by a member of the organization. - const orgCollection = this.getCollectionName(ctx); - console.log(`AgreeToTransfer Put: collection ${orgCollection}, ID ${valueJSON.ID}`); - // Put agreed value in the org specifc private data collection - await ctx.stub.putPrivateData(orgCollection, asset.ID, Buffer.from(stringify(sortKeysRecursive(valueJSON)))); - // Create agreeement that indicates which identity has agreed to purchase - // In a more realistic transfer scenario, a transfer agreement would be secured to ensure that it cannot - // be overwritten by another channel member - const transferAgreeKey = ctx.stub.createCompositeKey(transferAgreementObjectType, [valueJSON.ID]); - console.log(`AgreeToTransfer Put: collection ${assetCollection}, ID ${valueJSON.ID}, Key ${transferAgreeKey}`); - await ctx.stub.putPrivateData(assetCollection, transferAgreeKey, new Uint8Array(Buffer.from(clientID))); - } - - @Transaction() - // TransferAsset transfers the asset to the new owner by setting a new owner ID - public async TransferAsset(ctx: Context): Promise { - // Asset properties are private, therefore they get passed in transient field - const transientMap = ctx.stub.getTransient(); - const assetOwner = new TransientAssetOwner(transientMap); - - console.log('TransferAsset: verify asset exists ID ' + assetOwner.assetID); - // Read asset from the private data collection - const asset = await this.ReadAsset(ctx, assetOwner.assetID); - // Verify that the client is submitting request to peer in their organization - this.verifyClientOrgMatchesPeerOrg(ctx); - // Verify transfer details and transfer owner - await this.verifyAgreement(ctx, assetOwner.assetID, asset.Owner, assetOwner.buyerMSP); - - const transferAgreement = await this.ReadTransferAgreement(ctx, assetOwner.assetID); - if (transferAgreement.BuyerID === '') { - throw new Error('BuyerID not found in TransferAgreement for ' + assetOwner.assetID); - } - // Transfer asset in private data collection to new owner - asset.Owner = transferAgreement.BuyerID; - console.log(`TransferAsset Put: collection ${assetCollection}, ID ${assetOwner.assetID}`); - await ctx.stub.putPrivateData(assetCollection, assetOwner.assetID, Buffer.from(stringify(sortKeysRecursive(asset)))); // rewrite the asset - - // Get collection name for this organization - const ownersCollection = this.getCollectionName(ctx); - // Delete the asset appraised value from this organization's private data collection - await ctx.stub.deletePrivateData(ownersCollection, assetOwner.assetID); - // Delete the transfer agreement from the asset collection - const transferAgreeKey = ctx.stub.createCompositeKey(transferAgreementObjectType, [assetOwner.assetID]); - await ctx.stub.deletePrivateData(assetCollection, transferAgreeKey); - } - - @Transaction() - // DeleteAsset can be used by the owner of the asset to delete the asset - public async DeleteAsset(ctx: Context): Promise { - // Value is private, therefore it gets passed in transient field - const transientMap = ctx.stub.getTransient(); - const assetDelete = new TransientAssetDelete(transientMap); - - // Verify that the client is submitting request to peer in their organization - this.verifyClientOrgMatchesPeerOrg(ctx); - - console.log('Deleting Asset: ' + assetDelete.assetID); - // get the asset from chaincode state - const valAsbytes = await ctx.stub.getPrivateData(assetCollection, assetDelete.assetID); - if (valAsbytes.length === 0) { - throw new Error('asset not found: ' + assetDelete.assetID); - } - const ownerCollection = this.getCollectionName(ctx); - // Check the asset is in the caller org's private collection - const valAsbytesPrivate = await ctx.stub.getPrivateData(ownerCollection, assetDelete.assetID); - if (valAsbytesPrivate.length === 0) { - throw new Error(`asset not found in owner's private Collection: ${ownerCollection} : ${assetDelete.assetID}`); - } - // delete the asset from state - await ctx.stub.deletePrivateData(assetCollection, assetDelete.assetID); - // Finally, delete private details of asset - await ctx.stub.deletePrivateData(ownerCollection, assetDelete.assetID); - } - - @Transaction() - // PurgeAsset can be used by the owner of the asset to delete the asset - // Trigger removal of the asset - public async PurgeAsset(ctx: Context): Promise { - // Value is private, therefore it gets passed in transient field - const transientMap = ctx.stub.getTransient(); - const assetPurge = new TransientAssetPurge(transientMap); - - // Verify that the client is submitting request to peer in their organization - this.verifyClientOrgMatchesPeerOrg(ctx); - - console.log('Purging Asset: ' + assetPurge.assetID); - // Note that there is no check here to see if the id exist; it might have been 'deleted' already - // so a check here is pointless. We would need to call purge irrespective of the result - // A delete can be called before purge, but is not essential - const ownerCollection = this.getCollectionName(ctx); - // delete the asset from state - await ctx.stub.purgePrivateData(assetCollection, assetPurge.assetID); - // Finally, delete private details of asset - await ctx.stub.purgePrivateData(ownerCollection, assetPurge.assetID); - } - - @Transaction() - // DeleteTranferAgreement can be used by the buyer to withdraw a proposal from - // the asset collection and from his own collection. - public async DeleteTransferAgreement(ctx: Context): Promise { - // Value is private, therefore it gets passed in transient field - const transientMap = ctx.stub.getTransient(); - const agreementDelete = new TransientAssetDelete(transientMap); - - // Verify that the client is submitting request to peer in their organization - this.verifyClientOrgMatchesPeerOrg(ctx); - - // Delete private details of agreement - // Get proposers collection. - const orgCollection = this.getCollectionName(ctx); - // Delete the transfer agreement from the asset collection - const transferAgreeKey = ctx.stub.createCompositeKey(transferAgreementObjectType, [agreementDelete.assetID]); - // get the transfer_agreement - const valAsbytes = await ctx.stub.getPrivateData(assetCollection, transferAgreeKey); - - if (valAsbytes.length === 0) { - throw new Error(`asset's transfer_agreement does not exist: ${agreementDelete.assetID}`); - } - // Delete the asset - await ctx.stub.deletePrivateData(orgCollection, agreementDelete.assetID); - // Delete transfer agreement record, remove agreement from state - await ctx.stub.deletePrivateData(assetCollection, transferAgreeKey); - } - - /* - GETTERS - */ - - // ReadAsset reads the information from collection - @Transaction() - public async ReadAsset(ctx: Context, id: string): Promise { - // Check if asset already exists - const assetAsBytes = await ctx.stub.getPrivateData(assetCollection, id); - // No Asset found, return empty response - if (assetAsBytes.length === 0) { - throw new Error(id + ' does not exist in collection ' + assetCollection); - } - return Asset.fromBytes(assetAsBytes); - } - - // ReadAssetPrivateDetails reads the asset private details in organization specific collection - @Transaction() - public async ReadAssetPrivateDetails(ctx: Context, collection: string, id: string): Promise { - // Check if asset already exists - const detailBytes = await ctx.stub.getPrivateData(collection, id); - // No Asset found, return empty response - if (detailBytes.length === 0) { - throw new Error(id + ' does not exist in collection ' + collection); - } - return AssetPrivateDetails.fromBytes(detailBytes); - } - - // ReadTransferAgreement gets the buyer's identity from the transfer agreement from collection - @Transaction() - public async ReadTransferAgreement(ctx: Context, assetID: string): Promise { - // composite key for TransferAgreement of this asset - const transferAgreeKey = ctx.stub.createCompositeKey(transferAgreementObjectType, [assetID]); - // Get the identity from collection - const buyerIdentity = await ctx.stub.getPrivateData(assetCollection, transferAgreeKey); - - if (buyerIdentity.length === 0) { - throw new Error(`TransferAgreement for ${assetID} does not exist `); - } - - return { - ID: assetID, - BuyerID: String(buyerIdentity), - }; - } - - // GetAssetByRange performs a range query based on the start and end keys provided. Range - // queries can be used to read data from private data collections, but can not be used in - // a transaction that also writes to private data. - @Transaction() - public async GetAssetByRange(ctx: Context, startKey: string, endKey: string): Promise { - const resultsIterator = ctx.stub.getPrivateDataByRange(assetCollection, startKey, endKey); - const results: Asset[] = []; - for await (const res of resultsIterator) { - const asset = Asset.fromBytes(res.value); - results.push(asset); - } - return results; - } - /* - HELPERS - */ - // verifyAgreement is an internal helper function used by TransferAsset to verify - // that the transfer is being initiated by the owner and that the buyer has agreed - // to the same appraisal value as the owner - public async verifyAgreement(ctx: Context, assetID: string, owner: string, buyerMSP: string): Promise { - // Check 1: verify that the transfer is being initiatied by the owner - // Get ID of submitting client identity - const clientID = ctx.clientIdentity.getID(); - if (clientID !== owner) { - throw new Error(`error: submitting client(${clientID}) identity does not own asset ${assetID}.Owner is ${owner}`); - } - // Check 2: verify that the buyer has agreed to the appraised value - // Get collection names - const collectionOwner = this.getCollectionName(ctx); // get owner collection from caller identity - - const collectionBuyer = buyerMSP + 'PrivateCollection'; // get buyers collection - // Get hash of owners agreed to value - const ownerAppraisedValueHash = await ctx.stub.getPrivateDataHash(collectionOwner, assetID); - - if (ownerAppraisedValueHash.length === 0) { - throw new Error(`hash of appraised value for ${assetID} does not exist in collection ${collectionOwner}`); - } - // Get hash of buyers agreed to value - const buyerAppraisedValueHash = await ctx.stub.getPrivateDataHash(collectionBuyer, assetID); - if (buyerAppraisedValueHash.length === 0) { - throw new Error(`hash of appraised value for ${assetID} does not exist in collection ${collectionBuyer}. AgreeToTransfer must be called by the buyer first`); - } - // Verify that the two hashes match - if (ownerAppraisedValueHash.toString() !== buyerAppraisedValueHash.toString()) { - throw new Error(`hash for appraised value for owner ${Buffer.from(ownerAppraisedValueHash).toString('hex')} does not match value for seller ${Buffer.from(buyerAppraisedValueHash).toString('hex')}`); - } - } - // getCollectionName is an internal helper function to get collection of submitting client identity. - public getCollectionName(ctx: Context): string { - // Get the MSP ID of submitting client identity - const clientMSPID = ctx.clientIdentity.getMSPID(); - // Create the collection name - const orgCollection = clientMSPID + 'PrivateCollection'; - - return orgCollection; - } - // Get ID of submitting client identity - public submittingClientIdentity(ctx: Context): string { - - const b64ID = ctx.clientIdentity.getID(); - - // base64.StdEncoding.DecodeString(b64ID); - const decodeID = Buffer.from(b64ID, 'base64').toString('binary'); - - return String(decodeID); - } - // verifyClientOrgMatchesPeerOrg is an internal function used verify client org id and matches peer org id. - public verifyClientOrgMatchesPeerOrg(ctx: Context): void { - - const clientMSPID = ctx.clientIdentity.getMSPID(); - - const peerMSPID = ctx.stub.getMspID(); - - if (clientMSPID !== peerMSPID) { - throw new Error('client from org %v is not authorized to read or write private data from an org ' + clientMSPID + ' peer ' + peerMSPID); - } - } - // =======Rich queries ========================================================================= - // Two examples of rich queries are provided below (parameterized query and ad hoc query). - // Rich queries pass a query string to the state database. - // Rich queries are only supported by state database implementations - // that support rich query (e.g. CouchDB). - // The query string is in the syntax of the underlying state database. - // With rich queries there is no guarantee that the result set hasn't changed between - // endorsement time and commit time, aka 'phantom reads'. - // Therefore, rich queries should not be used in update transactions, unless the - // application handles the possibility of result set changes between endorsement and commit time. - // Rich queries can be used for point-in-time queries against a peer. - // ============================================================================================ - - // ===== Example: Parameterized rich query ================================================= - - // QueryAssetByOwner queries for assets based on assetType, owner. - // This is an example of a parameterized query where the query logic is baked into the chaincode, - // and accepting a single query parameter (owner). - // Only available on state databases that support rich query (e.g. CouchDB) - // ========================================================================================= - public async QueryAssetByOwner(ctx: Context, assetType: string, owner: string): Promise { - - const queryString = `{'selector':{'objectType':'${assetType}','owner':'${owner}'}}`; - - return await this.getQueryResultForQueryString(ctx, queryString); - } - - public QueryAssets(ctx: Context, queryString: string): Promise { - return this.getQueryResultForQueryString(ctx, queryString); - } - - public async getQueryResultForQueryString(ctx: Context, queryString: string): Promise { - - const resultsIterator = ctx.stub.getPrivateDataQueryResult(assetCollection, queryString); - - const results: Asset[] = []; - - for await (const res of resultsIterator) { - const asset = Asset.fromBytes(res.value); - results.push(asset); - } - - return results; - } -} diff --git a/asset-transfer-private-data/chaincode-typescript/src/assetTransferDetails.ts b/asset-transfer-private-data/chaincode-typescript/src/assetTransferDetails.ts deleted file mode 100644 index 7a63e8c7..00000000 --- a/asset-transfer-private-data/chaincode-typescript/src/assetTransferDetails.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - SPDX-License-Identifier: Apache-2.0 -*/ - -import { Object, Property } from "fabric-contract-api"; -import { nonEmptyString, positiveNumber } from "./utils"; - -@Object() -// AssetPrivateDetails describes details that are private to owners -export class AssetPrivateDetails { - @Property() - ID: string = ""; - @Property() - AppraisedValue: number = 0; - - static fromBytes(bytes: Uint8Array): AssetPrivateDetails { - if (bytes.length === 0) { - throw new Error("no asset private details"); - } - const json = Buffer.from(bytes).toString(); - const properties = JSON.parse(json) as Partial; - - const result = new AssetPrivateDetails(); - result.ID = nonEmptyString(properties.ID, "ID field must be a non-empty string"); - result.AppraisedValue = positiveNumber( - properties.AppraisedValue, - "AppraisedValue field must be a positive integer" - ); - - return result; - } -} diff --git a/asset-transfer-private-data/chaincode-typescript/src/assetTransferTransientInput.ts b/asset-transfer-private-data/chaincode-typescript/src/assetTransferTransientInput.ts deleted file mode 100644 index 66ed44d2..00000000 --- a/asset-transfer-private-data/chaincode-typescript/src/assetTransferTransientInput.ts +++ /dev/null @@ -1,115 +0,0 @@ -/* - SPDX-License-Identifier: Apache-2.0 -*/ - -import { nonEmptyString, positiveNumber } from "./utils"; - -export class TransientAssetProperties { - objectType: string; - assetID: string; - color: string; - size: number; - appraisedValue: number; - - constructor(transientMap: Map) { - const transient = transientMap.get("asset_properties"); - if (!transient?.length) { - throw new Error("no asset properties"); - } - const json = Buffer.from(transient).toString(); - const properties = JSON.parse(json) as Partial; - - this.objectType = nonEmptyString(properties.objectType, "objectType field must be a non-empty string"); - this.assetID = nonEmptyString(properties.assetID, "assetID field must be a non-empty string"); - this.color = nonEmptyString(properties.color, "color field must be a non-empty string"); - this.size = positiveNumber(properties.size, "size field must be a positive integer"); - this.appraisedValue = positiveNumber( - properties.appraisedValue, - "appraisedValue field must be a positive integer" - ); - } -} - -export class TransientAssetValue { - assetID: string; - appraisedValue: number; - - constructor(transientMap: Map) { - const transient = transientMap.get("asset_value"); - if (!transient?.length) { - throw new Error("no asset value"); - } - const json = Buffer.from(transient).toString(); - const properties = JSON.parse(json) as Partial; - - this.assetID = nonEmptyString(properties.assetID, "assetID field must be a non-empty string"); - this.appraisedValue = positiveNumber( - properties.appraisedValue, - "appraisedValue field must be a positive integer" - ); - } -} - -export class TransientAssetOwner { - assetID: string; - buyerMSP: string; - - constructor(transientMap: Map) { - const transient = transientMap.get("asset_owner"); - if (!transient?.length) { - throw new Error("no asset owner"); - } - const json = Buffer.from(transient).toString(); - const properties = JSON.parse(json) as Partial; - - this.assetID = nonEmptyString(properties.assetID, "assetID field must be a non-empty string"); - this.buyerMSP = nonEmptyString(properties.buyerMSP, "buyerMSP field must be a non-empty string"); - } -} - -export class TransientAssetDelete { - assetID: string; - - constructor(transientMap: Map) { - const transient = transientMap.get("asset_delete"); - if (!transient?.length) { - throw new Error("no asset delete"); - } - const json = Buffer.from(transient).toString(); - const properties = JSON.parse(json) as Partial; - - this.assetID = nonEmptyString(properties.assetID, "assetID field must be a non-empty string"); - } -} - -export class TransientAssetPurge { - assetID: string; - - constructor(transientMap: Map) { - const transient = transientMap.get("asset_purge"); - if (!transient?.length) { - throw new Error("no asset purge"); - } - - const json = Buffer.from(transient).toString(); - const properties = JSON.parse(json) as Partial; - - this.assetID = nonEmptyString(properties.assetID, "assetID field must be a non-empty string"); - } -} - -export class TransientAgreementDelete { - assetID: string; - - constructor(transientMap: Map) { - const transient = transientMap.get("agreement_delete"); - if (!transient?.length) { - throw new Error("no agreement delete"); - } - - const json = Buffer.from(transient).toString(); - const properties = JSON.parse(json) as Partial; - - this.assetID = nonEmptyString(properties.assetID, "assetID field must be a non-empty string"); - } -} diff --git a/asset-transfer-private-data/chaincode-typescript/src/index.ts b/asset-transfer-private-data/chaincode-typescript/src/index.ts deleted file mode 100644 index d5c4cc01..00000000 --- a/asset-transfer-private-data/chaincode-typescript/src/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -import { type Contract } from 'fabric-contract-api'; -import {AssetTransfer} from './assetTransfer'; - -export {AssetTransfer} from './assetTransfer'; - -export const contracts: typeof Contract[] = [AssetTransfer]; diff --git a/asset-transfer-private-data/chaincode-typescript/src/transferAgreement.ts b/asset-transfer-private-data/chaincode-typescript/src/transferAgreement.ts deleted file mode 100644 index fd780746..00000000 --- a/asset-transfer-private-data/chaincode-typescript/src/transferAgreement.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - SPDX-License-Identifier: Apache-2.0 -*/ - -import { Object, Property } from "fabric-contract-api"; - -@Object() -// TransferAgreement describes the buyer agreement returned by ReadTransferAgreement -export class TransferAgreement { - @Property() - ID: string = ""; - @Property() - BuyerID: string = ""; -} diff --git a/asset-transfer-private-data/chaincode-typescript/src/utils.ts b/asset-transfer-private-data/chaincode-typescript/src/utils.ts deleted file mode 100644 index 1763f0a9..00000000 --- a/asset-transfer-private-data/chaincode-typescript/src/utils.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - SPDX-License-Identifier: Apache-2.0 -*/ - -export function nonEmptyString(arg: unknown, errorMessage: string): string { - if (typeof arg !== "string" || arg.length === 0) { - throw new Error(errorMessage); - } - - return arg; -} - -export function positiveNumber(arg: unknown, errorMessage: string): number { - if (typeof arg !== "number" || arg < 1) { - throw new Error(errorMessage); - } - - return arg; -} diff --git a/asset-transfer-private-data/chaincode-typescript/tsconfig.json b/asset-transfer-private-data/chaincode-typescript/tsconfig.json deleted file mode 100644 index 031d7de7..00000000 --- a/asset-transfer-private-data/chaincode-typescript/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@tsconfig/node18/tsconfig.json", - "compilerOptions": { - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "outDir": "dist", - "strict": true, - "noUnusedLocals": true, - "noImplicitReturns": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["src/"] -} diff --git a/asset-transfer-sbe/README.md b/asset-transfer-sbe/README.md deleted file mode 100644 index 87bb99aa..00000000 --- a/asset-transfer-sbe/README.md +++ /dev/null @@ -1,169 +0,0 @@ -# State-based endorsement asset transfer sample - -Transactions that are submitted to Hyperledger Fabric networks need to be endorsed -by peers that are joined to a channel before the transaction can be added to the -ledger. Fabric peers endorse transactions by executing a smart contract using the -inputs of the transaction proposal. The peers then sign the input and output -generated by the smart contract execution. The endorsement policy specifies the -set of organizations whose peers need to endorse a transaction before it can be -added to the ledger. - -Each chaincode that is deployed to a channel has an endorsement policy that governs -the assets managed by the chaincode smart contracts. However, you can override the -chaincode level endorsement policy to create an endorsement policy for a specific key, -either on the public channel ledger or in a private collection. -State-based endorsement policies, also known as key-level endorsement policies, allow -channel members to use different endorsement policies for assets that are managed by -the same smart contract. For more information about endorsement policies and -state-based endorsement, visit the -[Endorsement Policies](https://hyperledger-fabric.readthedocs.io/en/release-2.2/endorsement-policies.html) -topic in the Fabric documentation. - -The implementation provided by State Based interface creates a policy which requires signatures from all the Org principals added, and hence is equivalent to an AND policy. For other advanced State Based policy implementations which are not supported by State Based interface directly like OR or NOutOf policies, please refer to method implementations setStateBasedEndorsementNOutOf(), which can be used as an alternative for setStateBasedEndorsement() inside asset-transfer-sbe smart contracts. - -## About the Sample - -The state-based endorsement (SBE) asset transfer sample demonstrates how to use -key-level endorsement policies to ensure that an asset only is endorsed by an -asset owner. In the course of the tutorial, you will use the smart contract -to complete the following transfer scenario: - -- Deploy the SBE smart contract to a channel that was created using the Fabric -test network. The channel will have two members, Org1 and Org2, that will -participate in the asset transfer. Each organization operates one peer that -is joined to the channel. -- Create an asset using the chaincode endorsement policy. The chaincode level -endorsement policy requires that a majority of organizations on the channel -endorse a transaction. This means that a transaction that creates an asset -needs to be endorsed by peers that belong to Org1 and Org2. When the asset is -created, the smart contract creates a state-based endorsement policy that -specifies that only the organization that owns that asset may endorse update -transactions. Because the asset is owned by Org1, any future updates to the asset -need to be endorsed by the Org1 peer. -- Update the asset by only endorsing with Org1, this will use the state-based -endorsement policy applied to the asset when it was created by the chaincode. -- Transfer the asset to Org2. During the execution of the transfer transaction, -the chaincode will create a new state-based endorsement policy that reflects -the new asset owner for the asset. -- Update the asset once more, this time with Org2 as the owner. Because the -state-based endorsement policy has been updated, this transaction only needs -to be endorsed by Org2. - -## Deploy the smart contract - -We are going to run the SBE smart contract using the Fabric test network. Open a command terminal and navigate to test network directory in your local clone of the `fabric-samples`. We will operate from the `test-network` directory for the remainder of the tutorial. -``` -cd fabric-samples/test-network -``` - -Run the following command to deploy the test network and create a channel named `mychannel`: - -``` -./network.sh up createChannel -``` - -You can use the test network script to deploy the smart contract to the channel that was just created. The script uses the Fabric chaincode lifecycle to deploy the smart contract to the channel. We will use the default chaincode level endorsement policy used by the Fabric chaincode lifecycle, which requires an endorsement from a majority of channel members. In our case, this will require that both Org1 and Org2 endorse a transaction (2 of 2). Deploy the smart contract to `mychannel` using the following command: -``` -./network.sh deployCC -ccn sbe -ccp ../asset-transfer-sbe/chaincode-typescript/ -ccl typescript -``` - -Set the following environment variables to interact with the network as a user from Org1: - -``` -export PATH=${PWD}/../bin:${PWD}:$PATH -export FABRIC_CFG_PATH=$PWD/../config/ -export CORE_PEER_TLS_ENABLED=true -export CORE_PEER_LOCALMSPID=Org1MSP -export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp -export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt -export CORE_PEER_ADDRESS=localhost:7051 -``` - -## Run the transfer scenario - -We can now invoke the SBE smart contract to create a new asset: -``` -peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n sbe --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"CreateAsset","Args":["asset1","100","Org1User1"]}' -``` -The create transaction needs to target both peers from Org1 and Org2 to meet the chaincode endorsement policy. The chaincode will read the MSP ID of the client user submitting the transaction and assign that organization as the asset owner. As a result, the asset will initially be owned by Org1. - -You can query the asset using with the following command: -``` -peer chaincode query -C mychannel -n sbe -c '{"Args":["ReadAsset","asset1"]}' -``` -The result is a new asset owned by Org1, identified using the Org1 MSP ID `Org1MSP`: -`{"ID":"asset1","Value":100,"Owner":"Org1User1","OwnerOrg":"Org1MSP"}` - -In addition to creating the asset, the `CreateAsset` function also sets a state-based endorsement policy for the asset. Only a peer of the asset owner, can successfully endorse an asset update. To demonstrate the key-level endorsement policy, lets try to update the asset while targeting the Org2 peer: -``` -peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n sbe --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"UpdateAsset","Args":["asset1","200"]}' -``` -The result is an endorsement policy failure: -``` -Error: transaction invalidated with status (ENDORSEMENT_POLICY_FAILURE) - proposal response: -``` - -If we attempt to update the asset with an endorsement from the Org1 peer, the update succeeds: -``` -peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n sbe --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" -c '{"function":"UpdateAsset","Args":["asset1","200"]}' -``` -You can query the asset one more time to verify that the update was successful: -``` -peer chaincode query -C mychannel -n sbe -c '{"Args":["ReadAsset","asset1"]}' -``` - -The asset value is now 200: -``` -{"ID":"asset1","Value":200,"Owner":"Org1User1","OwnerOrg":"Org1MSP"} -``` - -Now that we have tested the asset key-level endorsement policy, we can transfer the asset to Org2. Run the following command to transfer the asset from Org1 to Org2. This time the Org2 MSP ID is provided as a transaction input. The `TransferAsset` function will update the endorsement policy to specify that only a peer of the new owner can update the asset. Note that this command targets the Org1 peer. - -``` -peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n sbe --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" -c '{"function":"TransferAsset","Args":["asset1","Org2User1","Org2MSP"]}' -``` - -We can query the asset to see that the owner has been updated from Org1 to Org2: -``` -peer chaincode query -C mychannel -n sbe -c '{"Args":["ReadAsset","asset1"]}' -``` - -The owning organization is now Org2: -``` -{"ID":"asset1","Value":200,"Owner":"Org2User1","OwnerOrg":"Org2MSP"} -``` - -Org2 now needs to endorse any asset updates. Run the following command to try to update the asset with an endorsement from the Org1 peer: -``` -peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n sbe --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" -c '{"function":"UpdateAsset","Args":["asset1","300"]}' -``` - -The response will be an endorsement policy failure: -``` -Error: transaction invalidated with status (ENDORSEMENT_POLICY_FAILURE) - proposal response: -``` - -Now try to update the asset with an endorsement from the Org2 peer: -``` -peer chaincode invoke -o localhost:7050 --waitForEvent --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n sbe --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"UpdateAsset","Args":["asset1","300"]}' -``` - -You can query the asset again to verify that the transaction update succeeded: -``` -peer chaincode query -C mychannel -n sbe -c '{"Args":["ReadAsset","asset1"]}' -``` - -The asset value is now 300: -``` -{"ID":"asset1","Value":300,"Owner":"Org2User1","OwnerOrg":"Org2MSP"} -``` - -Note that the transaction to update the asset was submitted by a user from Org1, even though the asset was owned by Org2. The transfer enabled by the SBE smart contract is a simple scenario meant only to demonstrate the use of state-based endorsement policies. The smart contract can use access control to specify that an asset can only be updated by its owner. Private data collections can also be used to ensure that transfers need to be endorsed by the owner and recipient of the transfer, instead of just the asset owner. For a more realistic example of an asset transfer scenario, see the [Secured asset transfer in Fabric](https://hyperledger-fabric.readthedocs.io/en/master/secured_asset_transfer/secured_private_asset_transfer_tutorial.html) tutorial. - -## Clean up - -When you are finished, you can bring down the test network. The command will remove all the nodes of the test network, and delete any ledger data that you created: - -``` -./network.sh down -``` diff --git a/asset-transfer-sbe/application-javascript/.eslintignore b/asset-transfer-sbe/application-javascript/.eslintignore deleted file mode 100644 index 15958470..00000000 --- a/asset-transfer-sbe/application-javascript/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -coverage diff --git a/asset-transfer-sbe/application-javascript/.eslintrc.js b/asset-transfer-sbe/application-javascript/.eslintrc.js deleted file mode 100644 index 072edaf6..00000000 --- a/asset-transfer-sbe/application-javascript/.eslintrc.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ -'use strict'; - -module.exports = { - env: { - node: true, - mocha: true - }, - parserOptions: { - ecmaVersion: 8, - sourceType: 'script' - }, - extends: 'eslint:recommended', - rules: { - indent: ['error', 'tab'], - 'linebreak-style': ['error', 'unix'], - quotes: ['error', 'single'], - semi: ['error', 'always'], - 'no-unused-vars': ['error', { args: 'none' }], - 'no-console': 'off', - curly: 'error', - eqeqeq: 'error', - 'no-throw-literal': 'error', - strict: 'error', - 'no-var': 'error', - 'dot-notation': 'error', - 'no-trailing-spaces': 'error', - 'no-use-before-define': 'error', - 'no-useless-call': 'error', - 'no-with': 'error', - 'operator-linebreak': 'error', - yoda: 'error', - 'quote-props': ['error', 'as-needed'] - } -}; diff --git a/asset-transfer-sbe/application-javascript/.gitignore b/asset-transfer-sbe/application-javascript/.gitignore deleted file mode 100644 index 21b287f7..00000000 --- a/asset-transfer-sbe/application-javascript/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -# Coverage directory used by tools like istanbul -coverage - -# Dependency directories -node_modules/ -jspm_packages/ -package-lock.json - -wallet -!wallet/.gitkeep diff --git a/asset-transfer-sbe/application-javascript/app.js b/asset-transfer-sbe/application-javascript/app.js deleted file mode 100644 index 134f4443..00000000 --- a/asset-transfer-sbe/application-javascript/app.js +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -/** - * A test application to show state based endorsements operations with a running - * asset-transfer-sbe chaincode with discovery. - * -- How to submit a transaction - * -- How to query - * -- How to limit the organizations involved in a transaction - * - * To see the SDK workings, try setting the logging to show on the console before running - * export HFC_LOGGING='{"debug":"console"}' - */ - -// pre-requisites: -// - fabric-sample two organization test-network setup with two peers, ordering service, -// and 2 certificate authorities -// ===> from directory /fabric-samples/test-network -// ./network.sh up createChannel -ca -// - Use any of the asset-transfer-sbe chaincodes deployed on the channel "mychannel" -// with the chaincode name of "sbe". The following deploy command will package, -// install, approve, and commit the javascript chaincode, all the actions it takes -// to deploy a chaincode to a channel. -// ===> from directory /fabric-samples/test-network -// ./network.sh deployCC -ccn sbe -ccp ../asset-transfer-sbe/chaincode-typescript/ -ccl typescript -// - Be sure that node.js is installed -// ===> from directory /fabric-samples/asset-transfer-sbe/application-javascript -// node -v -// - npm installed code dependencies -// ===> from directory /fabric-samples/asset-transfer-sbe/application-javascript -// npm install -// - to run this test application -// ===> from directory /fabric-samples/asset-transfer-sbe/application-javascript -// node app.js - -// NOTE: If you see an error like these: -/* - - Error in setup: Error: DiscoveryService: mychannel error: access denied - - OR - - Failed to register user : Error: fabric-ca request register failed with errors [[ { code: 20, message: 'Authentication failure' } ]] - - */ -// Delete the /fabric-samples/asset-transfer-sbe/application-javascript/wallet directory -// and retry this application. -// -// The certificate authority must have been restarted and the saved certificates for the -// admin and application user are not valid. Deleting the wallet store will force these to be reset -// with the new certificate authority. -// - -const { Gateway, Wallets } = require('fabric-network'); -const FabricCAServices = require('fabric-ca-client'); -const path = require('path'); -const { buildCAClient, registerAndEnrollUser, enrollAdmin } = require('../../test-application/javascript/CAUtil.js'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); - -const channelName = 'mychannel'; -const chaincodeName = 'sbe'; - -const org1 = 'Org1MSP'; -const org2 = 'Org2MSP'; -const Org1UserId = 'appUser1'; -const Org2UserId = 'appUser2'; - -async function initGatewayForOrg1() { - console.log('\n--> Fabric client user & Gateway init: Using Org1 identity to Org1 Peer'); - // build an in memory object with the network configuration (also known as a connection profile) - const ccpOrg1 = buildCCPOrg1(); - - // build an instance of the fabric ca services client based on - // the information in the network configuration - const caOrg1Client = buildCAClient(FabricCAServices, ccpOrg1, 'ca.org1.example.com'); - - // setup the wallet to cache the credentials of the application user, on the app server locally - const walletPathOrg1 = path.join(__dirname, 'wallet', 'org1'); - const walletOrg1 = await buildWallet(Wallets, walletPathOrg1); - - // in a real application this would be done on an administrative flow, and only once - // stores admin identity in local wallet, if needed - await enrollAdmin(caOrg1Client, walletOrg1, org1); - // register & enroll application user with CA, which is used as client identify to make chaincode calls - // and stores app user identity in local wallet - // In a real application this would be done only when a new user was required to be added - // and would be part of an administrative flow - await registerAndEnrollUser(caOrg1Client, walletOrg1, org1, Org1UserId, 'org1.department1'); - - try { - // Create a new gateway for connecting to Org's peer node. - const gatewayOrg1 = new Gateway(); - //connect using Discovery enabled - await gatewayOrg1.connect(ccpOrg1, - { wallet: walletOrg1, identity: Org1UserId, discovery: { enabled: true, asLocalhost: true } }); - - return gatewayOrg1; - } catch (error) { - console.error(`Error in connecting to gateway for Org1: ${error}`); - process.exit(1); - } -} - -async function initGatewayForOrg2() { - console.log('\n--> Fabric client user & Gateway init: Using Org2 identity to Org2 Peer'); - const ccpOrg2 = buildCCPOrg2(); - const caOrg2Client = buildCAClient(FabricCAServices, ccpOrg2, 'ca.org2.example.com'); - - const walletPathOrg2 = path.join(__dirname, 'wallet', 'org2'); - const walletOrg2 = await buildWallet(Wallets, walletPathOrg2); - - await enrollAdmin(caOrg2Client, walletOrg2, org2); - await registerAndEnrollUser(caOrg2Client, walletOrg2, org2, Org2UserId, 'org2.department1'); - - try { - // Create a new gateway for connecting to Org's peer node. - const gatewayOrg2 = new Gateway(); - await gatewayOrg2.connect(ccpOrg2, - { wallet: walletOrg2, identity: Org2UserId, discovery: { enabled: true, asLocalhost: true } }); - - return gatewayOrg2; - } catch (error) { - console.error(`Error in connecting to gateway for Org2: ${error}`); - process.exit(1); - } -} - -function checkAsset(org, assetKey, resultBuffer, value, ownerOrg) { - let asset; - if (resultBuffer) { - asset = JSON.parse(resultBuffer.toString('utf8')); - } - - if (asset && value) { - if (asset.Value === value && asset.OwnerOrg === ownerOrg) { - console.log(`*** Result from ${org} - asset ${asset.ID} has value of ${asset.Value} and owned by ${asset.OwnerOrg}`); - } else { - console.log(`*** Failed from ${org} - asset ${asset.ID} has value of ${asset.Value} and owned by ${asset.OwnerOrg}`); - } - } else if (!asset && value === 0 ) { - console.log(`*** Success from ${org} - asset ${assetKey} does not exist`); - } else { - console.log('*** Failed - asset read failed'); - } -} - -async function readAssetByBothOrgs(assetKey, value, ownerOrg, contractOrg1, contractOrg2) { - if (value) { - console.log(`\n--> Evaluate Transaction: ReadAsset, - ${assetKey} should have a value of ${value} and owned by ${ownerOrg}`); - } else { - console.log(`\n--> Evaluate Transaction: ReadAsset, - ${assetKey} should not exist`); - } - let resultBuffer; - resultBuffer = await contractOrg1.evaluateTransaction('ReadAsset', assetKey); - checkAsset('Org1', assetKey, resultBuffer, value, ownerOrg); - resultBuffer = await contractOrg2.evaluateTransaction('ReadAsset', assetKey); - checkAsset('Org2', assetKey, resultBuffer, value, ownerOrg); -} - -// This application uses fabric-samples/test-network based setup and the companion chaincode -// For this illustration, both Org1 & Org2 client identities will be used, however -// notice they are used by two different "gateway"s to simulate two different running -// applications from two different organizations. -async function main() { - try { - // use a random key so that we can run multiple times - const assetKey = `asset-${Math.floor(Math.random() * 100) + 1}`; - - /** ******* Fabric client init: Using Org1 identity to Org1 Peer ******* */ - const gatewayOrg1 = await initGatewayForOrg1(); - const networkOrg1 = await gatewayOrg1.getNetwork(channelName); - const contractOrg1 = networkOrg1.getContract(chaincodeName); - - /** ******* Fabric client init: Using Org2 identity to Org2 Peer ******* */ - const gatewayOrg2 = await initGatewayForOrg2(); - const networkOrg2 = await gatewayOrg2.getNetwork(channelName); - const contractOrg2 = networkOrg2.getContract(chaincodeName); - - try { - let transaction; - - try { - // Create an asset by organization Org1, this will require that both organization endorse. - // The endorsement will be handled by Discovery, since the gateway was connected with discovery enabled. - console.log(`\n--> Submit Transaction: CreateAsset, ${assetKey} as Org1 - endorsed by Org1 and Org2`); - await contractOrg1.submitTransaction('CreateAsset', assetKey, '100', 'Tom'); - console.log('*** Result: committed, now asset will only require Org1 to endorse'); - } catch (createError) { - console.log(`*** Failed: create - ${createError}`); - process.exit(1); - } - - await readAssetByBothOrgs(assetKey, 100, org1, contractOrg1, contractOrg2); - - try { - // Since the gateway is using discovery we should limit the organizations used by - // discovery to endorse. This way we only have to know the organization and not - // the actual peers that may be active at any given time. - console.log(`\n--> Submit Transaction: UpdateAsset ${assetKey}, as Org1 - endorse by Org1`); - transaction = contractOrg1.createTransaction('UpdateAsset'); - transaction.setEndorsingOrganizations(org1); - await transaction.submit(assetKey, '200'); - console.log('*** Result: committed'); - } catch (updateError) { - console.log(`*** Failed: update - ${updateError}`); - process.exit(1); - } - - await readAssetByBothOrgs(assetKey, 200, org1, contractOrg1, contractOrg2); - - try { - // Submit a transaction to make an update to the asset that has a key-level endorsement policy - // set to only allow Org1 to make updates. The following example will not use the "setEndorsingOrganizations" - // to limit the organizations that will do the endorsement, this means that it will be sent to all - // organizations in the chaincode endorsement policy. When Org1 endorses, the transaction will be committed - // if Org2 endorses or not. - console.log(`\n--> Submit Transaction: UpdateAsset ${assetKey}, as Org1 - endorse by Org1 and Org2`); - transaction = contractOrg1.createTransaction('UpdateAsset'); - await transaction.submit(assetKey, '300'); - console.log('*** Result: committed - because Org1 and Org2 both endorsed, while only the Org1 endorsement was required and checked'); - } catch (updateError) { - console.log(`*** Failed: update - ${updateError}`); - process.exit(1); - } - - await readAssetByBothOrgs(assetKey, 300, org1, contractOrg1, contractOrg2); - - try { - // Again submit the change to both Organizations by not using "setEndorsingOrganizations". Since only - // Org1 is required to approve, the transaction will be committed. - console.log(`\n--> Submit Transaction: UpdateAsset ${assetKey}, as Org2 - endorse by Org1 and Org2`); - transaction = contractOrg2.createTransaction('UpdateAsset'); - await transaction.submit(assetKey, '400'); - console.log('*** Result: committed - because Org1 was on the discovery list, Org2 did not endorse'); - } catch (updateError) { - console.log(`*** Failed: update - ${updateError}`); - process.exit(1); - } - - await readAssetByBothOrgs(assetKey, 400, org1, contractOrg1, contractOrg2); - - try { - // Try to update by sending only to Org2, since the state-based-endorsement says that - // Org1 is the only organization allowed to update, the transaction will fail. - console.log(`\n--> Submit Transaction: UpdateAsset ${assetKey}, as Org2 - endorse by Org2`); - transaction = contractOrg2.createTransaction('UpdateAsset'); - transaction.setEndorsingOrganizations(org2); - await transaction.submit(assetKey, '500'); - console.log('*** Failed: committed - this should have failed to endorse and commit'); - } catch (updateError) { - console.log(`*** Successfully caught the error: \n ${updateError}`); - } - - await readAssetByBothOrgs(assetKey, 400, org1, contractOrg1, contractOrg2); - - try { - // Make a change to the state-based-endorsement policy making Org2 the owner. - console.log(`\n--> Submit Transaction: TransferAsset ${assetKey}, as Org1 - endorse by Org1`); - transaction = contractOrg1.createTransaction('TransferAsset'); - transaction.setEndorsingOrganizations(org1); - await transaction.submit(assetKey, 'Henry', org2); - console.log('*** Result: committed'); - } catch (transferError) { - console.log(`*** Failed: transfer - ${transferError}`); - process.exit(1); - } - - await readAssetByBothOrgs(assetKey, 400, org2, contractOrg1, contractOrg2); - - try { - // Make sure that Org2 can now make updates, notice how the transaction has limited the - // endorsement to only Org2. - console.log(`\n--> Submit Transaction: UpdateAsset ${assetKey}, as Org2 - endorse by Org2`); - transaction = contractOrg2.createTransaction('UpdateAsset'); - transaction.setEndorsingOrganizations(org2); - await transaction.submit(assetKey, '600'); - console.log('*** Result: committed'); - } catch (updateError) { - console.log(`*** Failed: update - ${updateError}`); - process.exit(1); - } - - await readAssetByBothOrgs(assetKey, 600, org2, contractOrg1, contractOrg2); - - try { - // With Org2 now the owner and the state-based-endorsement policy only allowing organization Org2 - // to make updates, a transaction only to Org1 will fail. - console.log(`\n--> Submit Transaction: UpdateAsset ${assetKey}, as Org1 - endorse by Org1`); - transaction = contractOrg1.createTransaction('UpdateAsset'); - transaction.setEndorsingOrganizations(org1); - await transaction.submit(assetKey, '700'); - console.log('*** Failed: committed - this should have failed to endorse and commit'); - } catch (updateError) { - console.log(`*** Successfully caught the error: \n ${updateError}`); - } - - await readAssetByBothOrgs(assetKey, 600, org2, contractOrg1, contractOrg2); - - try { - // With Org2 the owner and the state-based-endorsement policy only allowing organization Org2 - // to make updates, a transaction to delete by Org1 will fail. - console.log(`\n--> Submit Transaction: DeleteAsset ${assetKey}, as Org1 - endorse by Org1`); - transaction = contractOrg1.createTransaction('DeleteAsset'); - transaction.setEndorsingOrganizations(org1); - await transaction.submit(assetKey); - console.log('*** Failed: committed - this should have failed to endorse and commit'); - } catch (updateError) { - console.log(`*** Successfully caught the error: \n ${updateError}`); - } - - try { - // With Org2 the owner and the state-based-endorsement policy only allowing organization Org2 - // to make updates, a transaction to delete by Org2 will succeed. - console.log(`\n--> Submit Transaction: DeleteAsset ${assetKey}, as Org2 - endorse by Org2`); - transaction = contractOrg2.createTransaction('DeleteAsset'); - transaction.setEndorsingOrganizations(org2); - await transaction.submit(assetKey); - console.log('*** Result: committed'); - } catch (deleteError) { - console.log(`*** Failed: delete - ${deleteError}`); - process.exit(1); - } - - // The asset should now be deleted, both orgs should not be able to read it - try { - await readAssetByBothOrgs(assetKey, 0, org2, contractOrg1, contractOrg2); - } catch (readDeleteError) { - console.log(`*** Successfully caught the error: ${readDeleteError}`); - } - - } catch (runError) { - console.error(`Error in transaction: ${runError}`); - if (runError.stack) { - console.error(runError.stack); - } - process.exit(1); - } finally { - // Disconnect from the gateway peer when all work for this client identity is complete - gatewayOrg1.disconnect(); - gatewayOrg2.disconnect(); - } - } catch (error) { - console.error(`Error in setup: ${error}`); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - -main(); diff --git a/asset-transfer-sbe/application-javascript/package.json b/asset-transfer-sbe/application-javascript/package.json deleted file mode 100644 index 09ed4f1d..00000000 --- a/asset-transfer-sbe/application-javascript/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "asset-transfer-sbe", - "version": "1.0.0", - "description": "Asset transfer state based endorsement application implemented in JavaScript", - "engines": { - "node": ">=12", - "npm": ">=5" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "scripts": { - "lint": "eslint *.js" - }, - "dependencies": { - "fabric-ca-client": "^2.2.19", - "fabric-network": "^2.2.19" - }, - "devDependencies": { - "eslint": "^7.32.0" - } -} diff --git a/asset-transfer-sbe/chaincode-java/.gitattributes b/asset-transfer-sbe/chaincode-java/.gitattributes deleted file mode 100644 index 00a51aff..00000000 --- a/asset-transfer-sbe/chaincode-java/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# These are explicitly windows files and should use crlf -*.bat text eol=crlf - diff --git a/asset-transfer-sbe/chaincode-java/.gitignore b/asset-transfer-sbe/chaincode-java/.gitignore deleted file mode 100644 index ae1478ca..00000000 --- a/asset-transfer-sbe/chaincode-java/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -/.classpath -/.gradle/ -/.project -/.settings/ -/bin/ -/build/ diff --git a/asset-transfer-sbe/chaincode-java/build.gradle b/asset-transfer-sbe/chaincode-java/build.gradle deleted file mode 100644 index a788dfc4..00000000 --- a/asset-transfer-sbe/chaincode-java/build.gradle +++ /dev/null @@ -1,86 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -plugins { - id 'com.gradleup.shadow' version '8.3.5' - id 'application' - id 'checkstyle' - id 'jacoco' -} - -group 'org.hyperledger.fabric.samples' -version '1.0-SNAPSHOT' - -dependencies { - implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.+' - implementation 'org.hyperledger.fabric:fabric-protos:0.3.3' - implementation 'com.owlike:genson:1.6' -} - -repositories { - mavenCentral() - maven { - url 'https://jitpack.io' - } -} - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(11) - } -} - -application { - mainClass = 'org.hyperledger.fabric.contract.ContractRouter' -} - -checkstyle { - toolVersion '8.21' - configFile file("config/checkstyle/checkstyle.xml") -} - -checkstyleMain { - source ='src/main/java' -} - -checkstyleTest { - source ='src/test/java' -} - -jacocoTestReport { - dependsOn test -} - -jacocoTestCoverageVerification { - violationRules { - rule { - limit { - minimum = 0.9 - } - } - } - - finalizedBy jacocoTestReport -} - -test { - useJUnitPlatform() - testLogging { - events "passed", "skipped", "failed" - } -} - -shadowJar { - archiveBaseName = 'chaincode' - archiveVersion = '' - archiveClassifier = '' - mergeServiceFiles() - - manifest { - attributes 'Main-Class': 'org.hyperledger.fabric.contract.ContractRouter' - } -} - -check.dependsOn jacocoTestCoverageVerification -installDist.dependsOn check diff --git a/asset-transfer-sbe/chaincode-java/config/checkstyle/checkstyle.xml b/asset-transfer-sbe/chaincode-java/config/checkstyle/checkstyle.xml deleted file mode 100644 index 797da97b..00000000 --- a/asset-transfer-sbe/chaincode-java/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/asset-transfer-sbe/chaincode-java/config/checkstyle/suppressions.xml b/asset-transfer-sbe/chaincode-java/config/checkstyle/suppressions.xml deleted file mode 100644 index 8c44b0a0..00000000 --- a/asset-transfer-sbe/chaincode-java/config/checkstyle/suppressions.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/asset-transfer-sbe/chaincode-java/gradle/wrapper/gradle-wrapper.jar b/asset-transfer-sbe/chaincode-java/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index d64cd491..00000000 Binary files a/asset-transfer-sbe/chaincode-java/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/asset-transfer-sbe/chaincode-java/gradle/wrapper/gradle-wrapper.properties b/asset-transfer-sbe/chaincode-java/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e2847c82..00000000 --- a/asset-transfer-sbe/chaincode-java/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/asset-transfer-sbe/chaincode-java/gradlew b/asset-transfer-sbe/chaincode-java/gradlew deleted file mode 100755 index 1aa94a42..00000000 --- a/asset-transfer-sbe/chaincode-java/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/asset-transfer-sbe/chaincode-java/gradlew.bat b/asset-transfer-sbe/chaincode-java/gradlew.bat deleted file mode 100644 index 25da30db..00000000 --- a/asset-transfer-sbe/chaincode-java/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/asset-transfer-sbe/chaincode-java/settings.gradle b/asset-transfer-sbe/chaincode-java/settings.gradle deleted file mode 100644 index e435c090..00000000 --- a/asset-transfer-sbe/chaincode-java/settings.gradle +++ /dev/null @@ -1,5 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -rootProject.name = 'sbe' diff --git a/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/Asset.java b/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/Asset.java deleted file mode 100644 index ca14959d..00000000 --- a/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/Asset.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.sbe; - -import com.owlike.genson.annotation.JsonProperty; -import org.hyperledger.fabric.contract.annotation.DataType; -import org.hyperledger.fabric.contract.annotation.Property; - -import java.util.Objects; - -@DataType() -public final class Asset { - - @Property() - private final String ID; - - @Property() - private int Value; - - @Property() - private String Owner; - - @Property() - private String OwnerOrg; - - @JsonProperty("ID") - public String getID() { - return ID; - } - - @JsonProperty("Value") - public int getValue() { - return Value; - } - - public void setValue(final int Value) { - this.Value = Value; - } - - @JsonProperty("Owner") - public String getOwner() { - return Owner; - } - - public void setOwner(final String Owner) { - this.Owner = Owner; - } - - @JsonProperty("OwnerOrg") - public String getOwnerOrg() { - return OwnerOrg; - } - - public void setOwnerOrg(final String OwnerOrg) { - this.OwnerOrg = OwnerOrg; - } - - public Asset(@JsonProperty("ID") final String ID, @JsonProperty("Value") final int Value, - @JsonProperty("Owner") final String Owner, @JsonProperty("OwnerOrg") final String OwnerOrg) { - this.ID = ID; - this.Value = Value; - this.Owner = Owner; - this.OwnerOrg = OwnerOrg; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Asset asset = (Asset) o; - return getValue() == asset.getValue() - && - getID().equals(asset.getID()) - && - getOwner().equals(asset.getOwner()) - && - getOwnerOrg().equals(asset.getOwnerOrg()); - } - - @Override - public int hashCode() { - return Objects.hash(getID(), getValue(), getOwner(), getOwnerOrg()); - } - - @Override - public String toString() { - return "Asset{" + "ID='" + ID + '\'' + ", Value=" + Value + ", Owner='" - + Owner + '\'' + ", OwnerOrg='" + OwnerOrg + '\'' + '}'; - } -} diff --git a/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/AssetContract.java b/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/AssetContract.java deleted file mode 100644 index 62b286b0..00000000 --- a/asset-transfer-sbe/chaincode-java/src/main/java/org/hyperledger/fabric/samples/sbe/AssetContract.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.sbe; - -import com.owlike.genson.Genson; -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.contract.ContractInterface; -import org.hyperledger.fabric.contract.annotation.Contract; -import org.hyperledger.fabric.contract.annotation.Default; -import org.hyperledger.fabric.contract.annotation.Info; -import org.hyperledger.fabric.contract.annotation.License; -import org.hyperledger.fabric.contract.annotation.Transaction; -import org.hyperledger.fabric.protos.common.MSPPrincipal; -import org.hyperledger.fabric.protos.common.MSPRole; -import org.hyperledger.fabric.protos.common.SignaturePolicy; -import org.hyperledger.fabric.protos.common.SignaturePolicyEnvelope; -import org.hyperledger.fabric.shim.ChaincodeException; -import org.hyperledger.fabric.shim.ChaincodeStub; -import org.hyperledger.fabric.shim.ext.sbe.StateBasedEndorsement; -import org.hyperledger.fabric.shim.ext.sbe.impl.StateBasedEndorsementFactory; - -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -@Contract( - name = "sbe", - info = @Info( - title = "Asset Contract", - description = "Asset Transfer Smart Contract, using State Based Endorsement(SBE), implemented in Java", - version = "0.0.1-SNAPSHOT", - license = @License( - name = "Apache 2.0 License", - url = "http://www.apache.org/licenses/LICENSE-2.0.html"))) -@Default -public final class AssetContract implements ContractInterface { - private final Genson genson = new Genson(); - - private enum AssetTransferErrors { - ASSET_NOT_FOUND, - ASSET_ALREADY_EXISTS - } - - /** - * Creates a new asset. - * Sets the endorsement policy of the assetId Key, such that current owner Org Peer is required to endorse future updates. - * Optionally, set the endorsement policy of the assetId Key, such that any 1(N) out of the Org's specified can endorse future updates. - * - * @param ctx the transaction context - * @param assetId the id of the new asset - * @param value the value of the new asset - * @param owner the owner of the new asset - * @return the created asset - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public Asset CreateAsset(final Context ctx, final String assetId, final int value, final String owner) { - ChaincodeStub stub = ctx.getStub(); - - if (AssetExists(ctx, assetId)) { - String errorMessage = String.format("Asset %s already exists", assetId); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_ALREADY_EXISTS.toString()); - } - - final String ownerOrg = getClientOrgId(ctx); - Asset asset = new Asset(assetId, value, owner, ownerOrg); - String assetJSON = genson.serialize(asset); - stub.putStringState(assetId, assetJSON); - - // Set the endorsement policy of the assetId Key, such that current owner Org is required to endorse future updates - setStateBasedEndorsement(ctx, assetId, List.of(ownerOrg)); - - // Optionally, set the endorsement policy of the assetId Key, such that any 1 Org (N) out of the specified Orgs can endorse future updates - // setStateBasedEndorsementNOutOf(ctx, assetId, 1, new String[]{"Org1MSP", "Org2MSP"}); - - return asset; - } - - /** - * Retrieves an asset with the given assetId. - * - * @param ctx the transaction context - * @param assetId the id of the asset - * @return the asset found on the ledger if there was one - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public String ReadAsset(final Context ctx, final String assetId) { - ChaincodeStub stub = ctx.getStub(); - String assetJSON = stub.getStringState(assetId); - - if (assetJSON == null || assetJSON.isEmpty()) { - String errorMessage = String.format("Asset %s does not exist", assetId); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - - return assetJSON; - } - - /** - * Updates the properties of an existing asset. - * Needs an endorsement of current owner Org Peer. - * - * @param ctx the transaction context - * @param assetId the id of the asset being updated - * @param newValue the value of the asset being updated - * @return the updated asset - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public Asset UpdateAsset(final Context ctx, final String assetId, final int newValue) { - ChaincodeStub stub = ctx.getStub(); - - String assetString = ReadAsset(ctx, assetId); - Asset asset = genson.deserialize(assetString, Asset.class); - asset.setValue(newValue); - String updatedAssetJSON = genson.serialize(asset); - stub.putStringState(assetId, updatedAssetJSON); - - return asset; - } - - /** - * Deletes the given asset. - * Needs an endorsement of current owner Org Peer. - * - * @param ctx the transaction context - * @param assetId the id of the asset being deleted - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public void DeleteAsset(final Context ctx, final String assetId) { - ChaincodeStub stub = ctx.getStub(); - - if (!AssetExists(ctx, assetId)) { - String errorMessage = String.format("Asset %s does not exist", assetId); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - - stub.delState(assetId); - } - - /** - * Updates the owner & ownerOrg field of asset with given assetId, ownerOrg must be a valid Org MSP Id. - * Needs an endorsement of current owner Org Peer. - * Re-sets the endorsement policy of the assetId Key, such that new owner Org Peer is required to endorse future updates. - * - * @param ctx the transaction context - * @param assetId the id of the asset being transferred - * @param newOwner the new owner - * @param newOwnerOrg the new owner Org MSPID - * @return the updated asset - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public Asset TransferAsset(final Context ctx, final String assetId, final String newOwner, final String newOwnerOrg) { - ChaincodeStub stub = ctx.getStub(); - - String assetString = ReadAsset(ctx, assetId); - Asset asset = genson.deserialize(assetString, Asset.class); - asset.setOwner(newOwner); - asset.setOwnerOrg(newOwnerOrg); - String updatedAssetJSON = genson.serialize(asset); - stub.putStringState(assetId, updatedAssetJSON); - - // Re-Set the endorsement policy of the assetId Key, such that a new owner Org Peer is required to endorse future updates - setStateBasedEndorsement(ctx, assetId, List.of(newOwnerOrg)); - - // Optionally, set the endorsement policy of the assetId Key, such that any 1 Org (N) out of the specified Orgs can endorse future updates - // setStateBasedEndorsementNOutOf(ctx, assetId, 1, List.of("Org1MSP", "Org2MSP")); - - return asset; - } - - /** - * Checks the existence of the asset. - * - * @param ctx the transaction context - * @param assetId the id of the asset - * @return boolean indicating the existence of the asset - */ - private boolean AssetExists(final Context ctx, final String assetId) { - ChaincodeStub stub = ctx.getStub(); - String assetJSON = stub.getStringState(assetId); - - return (assetJSON != null && !assetJSON.isEmpty()); - } - - /** - * Retrieves the client's OrgId (MSPID) - * - * @param ctx the transaction context - * @return String value of the Org MSPID - */ - private static String getClientOrgId(final Context ctx) { - return ctx.getClientIdentity().getMSPID(); - } - - /** - * Sets an endorsement policy to the assetId Key. - * Enforces that the owner Org must endorse future update transactions for the specified assetId Key. - * - * @param ctx the transaction context - * @param assetId the id of the asset - * @param ownerOrgs the list of Owner Org MSPID's - */ - private static void setStateBasedEndorsement(final Context ctx, final String assetId, final List ownerOrgs) { - StateBasedEndorsement stateBasedEndorsement = StateBasedEndorsementFactory.getInstance().newStateBasedEndorsement(null); - stateBasedEndorsement.addOrgs(StateBasedEndorsement.RoleType.RoleTypeMember, ownerOrgs.toArray(new String[0])); - ctx.getStub().setStateValidationParameter(assetId, stateBasedEndorsement.policy()); - } - - /** - * Sets an endorsement policy to the assetId Key. - * Enforces that a given number of Orgs (N) out of the specified Orgs must endorse future update transactions for the specified assetId Key. - * - * @param ctx the transaction context - * @param assetId the id of the asset - * @param nOrgs the number of N Orgs to endorse out of the list of Orgs provided - * @param ownerOrgs the list of Owner Org MSPID's - */ - private static void setStateBasedEndorsementNOutOf(final Context ctx, final String assetId, final int nOrgs, final List ownerOrgs) { - ctx.getStub().setStateValidationParameter(assetId, policy(nOrgs, ownerOrgs)); - } - - /** - * Create a policy that requires a given number (N) of Org principals signatures out of the provided list of Orgs - * - * @param nOrgs the number of Org principals signatures required to endorse (out of the provided list of Orgs) - * @param mspIds the list of Owner Org MSPID's - */ - private static byte[] policy(final int nOrgs, final List mspIds) { - mspIds.sort(Comparator.naturalOrder()); - - var principals = mspIds.stream() - .map(mspId -> MSPRole.newBuilder() - .setMspIdentifier(mspId) - .setRole(MSPRole.MSPRoleType.MEMBER) - .build()) - .map(role -> MSPPrincipal.newBuilder() - .setPrincipalClassification(MSPPrincipal.Classification.ROLE) - .setPrincipal(role.toByteString()) - .build()) - .collect(Collectors.toList()); - - var signPolicy = IntStream.range(0, mspIds.size()) - .mapToObj(AssetContract::signedBy) - .collect(Collectors.toList()); - - // Create the policy such that it requires any N signature's from all the principals provided - return SignaturePolicyEnvelope.newBuilder() - .setVersion(0) - .setRule(nOutOf(nOrgs, signPolicy)) - .addAllIdentities(principals) - .build() - .toByteArray(); - } - - private static SignaturePolicy signedBy(final int index) { - return SignaturePolicy.newBuilder().setSignedBy(index).build(); - } - - private static SignaturePolicy nOutOf(final int n, final List policies) { - return SignaturePolicy.newBuilder().setNOutOf( - SignaturePolicy.NOutOf.newBuilder().setN(n).addAllRules(policies).build() - ).build(); - } -} diff --git a/asset-transfer-sbe/chaincode-typescript/.gitignore b/asset-transfer-sbe/chaincode-typescript/.gitignore deleted file mode 100644 index 2a76b3d8..00000000 --- a/asset-transfer-sbe/chaincode-typescript/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -# Coverage directory used by tools like istanbul -coverage - -# Dependency directories -node_modules/ -jspm_packages/ -package-lock.json - -# Compiled TypeScript files -dist - -# Editor Config -.editorconfig - -# npm ignore -.npmignore diff --git a/asset-transfer-sbe/chaincode-typescript/eslint.config.mjs b/asset-transfer-sbe/chaincode-typescript/eslint.config.mjs deleted file mode 100644 index 9ef6b243..00000000 --- a/asset-transfer-sbe/chaincode-typescript/eslint.config.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import js from '@eslint/js'; -import tseslint from 'typescript-eslint'; - -export default tseslint.config(js.configs.recommended, ...tseslint.configs.strictTypeChecked, { - languageOptions: { - ecmaVersion: 2023, - sourceType: 'module', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: import.meta.dirname, - }, - }, -}); diff --git a/asset-transfer-sbe/chaincode-typescript/npm-shrinkwrap.json b/asset-transfer-sbe/chaincode-typescript/npm-shrinkwrap.json deleted file mode 100644 index 8ddcd6ac..00000000 --- a/asset-transfer-sbe/chaincode-typescript/npm-shrinkwrap.json +++ /dev/null @@ -1,2205 +0,0 @@ -{ - "name": "asset-transfer-sbe", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "asset-transfer-sbe", - "version": "0.0.1", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "~2.5", - "fabric-shim": "~2.5" - }, - "devDependencies": { - "@eslint/js": "^9.3.0", - "@tsconfig/node18": "^18.2.4", - "@types/node": "^18.19.33", - "eslint": "^8.57.0", - "typescript": "~5.4.5", - "typescript-eslint": "^7.11.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.5.0.tgz", - "integrity": "sha512-A7+AOT2ICkodvtsWnxZP4Xxk3NbZ3VMHd8oihydLRGrJgqqdEz1qSeEgXYyT/Cu8h1TWWsQRejIx48mtjZ5y1w==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@fidm/asn1": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@fidm/asn1/-/asn1-1.0.4.tgz", - "integrity": "sha512-esd1jyNvRb2HVaQGq2Gg8Z0kbQPXzV9Tq5Z14KNIov6KfFD6PTaRIO8UpcsYiTNzOqJpmyzWgVTrUwFV3UF4TQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@fidm/x509": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@fidm/x509/-/x509-1.2.1.tgz", - "integrity": "sha512-nwc2iesjyc9hkuzcrMCBXQRn653XuAUKorfWM8PZyJawiy1QzLj4vahwzaI25+pfpwOLvMzbJ0uKpWLDNmo16w==", - "dependencies": { - "@fidm/asn1": "^1.0.4", - "tweetnacl": "^1.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.10.9", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.9.tgz", - "integrity": "sha512-5tcgUctCG0qoNyfChZifz2tJqbRbXVO9J7X6duFcOjY3HUNCxg5D0ZCK7EP9vIcZ0zRpLU9bWkyCqVCLZ46IbQ==", - "dependencies": { - "@grpc/proto-loader": "^0.7.13", - "@js-sdsl/ordered-map": "^4.4.2" - }, - "engines": { - "node": ">=12.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@hyperledger/fabric-protos": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@hyperledger/fabric-protos/-/fabric-protos-0.2.1.tgz", - "integrity": "sha512-qjm0vIQIfCall804tWDeA8p/mUfu14sl5Sj+PbOn2yDKJq+7ThoIhNsLAqf+BCxUfqsoqQq6AojhqQeTFyOOqg==", - "dependencies": { - "@grpc/grpc-js": "^1.9.0", - "google-protobuf": "^3.21.0" - }, - "engines": { - "node": ">=14.15.0" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@tsconfig/node18": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node18/-/node18-18.2.4.tgz", - "integrity": "sha512-5xxU8vVs9/FNcvm3gE07fPbn9tl6tqGGWA9tSlwsUEkBxtRnTsNmwrV8gasZ9F/EobaSv9+nu8AxUKccw77JpQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.19.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.34.tgz", - "integrity": "sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/triple-beam": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.0.tgz", - "integrity": "sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.13.0", - "@typescript-eslint/type-utils": "7.13.0", - "@typescript-eslint/utils": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.0.tgz", - "integrity": "sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "7.13.0", - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/typescript-estree": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz", - "integrity": "sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.0.tgz", - "integrity": "sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "7.13.0", - "@typescript-eslint/utils": "7.13.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz", - "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz", - "integrity": "sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.0.tgz", - "integrity": "sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.13.0", - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/typescript-estree": "7.13.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz", - "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/class-transformer": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", - "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==" - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fabric-contract-api": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-contract-api/-/fabric-contract-api-2.5.6.tgz", - "integrity": "sha512-AosGb8tA+Jgt+pqMEgYNB3/J/P5QuWOC7yhXbhDmAAwUzn4Sc7pdWDICH1YyrFGZNFxMGQmqJmLVWUX8BKHy0w==", - "dependencies": { - "class-transformer": "^0.4.0", - "fabric-shim-api": "2.5.6", - "fast-safe-stringify": "^2.1.1", - "get-params": "^0.1.2", - "reflect-metadata": "^0.1.13", - "winston": "^3.7.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fabric-shim": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-shim/-/fabric-shim-2.5.6.tgz", - "integrity": "sha512-4Y8WNFhYuQ9QYSEgPXWdlXnrXjwOlM10sQQzE4kJ7cDh8a4LX0rn44FxtxTCB18lnzrSLMZ8/8Cr5m0c9NeXWA==", - "dependencies": { - "@fidm/x509": "^1.2.1", - "@grpc/grpc-js": "~1.10.9", - "@hyperledger/fabric-protos": "~0.2.1", - "@types/node": "^16.11.1", - "ajv": "^6.12.2", - "fabric-contract-api": "2.5.6", - "fabric-shim-api": "2.5.6", - "fast-safe-stringify": "^2.1.1", - "long": "^5.2.3", - "reflect-metadata": "^0.1.13", - "winston": "^3.7.2", - "yargs": "^17.4.0", - "yargs-parser": "^21.0.1" - }, - "bin": { - "fabric-chaincode-node": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fabric-shim-api": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-shim-api/-/fabric-shim-api-2.5.6.tgz", - "integrity": "sha512-1L0nO7CJ31/gEOWKWHEeCqgB5HkqPVfRbpcS7L9eTscT7tffjg2OkZISvC+a7RiqihL0iyrXNBgBg5MwlSSN9g==", - "engines": { - "eslint": "^6.6.0", - "node": ">=18" - } - }, - "node_modules/fabric-shim/node_modules/@types/node": { - "version": "16.18.98", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.98.tgz", - "integrity": "sha512-fpiC20NvLpTLAzo3oVBKIqBGR6Fx/8oAK/SSf7G+fydnXMY1x4x9RZ6sBXhqKlCU21g2QapUsbLlhv3+a7wS+Q==" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-params": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/get-params/-/get-params-0.1.2.tgz", - "integrity": "sha512-41eOxtlGgHQRbFyA8KTH+w+32Em3cRdfBud7j67ulzmIfmaHX9doq47s0fa4P5o9H64BZX9nrYI6sJvk46Op+Q==" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/google-protobuf": { - "version": "3.21.2", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz", - "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/logform": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", - "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", - "dependencies": { - "@colors/colors": "1.6.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/protobufjs": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.2.tgz", - "integrity": "sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/reflect-metadata": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", - "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==" - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "engines": { - "node": "*" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/triple-beam": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", - "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.13.0.tgz", - "integrity": "sha512-upO0AXxyBwJ4BbiC6CRgAJKtGYha2zw4m1g7TIVPSonwYEuf7vCicw3syjS1OxdDMTz96sZIXl3Jx3vWJLLKFw==", - "dev": true, - "dependencies": { - "@typescript-eslint/eslint-plugin": "7.13.0", - "@typescript-eslint/parser": "7.13.0", - "@typescript-eslint/utils": "7.13.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/winston": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.0.tgz", - "integrity": "sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==", - "dependencies": { - "@colors/colors": "^1.6.0", - "@dabh/diagnostics": "^2.0.2", - "async": "^3.2.3", - "is-stream": "^2.0.0", - "logform": "^2.4.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "safe-stable-stringify": "^2.3.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/winston-transport": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", - "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", - "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/asset-transfer-sbe/chaincode-typescript/package.json b/asset-transfer-sbe/chaincode-typescript/package.json deleted file mode 100644 index 4ce6b7c3..00000000 --- a/asset-transfer-sbe/chaincode-typescript/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "asset-transfer-sbe", - "version": "0.0.1", - "description": "Asset Transfer contract, using State Based Endorsement(SBE), implemented in TypeScript", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "engines": { - "node": ">=18" - }, - "scripts": { - "lint": "eslint src", - "pretest": "npm run lint", - "test": "echo 'No tests implemented'", - "start": "fabric-chaincode-node start", - "build": "tsc", - "build:watch": "tsc -w", - "prepublishOnly": "npm run build", - "postinstall": "npm dedupe" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "~2.5", - "fabric-shim": "~2.5" - }, - "devDependencies": { - "@types/node": "^18.19.33", - "@eslint/js": "^9.3.0", - "@tsconfig/node18": "^18.2.4", - "eslint": "^8.57.0", - "typescript": "~5.4.5", - "typescript-eslint": "^7.11.0" -} -} diff --git a/asset-transfer-sbe/chaincode-typescript/src/asset.ts b/asset-transfer-sbe/chaincode-typescript/src/asset.ts deleted file mode 100644 index 272d6baf..00000000 --- a/asset-transfer-sbe/chaincode-typescript/src/asset.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Object, Property } from 'fabric-contract-api'; - -@Object() -export class Asset { - @Property() - public ID: string = ''; - - @Property() - public Value: number = 0; - - @Property() - public Owner: string = ''; - - @Property() - public OwnerOrg: string = ''; -} diff --git a/asset-transfer-sbe/chaincode-typescript/src/assetContract.ts b/asset-transfer-sbe/chaincode-typescript/src/assetContract.ts deleted file mode 100644 index 019b9b19..00000000 --- a/asset-transfer-sbe/chaincode-typescript/src/assetContract.ts +++ /dev/null @@ -1,121 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Context, Contract, Info, Transaction } from 'fabric-contract-api'; -import { Asset } from './asset'; -import { KeyEndorsementPolicy } from 'fabric-shim'; - -@Info({title: 'AssetContract', description: 'Asset Transfer Smart Contract, using State Based Endorsement(SBE), implemented in TypeScript' }) -export class AssetContract extends Contract { - // CreateAsset creates a new asset - // CreateAsset sets the endorsement policy of the assetId Key, such that current owner Org Peer is required to endorse future updates - @Transaction() - public async CreateAsset(ctx: Context, assetId: string, value: number, owner: string): Promise { - const exists = await this.AssetExists(ctx, assetId); - if (exists) { - throw new Error(`The asset ${assetId} already exists`); - } - const ownerOrg = AssetContract.getClientOrgId(ctx); - const asset = new Asset(); - asset.ID = assetId; - asset.Value = value; - asset.Owner = owner; - asset.OwnerOrg = ownerOrg; - const buffer = Buffer.from(JSON.stringify(asset)); - // Create the asset - await ctx.stub.putState(assetId, buffer); - - // Set the endorsement policy of the assetId Key, such that current owner Org is required to endorse future updates - await AssetContract.setStateBasedEndorsement(ctx, assetId, [ownerOrg]); - - // Optionally, set the endorsement policy of the assetId Key, such that any 1 Org (N) out of the specified Orgs can endorse future updates - // await AssetContract.setStateBasedEndorsementNOutOf(ctx, assetId, 1, ["Org1MSP", "Org2MSP"]); - } - - // ReadAsset returns asset with given assetId - @Transaction(false) - public async ReadAsset(ctx: Context, assetId: string): Promise { - const exists = await this.AssetExists(ctx, assetId); - if (!exists) { - throw new Error(`The asset ${assetId} does not exist`); - } - // Read the asset - const assetJSON = await ctx.stub.getState(assetId); - return assetJSON.toString(); - } - - // UpdateAsset updates an existing asset - // UpdateAsset needs an endorsement of current owner Org Peer - @Transaction() - public async UpdateAsset(ctx: Context, assetId: string, newValue: number): Promise { - const assetString = await this.ReadAsset(ctx, assetId); - const asset = JSON.parse(assetString) as Asset; - asset.Value = newValue; - const buffer = Buffer.from(JSON.stringify(asset)); - // Update the asset - await ctx.stub.putState(assetId, buffer); - } - - // DeleteAsset deletes an given asset - // DeleteAsset needs an endorsement of current owner Org Peer - @Transaction() - public async DeleteAsset(ctx: Context, assetId: string): Promise { - const exists = await this.AssetExists(ctx, assetId); - if (!exists) { - throw new Error(`The asset ${assetId} does not exist`); - } - // Delete the asset - await ctx.stub.deleteState(assetId); - } - - // TransferAsset updates the Owner & OwnerOrg field of asset with given assetId, OwnerOrg must be a valid Org MSP Id - // TransferAsset needs an endorsement of current owner Org Peer - // TransferAsset re-sets the endorsement policy of the assetId Key, such that new owner Org Peer is required to endorse future updates - @Transaction() - public async TransferAsset(ctx: Context, assetId: string, newOwner: string, newOwnerOrg: string): Promise { - const assetString = await this.ReadAsset(ctx, assetId); - const asset = JSON.parse(assetString) as Asset; - asset.Owner = newOwner; - asset.OwnerOrg = newOwnerOrg; - // Update the asset - await ctx.stub.putState(assetId, Buffer.from(JSON.stringify(asset))); - // Re-Set the endorsement policy of the assetId Key, such that a new owner Org Peer is required to endorse future updates - await AssetContract.setStateBasedEndorsement(ctx, asset.ID, [newOwnerOrg]); - - // Optionally, set the endorsement policy of the assetId Key, such that any 1 Org (N) out of the specified Orgs can endorse future updates - // await AssetContract.setStateBasedEndorsementNOutOf(ctx, assetId, 1, ["Org1MSP", "Org2MSP"]); - } - - // AssetExists returns true when asset with given ID exists - public async AssetExists(ctx: Context, assetId: string): Promise { - const buffer = await ctx.stub.getState(assetId); - return buffer.length > 0; - } - - // getClientOrgId gets the client's OrgId (MSPID) - private static getClientOrgId(ctx: Context): string { - return ctx.clientIdentity.getMSPID(); - } - - // setStateBasedEndorsement sets an endorsement policy to the assetId Key - // setStateBasedEndorsement enforces that the owner Org must endorse future update transactions for the specified assetId Key - private static async setStateBasedEndorsement(ctx: Context, assetId: string, ownerOrgs: string[]): Promise { - const ep = new KeyEndorsementPolicy(); - ep.addOrgs('MEMBER', ...ownerOrgs); - await ctx.stub.setStateValidationParameter(assetId, ep.getPolicy()); - } - - // setStateBasedEndorsementNOutOf sets an endorsement policy to the assetId Key - // setStateBasedEndorsementNOutOf enforces that a given number of Orgs (N) out of the specified Orgs must endorse future update transactions for the specified assetId Key. - private static async setStateBasedEndorsementNOutOf(ctx: Context, assetId: string, nOrgs: number, ownerOrgs: string[]): Promise { - const ROLE_TYPE_MEMBER = 'MEMBER'; - - // Use the KeyEndorsementPolicy helper form the chaincode libarries - // If you need more advanced policies, please use that helper as a reference point. - const keyEndorsementPolicy = new KeyEndorsementPolicy(); - keyEndorsementPolicy.addOrgs(ROLE_TYPE_MEMBER, ...ownerOrgs); - - await ctx.stub.setStateValidationParameter(assetId, keyEndorsementPolicy.getPolicy()); - } -} diff --git a/asset-transfer-sbe/chaincode-typescript/src/index.ts b/asset-transfer-sbe/chaincode-typescript/src/index.ts deleted file mode 100644 index 412fda46..00000000 --- a/asset-transfer-sbe/chaincode-typescript/src/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -import { AssetContract } from './assetContract'; -export { AssetContract } from './assetContract'; - -export const contracts: unknown[] = [ AssetContract ]; diff --git a/asset-transfer-sbe/chaincode-typescript/tsconfig.json b/asset-transfer-sbe/chaincode-typescript/tsconfig.json deleted file mode 100644 index 031d7de7..00000000 --- a/asset-transfer-sbe/chaincode-typescript/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@tsconfig/node18/tsconfig.json", - "compilerOptions": { - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "outDir": "dist", - "strict": true, - "noUnusedLocals": true, - "noImplicitReturns": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["src/"] -} diff --git a/asset-transfer-secured-agreement/README.md b/asset-transfer-secured-agreement/README.md deleted file mode 100644 index 83e4c2fc..00000000 --- a/asset-transfer-secured-agreement/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# Asset transfer secured agreement sample - -The asset transfer events sample demonstrates how to transfer a private asset between two organizations without publicly sharing data . - -## About the sample - -This sample includes smart contract and application code in multiple languages. This sample shows how Fabric features state based endorsement, private data, and access control to provide secured transactions. - -### Application - -Refer [Secured asset transfer in Fabric](https://hyperledger-fabric.readthedocs.io/en/latest/secured_asset_transfer/secured_private_asset_transfer_tutorial.html) for application details . - -### Smart Contract - -The smart contract (in folder `chaincode-go`) implements the following functions to support the application: - -- CreateAsset -- ChangePublicDescription -- AgreeToSell -- AgreeToBuy -- VerifyAssetProperties -- TransferAsset -- ReadAsset -- GetAssetPrivateProperties -- GetAssetSalesPrice -- GetAssetBidPrice -- GetAssetHashId -- QueryAssetSaleAgreements -- QueryAssetBuyAgreements -- QueryAssetHistory - -## Running the sample - -Like other samples, the Fabric test network is used to deploy and run this sample. Follow these steps in order: - -1. Create the test network and a channel (from the `test-network` folder). - ``` - ./network.sh up createChannel -c mychannel -ca - ``` - -1. Deploy the smart contract implementations. - ``` - # To deploy the go chaincode implementation - ./network.sh deployCC -ccn secured -ccp ../asset-transfer-secured-agreement/chaincode-go/ -ccl go -ccep "OR('Org1MSP.peer','Org2MSP.peer')" - ``` - -1. Run the application (from the `asset-transfer-secured-agreement` folder). - ``` - # To run the Typescript sample application - cd application-gateway-typescript - npm install - npm start - ``` - -## Clean up - -When you are finished, you can bring down the test network (from the `test-network` folder). The command will remove all the nodes of the test network, and delete any ledger data that you created. - -``` -./network.sh down -``` \ No newline at end of file diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/.gitignore b/asset-transfer-secured-agreement/application-gateway-typescript/.gitignore deleted file mode 100644 index 99e5af9f..00000000 --- a/asset-transfer-secured-agreement/application-gateway-typescript/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - - -# Coverage directory used by tools like istanbul -coverage - -# Dependency directories -node_modules/ -jspm_packages/ - -# Compiled TypeScript files -dist diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/eslint.config.mjs b/asset-transfer-secured-agreement/application-gateway-typescript/eslint.config.mjs deleted file mode 100644 index 9ef6b243..00000000 --- a/asset-transfer-secured-agreement/application-gateway-typescript/eslint.config.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import js from '@eslint/js'; -import tseslint from 'typescript-eslint'; - -export default tseslint.config(js.configs.recommended, ...tseslint.configs.strictTypeChecked, { - languageOptions: { - ecmaVersion: 2023, - sourceType: 'module', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: import.meta.dirname, - }, - }, -}); diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/package.json b/asset-transfer-secured-agreement/application-gateway-typescript/package.json deleted file mode 100644 index adcec840..00000000 --- a/asset-transfer-secured-agreement/application-gateway-typescript/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "asset-transfer-basic", - "version": "1.0.0", - "description": "Asset Transfer Secured Agreement Application implemented in typeScript using fabric-gateway", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "engines": { - "node": ">=18" - }, - "scripts": { - "build": "tsc", - "build:watch": "tsc -w", - "lint": "eslint src", - "prepare": "npm run build", - "pretest": "npm run lint", - "start": "node dist/app.js" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "@grpc/grpc-js": "^1.12.2", - "@hyperledger/fabric-gateway": "^1.7.0" - }, - "devDependencies": { - "@eslint/js": "^9.3.0", - "@tsconfig/node18": "^18.2.2", - "@types/node": "^18.18.6", - "eslint": "^8.57.0", - "typescript": "~5.4", - "typescript-eslint": "^7.13.0" - } -} diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/src/app.ts b/asset-transfer-secured-agreement/application-gateway-typescript/src/app.ts deleted file mode 100644 index 14aa27ca..00000000 --- a/asset-transfer-secured-agreement/application-gateway-typescript/src/app.ts +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { connect, hash } from '@hyperledger/fabric-gateway'; - -import { newGrpcConnection, newIdentity, newSigner, tlsCertPathOrg1, peerEndpointOrg1, peerNameOrg1, certDirectoryPathOrg1, mspIdOrg1, keyDirectoryPathOrg1, tlsCertPathOrg2, peerEndpointOrg2, peerNameOrg2, certDirectoryPathOrg2, mspIdOrg2, keyDirectoryPathOrg2 } from './connect'; -import { ContractWrapper } from './contractWrapper'; -import { RED, RESET } from './utils'; - -const channelName = 'mychannel'; -const chaincodeName = 'secured'; - -// Use a random key so that we can run multiple times -const now = Date.now().toString(); -let assetKey: string; - -async function main(): Promise { - - // The gRPC client connection from org1 should be shared by all Gateway connections to this endpoint. - const clientOrg1 = await newGrpcConnection( - tlsCertPathOrg1, - peerEndpointOrg1, - peerNameOrg1 - ); - - const gatewayOrg1 = connect({ - client: clientOrg1, - identity: await newIdentity(certDirectoryPathOrg1, mspIdOrg1), - signer: await newSigner(keyDirectoryPathOrg1), - hash: hash.sha256, - }); - - // The gRPC client connection from org2 should be shared by all Gateway connections to this endpoint. - const clientOrg2 = await newGrpcConnection( - tlsCertPathOrg2, - peerEndpointOrg2, - peerNameOrg2 - ); - - const gatewayOrg2 = connect({ - client: clientOrg2, - identity: await newIdentity(certDirectoryPathOrg2, mspIdOrg2), - signer: await newSigner(keyDirectoryPathOrg2), - hash: hash.sha256, - }); - - - try { - - // Get the smart contract from the network for Org1. - const contractOrg1 = gatewayOrg1.getNetwork(channelName).getContract(chaincodeName); - const contractWrapperOrg1 = new ContractWrapper(contractOrg1, mspIdOrg1); - - // Get the smart contract from the network for Org2. - const contractOrg2 = gatewayOrg2.getNetwork(channelName).getContract(chaincodeName); - const contractWrapperOrg2 = new ContractWrapper(contractOrg2, mspIdOrg2); - - // Create an asset by organization Org1, this only requires the owning organization to endorse. - assetKey = await contractWrapperOrg1.createAsset(mspIdOrg1, - `Asset owned by ${mspIdOrg1} is not for sale`, { ObjectType: 'asset_properties', Color: 'blue', Size: 35 }); - - // Read the public details by org1. - await contractWrapperOrg1.readAsset(assetKey, mspIdOrg1); - - // Read the public details by org2. - await contractWrapperOrg2.readAsset(assetKey, mspIdOrg1); - - // Org1 should be able to read the private data details of the asset. - await contractWrapperOrg1.getAssetPrivateProperties(assetKey, mspIdOrg1); - - // Org2 is not the owner and does not have the private details, read expected to fail. - try { - await contractWrapperOrg2.getAssetPrivateProperties(assetKey, mspIdOrg1); - } catch (e) { - console.log(`${RED}*** Successfully caught the failure: getAssetPrivateProperties - ${String(e)}${RESET}`); - } - - // Org1 updates the assets public description. - await contractWrapperOrg1.changePublicDescription({assetId: assetKey, - ownerOrg: mspIdOrg1, - publicDescription: `Asset ${assetKey} owned by ${mspIdOrg1} is for sale`}); - - // Read the public details by org1. - await contractWrapperOrg1.readAsset(assetKey, mspIdOrg1); - - // Read the public details by org2. - await contractWrapperOrg2.readAsset(assetKey, mspIdOrg1); - - // This is an update to the public state and requires the owner(Org1) to endorse and sent by the owner org client (Org1). - // Since the client is from Org2, which is not the owner, this will fail. - try{ - await contractWrapperOrg2.changePublicDescription({assetId: assetKey, - ownerOrg: mspIdOrg1, - publicDescription: `Asset ${assetKey} owned by ${mspIdOrg2} is NOT for sale`}); - } catch(e) { - console.log(`${RED}*** Successfully caught the failure: changePublicDescription - ${String(e)}${RESET}`); - } - - // Read the public details by org1. - await contractWrapperOrg1.readAsset(assetKey, mspIdOrg1); - - // Read the public details by org2. - await contractWrapperOrg2.readAsset(assetKey, mspIdOrg1); - - // Agree to a sell by org1. - await contractWrapperOrg1.agreeToSell({ - assetId: assetKey, - price: 110, - tradeId: now, - }); - - // Check the private information about the asset from Org2. Org1 would have to send Org2 asset details, - // so the hash of the details may be checked by the chaincode. - await contractWrapperOrg2.verifyAssetProperties(assetKey, {color:'blue', size:35}); - - // Agree to a buy by org2. - await contractWrapperOrg2.agreeToBuy( {assetId: assetKey, - price: 100, - tradeId: now}, { ObjectType: 'asset_properties', Color: 'blue', Size: 35 }); - - // Org1 should be able to read the sale price of this asset. - await contractWrapperOrg1.getAssetSalesPrice(assetKey, mspIdOrg1); - - // Org2 has not set a sale price and this should fail. - try{ - await contractWrapperOrg2.getAssetSalesPrice(assetKey, mspIdOrg1); - } catch(e) { - console.log(`${RED}*** Successfully caught the failure: getAssetSalesPrice - ${String(e)}${RESET}`); - } - - // Org1 has not agreed to buy so this should fail. - try{ - await contractWrapperOrg1.getAssetBidPrice(assetKey, mspIdOrg2); - } catch(e) { - console.log(`${RED}*** Successfully caught the failure: getAssetBidPrice - ${String(e)}${RESET}`); - } - // Org2 should be able to see the price it has agreed. - await contractWrapperOrg2.getAssetBidPrice(assetKey, mspIdOrg2); - - // Org1 will try to transfer the asset to Org2 - // This will fail due to the sell price and the bid price are not the same. - try{ - await contractWrapperOrg1.transferAsset({ assetId: assetKey, price: 110, tradeId: now}, [ mspIdOrg1, mspIdOrg2 ], mspIdOrg1, mspIdOrg2); - } catch(e) { - console.log(`${RED}*** Successfully caught the failure: transferAsset - ${String(e)}${RESET}`); - } - // Agree to a sell by Org1, the seller will agree to the bid price of Org2. - await contractWrapperOrg1.agreeToSell({assetId:assetKey, price:100, tradeId:now}); - - // Read the public details by org1. - await contractWrapperOrg1.readAsset(assetKey, mspIdOrg1); - - // Read the public details by org2. - await contractWrapperOrg2.readAsset(assetKey, mspIdOrg1); - - // Org1 should be able to read the private data details of the asset. - await contractWrapperOrg1.getAssetPrivateProperties(assetKey, mspIdOrg1); - - // Org1 should be able to read the sale price of this asset. - await contractWrapperOrg1.getAssetSalesPrice(assetKey, mspIdOrg1); - - // Org2 should be able to see the price it has agreed. - await contractWrapperOrg2.getAssetBidPrice(assetKey, mspIdOrg2); - - // Org2 user will try to transfer the asset to Org1. - // This will fail as the owner is Org1. - try{ - await contractWrapperOrg2.transferAsset({ assetId: assetKey, price: 100, tradeId: now}, [ mspIdOrg1, mspIdOrg2 ], mspIdOrg1, mspIdOrg2); - } catch(e) { - console.log(`${RED}*** Successfully caught the failure: transferAsset - ${String(e)}${RESET}`); - } - - // Org1 will transfer the asset to Org2. - // This will now complete as the sell price and the bid price are the same. - await contractWrapperOrg1.transferAsset({ assetId: assetKey, price: 100, tradeId: now}, [ mspIdOrg1, mspIdOrg2 ], mspIdOrg1, mspIdOrg2); - - // Read the public details by org1. - await contractWrapperOrg1.readAsset(assetKey, mspIdOrg2); - - // Read the public details by org2. - await contractWrapperOrg2.readAsset(assetKey, mspIdOrg2); - - // Org2 should be able to read the private data details of this asset. - await contractWrapperOrg2.getAssetPrivateProperties(assetKey, mspIdOrg2); - - // Org1 should not be able to read the private data details of this asset, expected to fail. - try{ - await contractWrapperOrg1.getAssetPrivateProperties(assetKey, mspIdOrg2); - } catch(e) { - console.log(`${RED}*** Successfully caught the failure: getAssetPrivateProperties - ${String(e)}${RESET}`); - } - - // This is an update to the public state and requires only the owner to endorse. - // Org2 wants to indicate that the items is no longer for sale. - await contractWrapperOrg2.changePublicDescription( {assetId: assetKey, ownerOrg: mspIdOrg2, publicDescription: `Asset ${assetKey} owned by ${mspIdOrg2} is NOT for sale`}); - - // Read the public details by org1. - await contractWrapperOrg1.readAsset(assetKey, mspIdOrg2); - - // Read the public details by org2. - await contractWrapperOrg2.readAsset(assetKey, mspIdOrg2); - - } finally { - gatewayOrg1.close(); - gatewayOrg2.close(); - clientOrg1.close(); - clientOrg2.close(); - } -} - -main().catch((error: unknown) => { - console.error('******** FAILED to run the application:', error); - process.exitCode = 1; -}); diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/src/connect.ts b/asset-transfer-secured-agreement/application-gateway-typescript/src/connect.ts deleted file mode 100644 index b6afd2e8..00000000 --- a/asset-transfer-secured-agreement/application-gateway-typescript/src/connect.ts +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as grpc from '@grpc/grpc-js'; -import { Identity, Signer, signers } from '@hyperledger/fabric-gateway'; -import * as crypto from 'crypto'; -import { promises as fs } from 'fs'; -import * as path from 'path'; - -// MSP Id's of Organizations -export const mspIdOrg1 = 'Org1MSP'; -export const mspIdOrg2 = 'Org2MSP'; - -// Path to org1 crypto materials. -export const cryptoPathOrg1 = path.resolve(__dirname, '..', '..', '..', 'test-network', 'organizations', 'peerOrganizations', 'org1.example.com'); - -// Path to user private key directory. -export const keyDirectoryPathOrg1 = path.resolve(cryptoPathOrg1, 'users', 'User1@org1.example.com', 'msp', 'keystore'); - -// Path to user certificate. -export const certDirectoryPathOrg1 = path.resolve(cryptoPathOrg1, 'users', 'User1@org1.example.com', 'msp', 'signcerts'); - -// Path to peer tls certificate. -export const tlsCertPathOrg1 = path.resolve(cryptoPathOrg1, 'peers', 'peer0.org1.example.com', 'tls', 'ca.crt'); - -// Path to org2 crypto materials. -export const cryptoPathOrg2 = path.resolve( - __dirname, - '..', - '..', - '..', - 'test-network', - 'organizations', - 'peerOrganizations', - 'org2.example.com' -); - -// Path to org2 user private key directory. -export const keyDirectoryPathOrg2 = path.resolve( - cryptoPathOrg2, - 'users', - 'User1@org2.example.com', - 'msp', - 'keystore' -); - -// Path to org2 user certificate. -export const certDirectoryPathOrg2 = path.resolve( - cryptoPathOrg2, - 'users', - 'User1@org2.example.com', - 'msp', - 'signcerts' -); - -// Path to org2 peer tls certificate. -export const tlsCertPathOrg2 = path.resolve( - cryptoPathOrg2, - 'peers', - 'peer0.org2.example.com', - 'tls', - 'ca.crt' -); -// Gateway peer endpoint. -export const peerEndpointOrg1 = 'localhost:7051'; -export const peerEndpointOrg2 = 'localhost:9051'; - -// Gateway peer container name. -export const peerNameOrg1 = 'peer0.org1.example.com'; -export const peerNameOrg2 = 'peer0.org2.example.com'; - -// Collection Names -export const org1PrivateCollectionName = 'Org1MSPPrivateCollection'; -export const org2PrivateCollectionName = 'Org2MSPPrivateCollection'; - -export async function newGrpcConnection( - tlsCertPath: string, - peerEndpoint: string, - peerName: string -): Promise { - const tlsRootCert = await fs.readFile(tlsCertPath); - const tlsCredentials = grpc.credentials.createSsl(tlsRootCert); - return new grpc.Client(peerEndpoint, tlsCredentials, { - 'grpc.ssl_target_name_override': peerName, - }); -} - -export async function newIdentity(certDirectoryPath: string, mspId: string): Promise { - const certPath = await getFirstDirFileName(certDirectoryPath); - const credentials = await fs.readFile(certPath); - return { mspId, credentials }; -} - -export async function newSigner(keyDirectoryPath: string): Promise { - const keyPath = await getFirstDirFileName(keyDirectoryPath); - const privateKeyPem = await fs.readFile(keyPath); - const privateKey = crypto.createPrivateKey(privateKeyPem); - return signers.newPrivateKeySigner(privateKey); -} - -async function getFirstDirFileName(dirPath: string): Promise { - const files = await fs.readdir(dirPath); - const file = files[0]; - if (!file) { - throw new Error(`No files in directory: ${dirPath}`); - } - return path.join(dirPath, file); -} diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/src/contractWrapper.ts b/asset-transfer-secured-agreement/application-gateway-typescript/src/contractWrapper.ts deleted file mode 100644 index 44c5f7d2..00000000 --- a/asset-transfer-secured-agreement/application-gateway-typescript/src/contractWrapper.ts +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ -import { Contract } from '@hyperledger/fabric-gateway'; -import { TextDecoder } from 'util'; -import { GREEN, parse, RED, RESET } from './utils'; -import crypto from 'crypto'; -import { mspIdOrg2 } from './connect'; - -const randomBytes = crypto.randomBytes(256).toString('hex'); - -interface AssetJSON { - objectType: string; - assetID: string; - ownerOrg: string; - publicDescription: string; -} - -interface AssetPropertiesJSON { - objectType: string; - color: string; - size: number; - salt: string; -} - -interface AssetPriceJSON { - assetID: string; - price: number; - tradeID: string; -} - -export interface AssetPrivateData { - ObjectType: string; - Color: string; - Size: number; -} - -export interface Asset { - assetId: string; - ownerOrg: string; - publicDescription: string; -} - -export interface AssetProperties { - color: string; - size: number; -} - -export interface AssetPrice { - assetId: string; - price: number; - tradeId: string; -} - -export class ContractWrapper { - - readonly #contract: Contract; - readonly #org: string; - readonly #utf8Decoder = new TextDecoder(); - readonly #randomBytes: string = randomBytes; - #endorsingOrgs: { [id: string]: string[] }; - - public constructor(contract: Contract, org: string) { - this.#contract = contract; - this.#org = org; - this.#endorsingOrgs = {}; - } - - public async createAsset(ownerOrg: string, publicDescription: string, privateData: AssetPrivateData): Promise { - console.log(`${GREEN}--> Submit Transaction: CreateAsset as ${ownerOrg} - endorsed by Org1.${RESET}`); - const assetPropertiesJSON: AssetPropertiesJSON = { - objectType: 'asset_properties', - color: privateData.Color, - size: privateData.Size, - salt: this.#randomBytes }; - - const resultBytes = await this.#contract.submit('CreateAsset', { - arguments: [publicDescription], - transientData: { asset_properties: JSON.stringify(assetPropertiesJSON)}, - }); - const assetID = this.#utf8Decoder.decode(resultBytes); - this.#endorsingOrgs[assetID] = [ownerOrg]; - console.log(`*** Result: committed, asset ${assetID} is owned by ${ownerOrg}`); - return assetID; - } - - public async readAsset(assetKey: string, ownerOrg: string): Promise { - console.log(`${GREEN}--> Evaluate Transactions: ReadAsset as ${this.#org}, - ${assetKey} should be owned by ${ownerOrg}.${RESET}`); - - const resultBytes = await this.#contract.evaluateTransaction('ReadAsset', assetKey); - - const result = this.#utf8Decoder.decode(resultBytes); - if (result.length !== 0) { - const json = parse(result); - if (json.ownerOrg === ownerOrg) { - console.log(`*** Result from ${this.#org} - asset ${json.assetID} owned by ${json.ownerOrg} DESC: ${json.publicDescription}`); - } else { - console.log(`${RED}*** Failed owner check from ${this.#org} - asset ${json.assetID} owned by ${json.ownerOrg} DESC:${json.publicDescription}.${RESET}`); - } - } else { - throw new Error('No Asset Found'); - } - } - - public async getAssetPrivateProperties(assetKey: string, ownerOrg: string): Promise { - console.log(`${GREEN}--> Evaluate Transaction: GetAssetPrivateProperties, - ${assetKey} from organization ${this.#org}.${RESET}`); - if(this.#org !== ownerOrg) { - console.log(`${GREEN}* Expected to fail as ${this.#org} is not the owner and does not have the private details.${RESET}`); - } - - const resultBytes = await this.#contract.evaluateTransaction('GetAssetPrivateProperties', assetKey); - - const resultString = this.#utf8Decoder.decode(resultBytes); - const json = parse(resultString); - const result: AssetProperties = { - color: json.color, - size: json.size, - }; - console.log('*** Result:', result); - } - - - public async changePublicDescription(asset: Asset): Promise { - console.log(`${GREEN}--> Submit Transaction: ChangePublicDescription ${asset.assetId}, as ${this.#org} - endorse by ${this.#org}.${RESET}`); - if (asset.ownerOrg !== this.#org) { - console.log(`${GREEN}* Expected to fail as ${this.#org} is not the owner.${RESET}`); - } - - await this.#contract.submit('ChangePublicDescription', { - arguments:[asset.assetId, asset.publicDescription], - endorsingOrganizations: this.#endorsingOrgs[asset.assetId] - }); - - console.log(`*** Result: committed, Desc: ${asset.publicDescription}`); - } - - public async agreeToSell(assetPrice: AssetPrice): Promise { - - console.log(`${GREEN}--> Submit Transaction: AgreeToSell, ${assetPrice.assetId} as ${this.#org} - endorsed by ${this.#org}.${RESET}`); - const assetPriceJSON: AssetPriceJSON = { - assetID:assetPrice.assetId, - price:assetPrice.price, - tradeID:assetPrice.tradeId - }; - - await this.#contract.submit('AgreeToSell', { - arguments:[assetPrice.assetId], - transientData: {asset_price: JSON.stringify(assetPriceJSON)}, - endorsingOrganizations: this.#endorsingOrgs[assetPrice.assetId] - }); - - console.log(`*** Result: committed, ${this.#org} has agreed to sell asset ${assetPrice.assetId} for ${String(assetPrice.price)}`); - } - - public async verifyAssetProperties(assetId: string, assetProperties: AssetProperties): Promise { - console.log(`${GREEN}--> Evalute: VerifyAssetProperties, ${assetId} as ${this.#org} - endorsed by ${this.#org} and ${mspIdOrg2}.${RESET}`); - const assetPropertiesJSON: AssetPropertiesJSON = {objectType: 'asset_properties', - color: assetProperties.color, - size: assetProperties.size, - salt: this.#randomBytes }; - - const resultBytes = await this.#contract.evaluate('VerifyAssetProperties', { - arguments:[assetId], - transientData: {asset_properties: JSON.stringify(assetPropertiesJSON)}, - }); - - const resultString = this.#utf8Decoder.decode(resultBytes); - if (resultString.length !== 0) { - const json = parse(resultString); - if (typeof json === 'object') { - console.log(`*** Success VerifyAssetProperties, private information about asset ${assetId} has been verified by ${this.#org}`); - } else { - console.log(`*** Failed: VerifyAssetProperties, private information about asset ${assetId} has not been verified by ${this.#org}`); - } - } else { - throw new Error(`Private information about asset ${assetId} has not been verified by ${this.#org}`); - } - } - - public async agreeToBuy(assetPrice: AssetPrice, privateData: AssetPrivateData): Promise { - - console.log(`${GREEN}--> Submit Transaction: AgreeToBuy, ${assetPrice.assetId} as ${this.#org} - endorsed by ${this.#org} and ${mspIdOrg2}.${RESET}`); - const assetPropertiesJSON: AssetPropertiesJSON = { - objectType: 'asset_properties', - color: privateData.Color, - size: privateData.Size, - salt: this.#randomBytes }; - - const assetPriceJSON: AssetPriceJSON = { - assetID: assetPrice.assetId, - price: assetPrice.price, - tradeID: assetPrice.tradeId - }; - - await this.#contract.submit('AgreeToBuy', { - arguments:[assetPrice.assetId], - transientData: { - asset_price: JSON.stringify(assetPriceJSON), - asset_properties: JSON.stringify(assetPropertiesJSON) - }, - endorsingOrganizations: this.#endorsingOrgs[assetPrice.assetId] - }); - - console.log(`*** Result: committed, ${this.#org} has agreed to buy asset ${assetPrice.assetId} for 100`); - - } - - public async getAssetSalesPrice(assetKey: string, ownerOrg: string): Promise { - - console.log(`${GREEN}--> Evaluate Transaction: GetAssetSalesPrice, - ${assetKey} from organization ${this.#org}.${RESET}`); - if(this.#org !== ownerOrg) { - console.log(`${GREEN}* Expected to fail as ${this.#org} has not set a sale price.${RESET}`); - } - - const resultBytes = await this.#contract.evaluateTransaction('GetAssetSalesPrice', assetKey); - - const resultString = this.#utf8Decoder.decode(resultBytes); - const json = parse(resultString); - - const result: AssetPrice = { - assetId: json.assetID, - price: json.price, - tradeId: json.tradeID - }; - - console.log('*** Result: GetAssetSalesPrice', result); - } - - public async getAssetBidPrice(assetKey: string, buyerOrgID: string): Promise { - - console.log(`${GREEN}--> Evaluate Transaction: GetAssetBidPrice, - ${assetKey} from organization ${this.#org}.${RESET}`); - if(this.#org !== buyerOrgID){ - console.log(`${GREEN}* Expected to fail as ${this.#org} has not agreed to buy.${RESET}`); - } - - const resultBytes = await this.#contract.evaluateTransaction('GetAssetBidPrice', assetKey); - - const resultString = this.#utf8Decoder.decode(resultBytes); - const json = parse(resultString); - const result: AssetPrice = { - assetId: json.assetID, - price: json.price, - tradeId: json.tradeID, - }; - - console.log('*** Result: GetAssetBidPrice', result); - } - - public async transferAsset(assetPrice: AssetPrice, endorsingOrganizations: string[], ownerOrgID: string, buyerOrgID: string): Promise { - - console.log(`${GREEN}--> Submit Transaction: TransferAsset, ${assetPrice.assetId} as ${this.#org } - endorsed by ${this.#org} and ${buyerOrgID}.${RESET}`); - - if (this.#org !== ownerOrgID) { - console.log(`${GREEN}* Expected to fail as the owner is ${ownerOrgID}.${RESET}`); - } else if (assetPrice.price === 110) { - console.log(`${GREEN}* Expected to fail as sell price and the bid price are not the same.${RESET}`); - } - - const assetPriceJSON: AssetPriceJSON = { assetID: assetPrice.assetId, price:assetPrice.price, tradeID:assetPrice.tradeId}; - - await this.#contract.submit('TransferAsset', { - arguments:[assetPrice.assetId, buyerOrgID], - transientData: { asset_price: JSON.stringify(assetPriceJSON) }, - endorsingOrganizations: endorsingOrganizations - }); - - console.log(`${GREEN}*** Result: committed, ${this.#org} has transfered the asset ${assetPrice.assetId} to ${buyerOrgID}.${RESET}`); - } -} diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/src/utils.ts b/asset-transfer-secured-agreement/application-gateway-typescript/src/utils.ts deleted file mode 100644 index 0442ff02..00000000 --- a/asset-transfer-secured-agreement/application-gateway-typescript/src/utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -export const RED = '\x1b[31m\n'; -export const GREEN = '\x1b[32m\n'; -export const RESET = '\x1b[0m'; - -export function parse(data: string): T { - return JSON.parse(data) as T; -} diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/tsconfig.json b/asset-transfer-secured-agreement/application-gateway-typescript/tsconfig.json deleted file mode 100644 index 4c20df24..00000000 --- a/asset-transfer-secured-agreement/application-gateway-typescript/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "@tsconfig/node18/tsconfig.json", - "compilerOptions": { - "outDir": "dist", - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "noUnusedLocals": true, - "noImplicitReturns": true, - "noUncheckedIndexedAccess": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["./src/**/*"], - "exclude": ["./src/**/*.spec.ts"] -} diff --git a/asset-transfer-secured-agreement/chaincode-go/README.md b/asset-transfer-secured-agreement/chaincode-go/README.md deleted file mode 100644 index f65f09b6..00000000 --- a/asset-transfer-secured-agreement/chaincode-go/README.md +++ /dev/null @@ -1 +0,0 @@ -[Secured asset transfer in Fabric Tutorial](https://hyperledger-fabric.readthedocs.io/en/latest/secured_asset_transfer/secured_private_asset_transfer_tutorial.html) diff --git a/asset-transfer-secured-agreement/chaincode-go/asset_transfer.go b/asset-transfer-secured-agreement/chaincode-go/asset_transfer.go deleted file mode 100644 index d7228406..00000000 --- a/asset-transfer-secured-agreement/chaincode-go/asset_transfer.go +++ /dev/null @@ -1,619 +0,0 @@ -/* - SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "bytes" - "crypto/sha256" - "encoding/hex" - "encoding/json" - "fmt" - "log" - "time" - - "github.com/hyperledger/fabric-chaincode-go/v2/pkg/statebased" - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -const ( - typeAssetForSale = "S" - typeAssetBid = "B" - typeAssetSaleReceipt = "SR" - typeAssetBuyReceipt = "BR" -) - -type SmartContract struct { - contractapi.Contract -} - -// Asset struct and properties must be exported (start with capitals) to work with contract api metadata -type Asset struct { - ObjectType string `json:"objectType"` // ObjectType is used to distinguish different object types in the same chaincode namespace - ID string `json:"assetID"` - OwnerOrg string `json:"ownerOrg"` - PublicDescription string `json:"publicDescription"` -} - -type receipt struct { - price int - timestamp time.Time -} - -// CreateAsset creates an asset, sets it as owned by the client's org and returns its id -// the id of the asset corresponds to the hash of the properties of the asset that are passed by transiet field -func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, publicDescription string) (string, error) { - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return "", fmt.Errorf("error getting transient: %v", err) - } - - // Asset properties must be retrieved from the transient field as they are private - immutablePropertiesJSON, ok := transientMap["asset_properties"] - if !ok { - return "", fmt.Errorf("asset_properties key not found in the transient map") - } - - // AssetID will be the hash of the asset's properties - hash := sha256.New() - hash.Write(immutablePropertiesJSON) - assetID := hex.EncodeToString(hash.Sum(nil)) - - // Get the clientOrgId from the input, will be used for implicit collection, owner, and state-based endorsement policy - clientOrgID, err := getClientOrgID(ctx) - if err != nil { - return "", err - } - - // In this scenario, client is only authorized to read/write private data from its own peer, therefore verify client org id matches peer org id. - err = verifyClientOrgMatchesPeerOrg(clientOrgID) - if err != nil { - return "", err - } - - asset := Asset{ - ObjectType: "asset", - ID: assetID, - OwnerOrg: clientOrgID, - PublicDescription: publicDescription, - } - assetBytes, err := json.Marshal(asset) - if err != nil { - return "", fmt.Errorf("failed to create asset JSON: %v", err) - } - - err = ctx.GetStub().PutState(assetID, assetBytes) - if err != nil { - return "", fmt.Errorf("failed to put asset in public data: %v", err) - } - - // Set the endorsement policy such that an owner org peer is required to endorse future updates. - // In practice, consider additional endorsers such as a trusted third party to further secure transfers. - endorsingOrgs := []string{clientOrgID} - err = setAssetStateBasedEndorsement(ctx, asset.ID, endorsingOrgs) - if err != nil { - return "", fmt.Errorf("failed setting state based endorsement for buyer and seller: %v", err) - } - - // Persist private immutable asset properties to owner's private data collection - collection := buildCollectionName(clientOrgID) - err = ctx.GetStub().PutPrivateData(collection, assetID, immutablePropertiesJSON) - if err != nil { - return "", fmt.Errorf("failed to put Asset private details: %v", err) - } - - return assetID, nil -} - -// ChangePublicDescription updates the assets public description. Only the current owner can update the public description -func (s *SmartContract) ChangePublicDescription(ctx contractapi.TransactionContextInterface, assetID string, newDescription string) error { - - clientOrgID, err := getClientOrgID(ctx) - if err != nil { - return err - } - - asset, err := s.ReadAsset(ctx, assetID) - if err != nil { - return fmt.Errorf("failed to get asset: %v", err) - } - - // Auth check to ensure that client's org actually owns the asset - if clientOrgID != asset.OwnerOrg { - return fmt.Errorf("a client from %s cannot update the description of a asset owned by %s", clientOrgID, asset.OwnerOrg) - } - - asset.PublicDescription = newDescription - updatedAssetJSON, err := json.Marshal(asset) - if err != nil { - return fmt.Errorf("failed to marshal asset: %v", err) - } - - return ctx.GetStub().PutState(assetID, updatedAssetJSON) -} - -// AgreeToSell adds seller's asking price to seller's implicit private data collection. -func (s *SmartContract) AgreeToSell(ctx contractapi.TransactionContextInterface, assetID string) error { - asset, err := s.ReadAsset(ctx, assetID) - if err != nil { - return err - } - - clientOrgID, err := getClientOrgID(ctx) - if err != nil { - return err - } - - // Verify that this client belongs to the peer's org - err = verifyClientOrgMatchesPeerOrg(clientOrgID) - if err != nil { - return err - } - - // Verify that this clientOrgId actually owns the asset. - if clientOrgID != asset.OwnerOrg { - return fmt.Errorf("a client from %s cannot sell an asset owned by %s", clientOrgID, asset.OwnerOrg) - } - - return agreeToPrice(ctx, assetID, typeAssetForSale) -} - -// AgreeToBuy adds buyer's bid price and asset properties to buyer's implicit private data collection -func (s *SmartContract) AgreeToBuy(ctx contractapi.TransactionContextInterface, assetID string) error { - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return fmt.Errorf("error getting transient: %v", err) - } - - clientOrgID, err := getClientOrgID(ctx) - if err != nil { - return err - } - - // Verify that this client belongs to the peer's org - err = verifyClientOrgMatchesPeerOrg(clientOrgID) - if err != nil { - return err - } - - // Asset properties must be retrieved from the transient field as they are private - immutablePropertiesJSON, ok := transientMap["asset_properties"] - if !ok { - return fmt.Errorf("asset_properties key not found in the transient map") - } - - // Persist private immutable asset properties to seller's private data collection - collection := buildCollectionName(clientOrgID) - err = ctx.GetStub().PutPrivateData(collection, assetID, immutablePropertiesJSON) - if err != nil { - return fmt.Errorf("failed to put Asset private details: %v", err) - } - - return agreeToPrice(ctx, assetID, typeAssetBid) -} - -// agreeToPrice adds a bid or ask price to caller's implicit private data collection -func agreeToPrice(ctx contractapi.TransactionContextInterface, assetID string, priceType string) error { - // In this scenario, both buyer and seller are authoried to read/write private about transfer after seller agrees to sell. - clientOrgID, err := getClientOrgID(ctx) - if err != nil { - return err - } - - transMap, err := ctx.GetStub().GetTransient() - if err != nil { - return fmt.Errorf("error getting transient: %v", err) - } - - // Asset price must be retrieved from the transient field as they are private - price, ok := transMap["asset_price"] - if !ok { - return fmt.Errorf("asset_price key not found in the transient map") - } - - collection := buildCollectionName(clientOrgID) - - // Persist the agreed to price in a collection sub-namespace based on priceType key prefix, - // to avoid collisions between private asset properties, sell price, and buy price - assetPriceKey, err := ctx.GetStub().CreateCompositeKey(priceType, []string{assetID}) - if err != nil { - return fmt.Errorf("failed to create composite key: %v", err) - } - - // The Price hash will be verified later, therefore always pass and persist price bytes as is, - // so that there is no risk of nondeterministic marshaling. - err = ctx.GetStub().PutPrivateData(collection, assetPriceKey, price) - if err != nil { - return fmt.Errorf("failed to put asset bid: %v", err) - } - - return nil -} - -// VerifyAssetProperties allows a buyer to validate the properties of -// an asset they intend to buy against the owner's implicit private data collection -// and verifies that the asset properties never changed from the origin of the asset by checking their hash against the assetID -func (s *SmartContract) VerifyAssetProperties(ctx contractapi.TransactionContextInterface, assetID string) (bool, error) { - transMap, err := ctx.GetStub().GetTransient() - if err != nil { - return false, fmt.Errorf("error getting transient: %v", err) - } - - // Asset properties must be retrieved from the transient field as they are private - immutablePropertiesJSON, ok := transMap["asset_properties"] - if !ok { - return false, fmt.Errorf("asset_properties key not found in the transient map") - } - - asset, err := s.ReadAsset(ctx, assetID) - if err != nil { - return false, fmt.Errorf("failed to get asset: %v", err) - } - - collectionOwner := buildCollectionName(asset.OwnerOrg) - immutablePropertiesOnChainHash, err := ctx.GetStub().GetPrivateDataHash(collectionOwner, assetID) - if err != nil { - return false, fmt.Errorf("failed to read asset private properties hash from seller's collection: %v", err) - } - if immutablePropertiesOnChainHash == nil { - return false, fmt.Errorf("asset private properties hash does not exist: %s", assetID) - } - - hash := sha256.New() - hash.Write(immutablePropertiesJSON) - calculatedPropertiesHash := hash.Sum(nil) - - // verify that the hash of the passed immutable properties matches the on-chain hash - if !bytes.Equal(immutablePropertiesOnChainHash, calculatedPropertiesHash) { - return false, fmt.Errorf("hash %x for passed immutable properties %s does not match on-chain hash %x", - calculatedPropertiesHash, - immutablePropertiesJSON, - immutablePropertiesOnChainHash, - ) - } - - // verify that the hash of the passed immutable properties and on chain hash matches the assetID - if !(hex.EncodeToString(immutablePropertiesOnChainHash) == assetID) { - return false, fmt.Errorf("hash %x for passed immutable properties %s does match on-chain hash %x but do not match assetID %s: asset was altered from its initial form", - calculatedPropertiesHash, - immutablePropertiesJSON, - immutablePropertiesOnChainHash, - assetID) - } - - return true, nil -} - -// TransferAsset checks transfer conditions and then transfers asset state to buyer. -// TransferAsset can only be called by current owner -func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface, assetID string, buyerOrgID string) error { - clientOrgID, err := getClientOrgID(ctx) - if err != nil { - return err - } - - transMap, err := ctx.GetStub().GetTransient() - if err != nil { - return fmt.Errorf("error getting transient data: %v", err) - } - - priceJSON, ok := transMap["asset_price"] - if !ok { - return fmt.Errorf("asset_price key not found in the transient map") - } - - var agreement Agreement - err = json.Unmarshal(priceJSON, &agreement) - if err != nil { - return fmt.Errorf("failed to unmarshal price JSON: %v", err) - } - - asset, err := s.ReadAsset(ctx, assetID) - if err != nil { - return fmt.Errorf("failed to get asset: %v", err) - } - - err = verifyTransferConditions(ctx, asset, clientOrgID, buyerOrgID, priceJSON) - if err != nil { - return fmt.Errorf("failed transfer verification: %v", err) - } - - err = transferAssetState(ctx, asset, clientOrgID, buyerOrgID, agreement.Price) - if err != nil { - return fmt.Errorf("failed asset transfer: %v", err) - } - - return nil - -} - -// verifyTransferConditions checks that client org currently owns asset and that both parties have agreed on price -func verifyTransferConditions(ctx contractapi.TransactionContextInterface, - asset *Asset, - clientOrgID string, - buyerOrgID string, - priceJSON []byte) error { - - // CHECK1: Auth check to ensure that client's org actually owns the asset - - if clientOrgID != asset.OwnerOrg { - return fmt.Errorf("a client from %s cannot transfer a asset owned by %s", clientOrgID, asset.OwnerOrg) - } - - // CHECK2: Verify that buyer and seller on-chain asset defintion hash matches - - collectionSeller := buildCollectionName(clientOrgID) - collectionBuyer := buildCollectionName(buyerOrgID) - sellerPropertiesOnChainHash, err := ctx.GetStub().GetPrivateDataHash(collectionSeller, asset.ID) - if err != nil { - return fmt.Errorf("failed to read asset private properties hash from seller's collection: %v", err) - } - if sellerPropertiesOnChainHash == nil { - return fmt.Errorf("asset private properties hash does not exist: %s", asset.ID) - } - buyerPropertiesOnChainHash, err := ctx.GetStub().GetPrivateDataHash(collectionBuyer, asset.ID) - if err != nil { - return fmt.Errorf("failed to read asset private properties hash from seller's collection: %v", err) - } - if buyerPropertiesOnChainHash == nil { - return fmt.Errorf("asset private properties hash does not exist: %s", asset.ID) - } - - // verify that buyer and seller on-chain asset defintion hash matches - if !bytes.Equal(sellerPropertiesOnChainHash, buyerPropertiesOnChainHash) { - return fmt.Errorf("on chain hash of seller %x does not match on-chain hash of buyer %x", - sellerPropertiesOnChainHash, - buyerPropertiesOnChainHash, - ) - } - - // CHECK3: Verify that seller and buyer agreed on the same price - - // Get sellers asking price - assetForSaleKey, err := ctx.GetStub().CreateCompositeKey(typeAssetForSale, []string{asset.ID}) - if err != nil { - return fmt.Errorf("failed to create composite key: %v", err) - } - sellerPriceHash, err := ctx.GetStub().GetPrivateDataHash(collectionSeller, assetForSaleKey) - if err != nil { - return fmt.Errorf("failed to get seller price hash: %v", err) - } - if sellerPriceHash == nil { - return fmt.Errorf("seller price for %s does not exist", asset.ID) - } - - // Get buyers bid price - assetBidKey, err := ctx.GetStub().CreateCompositeKey(typeAssetBid, []string{asset.ID}) - if err != nil { - return fmt.Errorf("failed to create composite key: %v", err) - } - buyerPriceHash, err := ctx.GetStub().GetPrivateDataHash(collectionBuyer, assetBidKey) - if err != nil { - return fmt.Errorf("failed to get buyer price hash: %v", err) - } - if buyerPriceHash == nil { - return fmt.Errorf("buyer price for %s does not exist", asset.ID) - } - - hash := sha256.New() - hash.Write(priceJSON) - calculatedPriceHash := hash.Sum(nil) - - // Verify that the hash of the passed price matches the on-chain sellers price hash - if !bytes.Equal(calculatedPriceHash, sellerPriceHash) { - return fmt.Errorf("hash %x for passed price JSON %s does not match on-chain hash %x, seller hasn't agreed to the passed trade id and price", - calculatedPriceHash, - priceJSON, - sellerPriceHash, - ) - } - - // Verify that the hash of the passed price matches the on-chain buyer price hash - if !bytes.Equal(calculatedPriceHash, buyerPriceHash) { - return fmt.Errorf("hash %x for passed price JSON %s does not match on-chain hash %x, buyer hasn't agreed to the passed trade id and price", - calculatedPriceHash, - priceJSON, - buyerPriceHash, - ) - } - - return nil -} - -// transferAssetState performs the public and private state updates for the transferred asset -// changes the endorsement for the transferred asset sbe to the new owner org -func transferAssetState(ctx contractapi.TransactionContextInterface, asset *Asset, clientOrgID string, buyerOrgID string, price int) error { - - // Update ownership in public state - asset.OwnerOrg = buyerOrgID - updatedAsset, err := json.Marshal(asset) - if err != nil { - return err - } - err = ctx.GetStub().PutState(asset.ID, updatedAsset) - if err != nil { - return fmt.Errorf("failed to write asset for buyer: %v", err) - } - - // Changes the endorsement policy to the new owner org - endorsingOrgs := []string{buyerOrgID} - err = setAssetStateBasedEndorsement(ctx, asset.ID, endorsingOrgs) - if err != nil { - return fmt.Errorf("failed setting state based endorsement for new owner: %v", err) - } - - // Delete asset description from seller collection - collectionSeller := buildCollectionName(clientOrgID) - err = ctx.GetStub().DelPrivateData(collectionSeller, asset.ID) - if err != nil { - return fmt.Errorf("failed to delete Asset private details from seller: %v", err) - } - - // Delete the price records for seller - assetPriceKey, err := ctx.GetStub().CreateCompositeKey(typeAssetForSale, []string{asset.ID}) - if err != nil { - return fmt.Errorf("failed to create composite key for seller: %v", err) - } - err = ctx.GetStub().DelPrivateData(collectionSeller, assetPriceKey) - if err != nil { - return fmt.Errorf("failed to delete asset price from implicit private data collection for seller: %v", err) - } - - // Delete the price records for buyer - collectionBuyer := buildCollectionName(buyerOrgID) - assetPriceKey, err = ctx.GetStub().CreateCompositeKey(typeAssetBid, []string{asset.ID}) - if err != nil { - return fmt.Errorf("failed to create composite key for buyer: %v", err) - } - err = ctx.GetStub().DelPrivateData(collectionBuyer, assetPriceKey) - if err != nil { - return fmt.Errorf("failed to delete asset price from implicit private data collection for buyer: %v", err) - } - - // Keep record for a 'receipt' in both buyers and sellers private data collection to record the sale price and date. - // Persist the agreed to price in a collection sub-namespace based on receipt key prefix. - receiptBuyKey, err := ctx.GetStub().CreateCompositeKey(typeAssetBuyReceipt, []string{asset.ID, ctx.GetStub().GetTxID()}) - if err != nil { - return fmt.Errorf("failed to create composite key for receipt: %v", err) - } - - txTimestamp, err := ctx.GetStub().GetTxTimestamp() - if err != nil { - return fmt.Errorf("failed to create timestamp for receipt: %v", err) - } - - assetReceipt := receipt{ - price: price, - timestamp: txTimestamp.AsTime(), - } - receipt, err := json.Marshal(assetReceipt) - if err != nil { - return fmt.Errorf("failed to marshal receipt: %v", err) - } - - err = ctx.GetStub().PutPrivateData(collectionBuyer, receiptBuyKey, receipt) - if err != nil { - return fmt.Errorf("failed to put private asset receipt for buyer: %v", err) - } - - receiptSaleKey, err := ctx.GetStub().CreateCompositeKey(typeAssetSaleReceipt, []string{ctx.GetStub().GetTxID(), asset.ID}) - if err != nil { - return fmt.Errorf("failed to create composite key for receipt: %v", err) - } - - err = ctx.GetStub().PutPrivateData(collectionSeller, receiptSaleKey, receipt) - if err != nil { - return fmt.Errorf("failed to put private asset receipt for seller: %v", err) - } - - return nil -} - -// getClientOrgID gets the client org ID. -func getClientOrgID(ctx contractapi.TransactionContextInterface) (string, error) { - clientOrgID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return "", fmt.Errorf("failed getting client's orgID: %v", err) - } - - return clientOrgID, nil -} - -// getClientImplicitCollectionNameAndVerifyClientOrg gets the implicit collection for the client and checks that the client is from the same org as the peer -func getClientImplicitCollectionNameAndVerifyClientOrg(ctx contractapi.TransactionContextInterface) (string, error) { - clientOrgID, err := getClientOrgID(ctx) - if err != nil { - return "", err - } - - err = verifyClientOrgMatchesPeerOrg(clientOrgID) - if err != nil { - return "", err - } - - return buildCollectionName(clientOrgID), nil -} - -// verifyClientOrgMatchesPeerOrg checks that the client is from the same org as the peer -func verifyClientOrgMatchesPeerOrg(clientOrgID string) error { - peerOrgID, err := shim.GetMSPID() - if err != nil { - return fmt.Errorf("failed getting peer's orgID: %v", err) - } - - if clientOrgID != peerOrgID { - return fmt.Errorf("client from org %s is not authorized to read or write private data from an org %s peer", - clientOrgID, - peerOrgID, - ) - } - - return nil -} - -// buildCollectionName returns the implicit collection name for an org -func buildCollectionName(clientOrgID string) string { - return fmt.Sprintf("_implicit_org_%s", clientOrgID) -} - -// setAssetStateBasedEndorsement adds an endorsement policy to an asset so that the passed orgs need to agree upon transfer -func setAssetStateBasedEndorsement(ctx contractapi.TransactionContextInterface, assetID string, orgsToEndorse []string) error { - endorsementPolicy, err := statebased.NewStateEP(nil) - if err != nil { - return err - } - err = endorsementPolicy.AddOrgs(statebased.RoleTypePeer, orgsToEndorse...) - if err != nil { - return fmt.Errorf("failed to add org to endorsement policy: %v", err) - } - policy, err := endorsementPolicy.Policy() - if err != nil { - return fmt.Errorf("failed to create endorsement policy bytes from org: %v", err) - } - err = ctx.GetStub().SetStateValidationParameter(assetID, policy) - if err != nil { - return fmt.Errorf("failed to set validation parameter on asset: %v", err) - } - - return nil -} - -// GetAssetHashId allows a potential buyer to validate the properties of an asset against the asset Id hash on chain and returns the hash -func (s *SmartContract) GetAssetHashId(ctx contractapi.TransactionContextInterface) (string, error) { - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return "", fmt.Errorf("error getting transient: %v", err) - } - - // Asset properties must be retrieved from the transient field as they are private - propertiesJSON, ok := transientMap["asset_properties"] - if !ok { - return "", fmt.Errorf("asset_properties key not found in the transient map") - } - - hash := sha256.New() - hash.Write(propertiesJSON) - assetID := hex.EncodeToString(hash.Sum(nil)) - - asset, err := s.ReadAsset(ctx, assetID) - if err != nil { - return "", fmt.Errorf("failed to get asset: %v, asset properies provided do not represent any on chain asset", err) - } - if asset.ID != assetID { - return "", fmt.Errorf("Asset properies provided do not correpond to any on chain asset") - } - return asset.ID, nil -} - -func main() { - chaincode, err := contractapi.NewChaincode(new(SmartContract)) - if err != nil { - log.Panicf("Error create transfer asset chaincode: %v", err) - } - - if err := chaincode.Start(); err != nil { - log.Panicf("Error starting asset chaincode: %v", err) - } -} diff --git a/asset-transfer-secured-agreement/chaincode-go/asset_transfer_queries.go b/asset-transfer-secured-agreement/chaincode-go/asset_transfer_queries.go deleted file mode 100644 index 4dc569d8..00000000 --- a/asset-transfer-secured-agreement/chaincode-go/asset_transfer_queries.go +++ /dev/null @@ -1,172 +0,0 @@ -/* - SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "encoding/json" - "fmt" - "time" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -// QueryResult structure used for handling result of query -type QueryResult struct { - Record *Asset - TxId string `json:"txId"` - Timestamp time.Time `json:"timestamp"` -} - -type Agreement struct { - ID string `json:"asset_id"` - Price int `json:"price"` - TradeID string `json:"trade_id"` -} - -// ReadAsset returns the public asset data -func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, assetID string) (*Asset, error) { - // Since only public data is accessed in this function, no access control is required - assetJSON, err := ctx.GetStub().GetState(assetID) - if err != nil { - return nil, fmt.Errorf("failed to read from world state: %v", err) - } - if assetJSON == nil { - return nil, fmt.Errorf("%s does not exist", assetID) - } - - var asset *Asset - err = json.Unmarshal(assetJSON, &asset) - if err != nil { - return nil, err - } - return asset, nil -} - -// GetAssetPrivateProperties returns the immutable asset properties from owner's private data collection -func (s *SmartContract) GetAssetPrivateProperties(ctx contractapi.TransactionContextInterface, assetID string) (string, error) { - - collection, err := getClientImplicitCollectionNameAndVerifyClientOrg(ctx) - if err != nil { - return "", err - } - - immutableProperties, err := ctx.GetStub().GetPrivateData(collection, assetID) - if err != nil { - return "", fmt.Errorf("failed to read asset private properties from client org's collection: %v", err) - } - if immutableProperties == nil { - return "", fmt.Errorf("asset private details does not exist in client org's collection: %s", assetID) - } - - return string(immutableProperties), nil -} - -// GetAssetSalesPrice returns the sales price -func (s *SmartContract) GetAssetSalesPrice(ctx contractapi.TransactionContextInterface, assetID string) (string, error) { - return getAssetPrice(ctx, assetID, typeAssetForSale) -} - -// GetAssetBidPrice returns the bid price -func (s *SmartContract) GetAssetBidPrice(ctx contractapi.TransactionContextInterface, assetID string) (string, error) { - return getAssetPrice(ctx, assetID, typeAssetBid) -} - -// getAssetPrice gets the bid or ask price from caller's implicit private data collection -func getAssetPrice(ctx contractapi.TransactionContextInterface, assetID string, priceType string) (string, error) { - - collection, err := getClientImplicitCollectionNameAndVerifyClientOrg(ctx) - if err != nil { - return "", err - } - - assetPriceKey, err := ctx.GetStub().CreateCompositeKey(priceType, []string{assetID}) - if err != nil { - return "", fmt.Errorf("failed to create composite key: %v", err) - } - - price, err := ctx.GetStub().GetPrivateData(collection, assetPriceKey) - if err != nil { - return "", fmt.Errorf("failed to read asset price from implicit private data collection: %v", err) - } - if price == nil { - return "", fmt.Errorf("asset price does not exist: %s", assetID) - } - - return string(price), nil -} - -// QueryAssetSaleAgreements returns all of an organization's proposed sales -func (s *SmartContract) QueryAssetSaleAgreements(ctx contractapi.TransactionContextInterface) ([]Agreement, error) { - return queryAgreementsByType(ctx, typeAssetForSale) -} - -// QueryAssetBuyAgreements returns all of an organization's proposed bids -func (s *SmartContract) QueryAssetBuyAgreements(ctx contractapi.TransactionContextInterface) ([]Agreement, error) { - return queryAgreementsByType(ctx, typeAssetBid) -} - -func queryAgreementsByType(ctx contractapi.TransactionContextInterface, agreeType string) ([]Agreement, error) { - collection, err := getClientImplicitCollectionNameAndVerifyClientOrg(ctx) - if err != nil { - return nil, err - } - - // Query for any object type starting with `agreeType` - agreementsIterator, err := ctx.GetStub().GetPrivateDataByPartialCompositeKey(collection, agreeType, []string{}) - if err != nil { - return nil, fmt.Errorf("failed to read from private data collection: %v", err) - } - defer agreementsIterator.Close() - - var agreements []Agreement - for agreementsIterator.HasNext() { - resp, err := agreementsIterator.Next() - if err != nil { - return nil, err - } - - var agreement Agreement - err = json.Unmarshal(resp.Value, &agreement) - if err != nil { - return nil, err - } - - agreements = append(agreements, agreement) - } - - return agreements, nil -} - -// QueryAssetHistory returns the chain of custody for a asset since issuance -func (s *SmartContract) QueryAssetHistory(ctx contractapi.TransactionContextInterface, assetID string) ([]QueryResult, error) { - resultsIterator, err := ctx.GetStub().GetHistoryForKey(assetID) - if err != nil { - return nil, err - } - defer resultsIterator.Close() - - var results []QueryResult - for resultsIterator.HasNext() { - response, err := resultsIterator.Next() - if err != nil { - return nil, err - } - - var asset *Asset - err = json.Unmarshal(response.Value, &asset) - if err != nil { - return nil, err - } - - record := QueryResult{ - TxId: response.TxId, - Timestamp: response.Timestamp.AsTime(), - Record: asset, - } - results = append(results, record) - } - - return results, nil -} diff --git a/asset-transfer-secured-agreement/chaincode-go/go.mod b/asset-transfer-secured-agreement/chaincode-go/go.mod deleted file mode 100644 index 8599ebee..00000000 --- a/asset-transfer-secured-agreement/chaincode-go/go.mod +++ /dev/null @@ -1,28 +0,0 @@ -module github.com/hyperledger/fabric-samples/chaincode/tradingMarbles - -go 1.22.0 - -require ( - github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 - github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 -) - -require ( - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.36.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/asset-transfer-secured-agreement/chaincode-go/go.sum b/asset-transfer-secured-agreement/chaincode-go/go.sum deleted file mode 100644 index fa4d3b24..00000000 --- a/asset-transfer-secured-agreement/chaincode-go/go.sum +++ /dev/null @@ -1,61 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 h1:IhkHfrl5X/fVnmB6pWeCYCdIJRi9bxj+WTnVN8DtW3c= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0/go.mod h1:PHHaFffjw7p7n9bmCfcm7RqDqYdivNEsJdiNIKZo5Lk= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 h1:rmUoBmciB0GL/miqcbJmJbgp5QTWoJUrZo+CNxrNLF4= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0/go.mod h1:FeWeO/jwGjiME7ak3GufqKIcwkejtzrDG4QxbfKydWs= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/auction-dutch/README.md b/auction-dutch/README.md deleted file mode 100644 index 12d79b1a..00000000 --- a/auction-dutch/README.md +++ /dev/null @@ -1,615 +0,0 @@ -## Dutch auction - -This example allows you to run a [Dutch auction](https://en.wikipedia.org/wiki/Dutch_auction) that sells multiple items of the same good. All items are sold at the price that clears the auction. You also have the option of adding an auditor organization to the auction. If the organizations running the auction cannot agree, or encounter a technical error that prevents them from updating the auction, one of the auction participants can appeal to an auditor organization. The dutch auction smart contract provides an example of how create a complex signature policy by creating a protobuf and then using the policy for state based endorsement. - -This tutorial uses the example smart contract to run an auction in which a single seller wants to sell 100 tickets to multiple bidders. If you chose to add an auditor to the auction, you can appeal to the auditor to end the auction by overriding the standard auction endorsement policy. - -## Deploy the chaincode - -Change into the test network directory. -``` -cd fabric-samples/test-network -``` - -If the test network is already running, run the following command to bring the network down and start from a clean initial state. -``` -./network.sh down -``` - -You can then run the following command to deploy a new network. -``` -./network.sh up createChannel -ca -``` - -Run the following command to deploy the dutch auction smart contract. -``` -./network.sh deployCC -ccn auction -ccp ../auction-dutch/chaincode-go/ -ccep "OR('Org1MSP.peer','Org2MSP.peer')" -ccl go -``` - -Note that we deploy the smart contract with an endorsement policy of `"OR('Org1MSP.peer','Org2MSP.peer')" ` instead of using the default endorsement policy of the majority of orgs on the channel. Either Org1 or Org2 can create an auction without the endorsement of the other organization. - -## Add an auditor (optional) - -The smart contract allows you to add an auditor organization to the auction. The auditor can add bids, close the auction, or end the auction if participants cannot cooperate. In this tutorial, we will add the Org3 organization to the test network channel and install an auditor specific version of the dutch auction smart contract. This allows you to use Org3 as the auditor organization. - -From the `test-network` directory, issue the following commands to add Org3 to the channel: - -``` -cd addOrg3 -./addOrg3.sh up -``` - -Navigate back to the test network directory: -``` -cd .. -``` - -Set the following environment to interact with the test network as Org3. -``` -export PATH=${PWD}/../bin:$PATH -export FABRIC_CFG_PATH=${PWD}/../config/ -export CORE_PEER_TLS_ENABLED=true -export CORE_PEER_LOCALMSPID=Org3MSP -export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt -export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp -export CORE_PEER_ADDRESS=localhost:11051 -``` - -To deploy the smart contract on the Org3 peer, we need to use the peer lifecycle chaincode commands to install the chaincode package and approve the chaincode definition as Org3. Run the following command to package the auditor version of the dutch auction smart contract: -``` -peer lifecycle chaincode package auction.tar.gz --path ../auction-dutch/chaincode-go-auditor/ --lang golang --label auction_1 -``` -Install the chaincode package on the Org3 peer: -``` -peer lifecycle chaincode install auction.tar.gz -``` - -The next step is to approve the chaincode as the Org3 admin. This requires getting the package ID of the chaincode that we just installed. -``` -peer lifecycle chaincode queryinstalled -``` - -The command should return a response similar to the following: -``` -Installed chaincodes on peer: -Package ID: auction_1:8f0d6b6b5a616a1c2b6a9268418f2ee65718acc3c07ea12e123b189b3fb4fb14, Label: auction_1 -``` - -Save the package ID returned by the command above as an environment variable. The package ID will not be the same for all users, so you need to complete this step using the package ID returned from your console. -``` -export CC_PACKAGE_ID=auction_1:8f0d6b6b5a616a1c2b6a9268418f2ee65718acc3c07ea12e123b189b3fb4fb14 -``` - -You can now approve the auction chaincode for Org3: -``` -peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --channelID mychannel --name auction --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --signature-policy "OR('Org1MSP.peer','Org2MSP.peer')" -``` - -The command will start the dutch auction chaincode on the Org3 peer. Note that we did not update the endorsement policy before we added the auditor organization. Only Org1 and Org2 will be able create an auction. The auditor is added the endorsement policy after the auction is created. Because the auditor does not need to create an auction or create new bids, the auditor can run a different version of the smart contract than the auction participants. The auditor version of the smart contract also adds logic to check that the request is submitted by one of the auction participants before the auditor can intervene. - -## Install the application dependencies - -We will run the dutch auction using a series of Node.js applications. Change into the `application-javascript` directory: -``` -cd fabric-samples/auction-dutch/application-javascript -``` - -From this directory, run the following command to download the application dependencies if you have not done so already: -``` -npm install -``` - -## Register and enroll the application identities - -To interact with the network, you will need to enroll the Certificate Authority administrators of Org1 and Org2. You can use the `enrollAdmin.js` program for this task. Run the following command to enroll the Org1 admin: -``` -node enrollAdmin.js org1 -``` -You should see the logs of the admin wallet being created on your local file system. Now run the command to enroll the CA admin of Org2: -``` -node enrollAdmin.js org2 -``` - -We can use the CA admins of both organizations to register and enroll the identities of the seller that will create the auction and the bidders who will try to purchase the tickets. Run the following command to register and enroll the seller identity that will create the auction. The seller will belong to Org1. -``` -node registerEnrollUser.js org1 seller -``` - -You should see the logs of the seller wallet being created as well. Run the following commands to register and enroll two bidders from Org1 and another three bidders from Org2: -``` -node registerEnrollUser.js org1 bidder1 -node registerEnrollUser.js org1 bidder2 -node registerEnrollUser.js org2 bidder3 -node registerEnrollUser.js org2 bidder4 -node registerEnrollUser.js org2 bidder5 -``` - -## Create the auction - -The seller from Org1 would like to create an auction to sell 100 tickets. Run the following command to use the seller wallet to run the `createAuction.js` application. The seller needs to provide an auction ID, the item to be sold, and the quantity to be sold to create the auction. The seller uses `withAuditor` to indicate that Org3 will be added as the auditor organization. If you do not want to add an auditor, you can provide a value of `noAuditor`. You will see the application query the auction after it is created. -``` -node createAuction.js org1 seller auction1 tickets 100 withAuditor -``` - -Adding an auditor to the auction creates an endorsement policy with the auditor included. Without the auditor, each organization with sellers or bidders participating in the auction is added to the auction endorsement policy. For example, if the auction had two organizations participating in the auction, the auction endorsement policy would be `AND(Org1, Org2)`. However, if the selling organization decides to add an auditor, the auditor organization would be added to the endorsement policy. If the participating organizations disagree, or if a participant has a technical problem, the auditor can join any one of the participating organizations and agree to update the auction. Extending the example above, if the auction with two organizations added an auditor, the auction endorsement policy would be `OR(AND(Org1, Org2), AND(auditor, OR(Org1, Org2)))`. - -## Bid on the auction - -We can now use the bidder wallets to submit bids to the auction: - -### Bid as bidder1 - -Bidder1 will create a bid to purchase 50 tickets for 80 dollars. -``` -node bid.js org1 bidder1 auction1 50 80 -``` - -The application will query the bid after it is created: -``` -*** Result: Bid: { - "objectType": "bid", - "quantity": 50, - "price": 80, - "org": "Org1MSP", - "buyer": "x509::CN=bidder1,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US" -} -``` - -The `bid.js` application also prints the bidID: -``` -*** Result ***SAVE THIS VALUE*** BidID: 6630e1bb06e827a2b77023f63677fae8a0ad43126730e450d3252fa58eeb85b1 -``` - -The BidID acts as the unique identifier for the bid. This ID allows you to query the bid using the `queryBid.js` program and add the bid to the auction. Save the bidID returned by the application as an environment variable in your terminal: -``` -export BIDDER1_BID_ID=6630e1bb06e827a2b77023f63677fae8a0ad43126730e450d3252fa58eeb85b1 -``` -This value will be different for each transaction, so you will need to use the value returned in your terminal. - -Now that the bid has been created, you can submit the bid to the auction. Run the following command to submit the bid that was just created: -``` -node submitBid.js org1 bidder1 auction1 $BIDDER1_BID_ID -``` - -The hash of bid is added to the list of private bids in that have been submitted to `auction1`. Storing the hash on the public auction ledger allows users to prove the accuracy of the bids they reveal once bidding is closed. The application queries the auction to verify that the bid was added: -``` -*** Result: Auction: { - "objectType": "auction", - "item": "tickets", - "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "quantity": 100, - "organizations": [ - "Org1MSP" - ], - "privateBids": { - "\u0000bid\u0000auction1\u00006630e1bb06e827a2b77023f63677fae8a0ad43126730e450d3252fa58eeb85b1\u0000": { - "org": "Org1MSP", - "hash": "2f7a62152627d69d73e31b62cd4731d32ecc277de0eef4d30b1235891298abf7" - } - }, - "revealedBids": {}, - "winners": [], - "price": 0, - "status": "open", - "auditor": true -} -``` - -### Bid as bidder2 - -Let's submit another bid. Bidder2 would like to purchase 40 tickets for 50 dollars. -``` -node bid.js org1 bidder2 auction1 40 50 -``` - -Save the Bid ID returned by the application: -``` -export BIDDER2_BID_ID=5796569dae2e95242eadc5cf1cf8aa24f5ae072d801e7decb2547530de5a65e8 -``` - -Submit bidder2's bid to the auction: -``` -node submitBid.js org1 bidder2 auction1 $BIDDER2_BID_ID -``` - -### Bid as bidder3 from Org2 - -Bidder3 will bid for 30 tickets at 70 dollars: -``` -node bid.js org2 bidder3 auction1 30 70 -``` - -Save the Bid ID returned by the application: -``` -export BIDDER3_BID_ID=d52ea4d9b4bc428d395db2d68323bc12cc9b5c1f8617900f459ccd41c38d3c0a -``` - -Add bidder3's bid to the auction: -``` -node submitBid.js org2 bidder3 auction1 $BIDDER3_BID_ID -``` - -Because bidder3 belongs to Org2, submitting the bid will add Org2 to the list of participating organizations. You can see the Org2 MSP ID has been added to the list of `"organizations"` in the updated auction returned by the application: -``` -*** Result: Auction: { - "objectType": "auction", - "item": "tickets", - "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "quantity": 100, - "organizations": [ - "Org1MSP", - "Org2MSP" - ], - "privateBids": { - "\u0000bid\u0000auction1\u00005796569dae2e95242eadc5cf1cf8aa24f5ae072d801e7decb2547530de5a65e8\u0000": { - "org": "Org1MSP", - "hash": "598749480aa3af816a829455e1fdac25a44f31c2ae81f911f85d004f44dbbe6c" - }, - "\u0000bid\u0000auction1\u00006630e1bb06e827a2b77023f63677fae8a0ad43126730e450d3252fa58eeb85b1\u0000": { - "org": "Org1MSP", - "hash": "2f7a62152627d69d73e31b62cd4731d32ecc277de0eef4d30b1235891298abf7" - }, - "\u0000bid\u0000auction1\u0000d52ea4d9b4bc428d395db2d68323bc12cc9b5c1f8617900f459ccd41c38d3c0a\u0000": { - "org": "Org2MSP", - "hash": "bf1e9fb80ea3e29780fe13b4781b6dad28fa83b4b5db68bd7e90252875d152fb" - } - }, - "revealedBids": {}, - "winners": [], - "price": 0, - "status": "open", - "auditor": true -} -``` - -Now that a bid from Org2 has been added to the auction, any updates to the auction need to be endorsed by the Org2 peer. The applications will use the `"organizations"` field to specify which organizations need to endorse submitting a new bid, revealing a bid, or updating the auction status. - -### Bid as bidder4 - -Bidder4 from Org2 would like to purchase 15 tickets for 60 dollars: -``` -node bid.js org2 bidder4 auction1 15 60 -``` - -Save the Bid ID returned by the application: -``` -export BIDDER4_BID_ID=c6464f984bb01e639a46e58b94c496e8bbd829b5e4fa7ffcc150d9a565d45684 -``` - -Add bidder4's bid to the auction: -``` -node submitBid.js org2 bidder4 auction1 $BIDDER4_BID_ID -``` - -### Bid as bidder5 - -Bidder5 from Org2 will bid for 20 tickets at 60 dollars: -``` -node bid.js org2 bidder5 auction1 20 60 -``` - -Save the Bid ID returned by the application: -``` -export BIDDER5_BID_ID=f4024ab09b4dacf0a636927414850dde2a2a5e8ec4601e2a0071f5c233248207 -``` - -Add bidder5's bid to the auction: -``` -node submitBid.js org2 bidder5 auction1 $BIDDER5_BID_ID -``` - - -## Close the auction - -Now that all five bidders have joined the auction, the seller would like to close the auction and allow buyers to reveal their bids. The seller identity that created the auction needs to submit the transaction: -``` -node closeAuction.js org1 seller auction1 -``` - -The application will query the auction to allow you to verify that the auction status has changed to closed. - -## Reveal bids - -After the auction is closed, bidders can try to win the auction by revealing their bids. The transaction to reveal a bid needs to pass four checks: -1. The auction is closed. -2. The transaction was submitted by the identity that created the bid. -3. The hash of the revealed bid matches the hash of the bid on the channel ledger. This confirms that the bid is the same as the bid that is stored in the private data collection. -4. The hash of the revealed bid matches the hash that was submitted to the auction. This confirms that the bid was not altered after the auction was closed. - -Use the `revealBid.js` application to reveal the bid of Bidder1: -``` -node revealBid.js org1 bidder1 auction1 $BIDDER1_BID_ID -``` - -The full bid details, including the quantity and price, are now visible: -``` -*** Result: Auction: { - "objectType": "auction", - "item": "tickets", - "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "quantity": 100, - "organizations": [ - "Org1MSP", - "Org2MSP" - ], - "privateBids": { - "\u0000bid\u0000auction1\u00005796569dae2e95242eadc5cf1cf8aa24f5ae072d801e7decb2547530de5a65e8\u0000": { - "org": "Org1MSP", - "hash": "598749480aa3af816a829455e1fdac25a44f31c2ae81f911f85d004f44dbbe6c" - }, - "\u0000bid\u0000auction1\u00006630e1bb06e827a2b77023f63677fae8a0ad43126730e450d3252fa58eeb85b1\u0000": { - "org": "Org1MSP", - "hash": "2f7a62152627d69d73e31b62cd4731d32ecc277de0eef4d30b1235891298abf7" - }, - "\u0000bid\u0000auction1\u0000c6464f984bb01e639a46e58b94c496e8bbd829b5e4fa7ffcc150d9a565d45684\u0000": { - "org": "Org2MSP", - "hash": "eefcadf8e9e5cb8322a6e642ab6d5512d62e6d68f37a72b00f5b0d9e580eddb9" - }, - "\u0000bid\u0000auction1\u0000d52ea4d9b4bc428d395db2d68323bc12cc9b5c1f8617900f459ccd41c38d3c0a\u0000": { - "org": "Org2MSP", - "hash": "bf1e9fb80ea3e29780fe13b4781b6dad28fa83b4b5db68bd7e90252875d152fb" - }, - "\u0000bid\u0000auction1\u0000f4024ab09b4dacf0a636927414850dde2a2a5e8ec4601e2a0071f5c233248207\u0000": { - "org": "Org2MSP", - "hash": "de82232141bac06ea3818146fb650dc9930d45b9ceab506ac66942b119eec094" - } - }, - "revealedBids": { - "\u0000bid\u0000auction1\u00006630e1bb06e827a2b77023f63677fae8a0ad43126730e450d3252fa58eeb85b1\u0000": { - "objectType": "bid", - "quantity": 50, - "price": 80, - "org": "Org1MSP", - "buyer": "x509::CN=bidder1,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US" - } - }, - "winners": [], - "price": 0, - "status": "closed", - "auditor": true -} -``` -We will add three more bidders, the second bidder from Org1 and two bidders from Org2. Run the following commands to reveal the bidders: -``` -node revealBid.js org1 bidder2 auction1 $BIDDER2_BID_ID -node revealBid.js org2 bidder4 auction1 $BIDDER4_BID_ID -node revealBid.js org2 bidder5 auction1 $BIDDER5_BID_ID -``` - -Let's try to end the auction using the seller identity and see what happens. - -``` -node endAuction.js org1 seller auction1 -``` - -The output should look something like the following: - -``` ---> Submit the transaction to end the auction -2021-01-28T16:47:27.501Z - error: [DiscoveryHandler]: compareProposalResponseResults[undefined] - read/writes result sets do not match index=1 -2021-01-28T16:47:27.503Z - error: [Transaction]: Error: No valid responses from any peers. Errors: - peer=undefined, status=grpc, message=Peer endorsements do not match -******** FAILED to submit bid: Error: No valid responses from any peers. Errors: - peer=undefined, status=grpc, message=Peer endorsements do not match -``` - -Instead of ending the auction, the transaction results in an endorsement policy failure. The end of the auction needs to be endorsed by Org2. Before endorsing the transaction, the Org2 peer queries its private data collection for any winning bids that have not yet been revealed. Because the price that would clear the auction with the currently revealed bids is lower than the bid of Bidder3, the Org2 peer refuses to endorse the transaction that would end the auction. - -In order to end the auction, Org1 would either need to wait for Org2 to reveal the final bid or appeal to the auditor. Depending on if you created the organization with an auditor, you can end the auction with either set of steps. - -## End the auction using an auditor - -If Org2 is unable to endorse the transaction to end the auction, Org1 can ask the auditor to intervene. The following program gets an endorsement from the Org3 auditor and Org1 to end the auction. As a result, the transaction would meet the auditor component of the state based endorsement policy. -``` -node endAuctionwithAuditor org1 seller auction1 -``` - -Even though Org2 has not agreed to the end of the auction, the endorsement Org1 is sufficient to end the auction if the auditor agrees. As part of ending the auction, both Org1 and the auditor need to calculate the same price and the same set of winners. Each winning bidder is listed next to the quantity that was allocated to them. -``` -*** Result: Auction: { - "objectType": "auction", - "item": "tickets", - "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "quantity": 100, - "organizations": [ - "Org1MSP", - "Org2MSP" - ], - "privateBids": { - "\u0000bid\u0000auction1\u00005796569dae2e95242eadc5cf1cf8aa24f5ae072d801e7decb2547530de5a65e8\u0000": { - "org": "Org1MSP", - "hash": "598749480aa3af816a829455e1fdac25a44f31c2ae81f911f85d004f44dbbe6c" - }, - "\u0000bid\u0000auction1\u00006630e1bb06e827a2b77023f63677fae8a0ad43126730e450d3252fa58eeb85b1\u0000": { - "org": "Org1MSP", - "hash": "2f7a62152627d69d73e31b62cd4731d32ecc277de0eef4d30b1235891298abf7" - }, - "\u0000bid\u0000auction1\u0000c6464f984bb01e639a46e58b94c496e8bbd829b5e4fa7ffcc150d9a565d45684\u0000": { - "org": "Org2MSP", - "hash": "eefcadf8e9e5cb8322a6e642ab6d5512d62e6d68f37a72b00f5b0d9e580eddb9" - }, - "\u0000bid\u0000auction1\u0000d52ea4d9b4bc428d395db2d68323bc12cc9b5c1f8617900f459ccd41c38d3c0a\u0000": { - "org": "Org2MSP", - "hash": "bf1e9fb80ea3e29780fe13b4781b6dad28fa83b4b5db68bd7e90252875d152fb" - }, - "\u0000bid\u0000auction1\u0000f4024ab09b4dacf0a636927414850dde2a2a5e8ec4601e2a0071f5c233248207\u0000": { - "org": "Org2MSP", - "hash": "de82232141bac06ea3818146fb650dc9930d45b9ceab506ac66942b119eec094" - } - }, - "revealedBids": { - "\u0000bid\u0000auction1\u00005796569dae2e95242eadc5cf1cf8aa24f5ae072d801e7decb2547530de5a65e8\u0000": { - "objectType": "bid", - "quantity": 40, - "price": 50, - "org": "Org1MSP", - "buyer": "x509::CN=bidder2,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US" - }, - "\u0000bid\u0000auction1\u00006630e1bb06e827a2b77023f63677fae8a0ad43126730e450d3252fa58eeb85b1\u0000": { - "objectType": "bid", - "quantity": 50, - "price": 80, - "org": "Org1MSP", - "buyer": "x509::CN=bidder1,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US" - }, - "\u0000bid\u0000auction1\u0000c6464f984bb01e639a46e58b94c496e8bbd829b5e4fa7ffcc150d9a565d45684\u0000": { - "objectType": "bid", - "quantity": 15, - "price": 60, - "org": "Org2MSP", - "buyer": "x509::CN=bidder4,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK" - }, - "\u0000bid\u0000auction1\u0000f4024ab09b4dacf0a636927414850dde2a2a5e8ec4601e2a0071f5c233248207\u0000": { - "objectType": "bid", - "quantity": 20, - "price": 60, - "org": "Org2MSP", - "buyer": "x509::CN=bidder5,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK" - } - }, - "winners": [ - { - "buyer": "x509::CN=bidder1,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "quantity": 50 - }, - { - "buyer": "x509::CN=bidder4,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK", - "quantity": 15 - }, - { - "buyer": "x509::CN=bidder5,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK", - "quantity": 20 - }, - { - "buyer": "x509::CN=bidder2,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "quantity": 15 - } - ], - "price": 50, - "status": "ended", - "auditor": true -} -``` - -The auction allocates tickets to the highest bids first. Because all 100 tickets are sold after allocating tickets to the bid that was submitted at 50, 50 is the `"price"` that clears the auction. - -## End the auction without an auditor - -If we did not add an auditor to the auction, we need to add the remaining bid so that Org2 will endorse ending the auction. -``` -node revealBid.js org2 bidder3 auction1 $BIDDER3_BID_ID -``` - -Now that all the winning bids have been revealed, we can submit the transaction to end the auction once more. -``` -node endAuction org1 seller auction1 -``` - -The transaction was successfully endorsed by both Org1 and Org2, who both calculated the same price and winners of the auction. Each winning bidder is listed next to the quantity that was allocated to them. -``` -*** Result: Auction: { - "objectType": "auction", - "item": "tickets", - "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "quantity": 100, - "organizations": [ - "Org1MSP", - "Org2MSP" - ], - "privateBids": { - "\u0000bid\u0000auction1\u0000482b2a68fbbfae329b0b4bc9d70b90f3a55fdcbae5f5274dec34d438efb6847e\u0000": { - "org": "Org1MSP", - "hash": "2f7a62152627d69d73e31b62cd4731d32ecc277de0eef4d30b1235891298abf7" - }, - "\u0000bid\u0000auction1\u000048d93017ac65cff0dd23406cc29918724fd84c8e7014eee30fd492fef760e6a4\u0000": { - "org": "Org2MSP", - "hash": "bf1e9fb80ea3e29780fe13b4781b6dad28fa83b4b5db68bd7e90252875d152fb" - }, - "\u0000bid\u0000auction1\u00005ba4c856224cdc8209b0e42f30a757331e3fb8a8b660b64a55e1bcf688b745ad\u0000": { - "org": "Org1MSP", - "hash": "598749480aa3af816a829455e1fdac25a44f31c2ae81f911f85d004f44dbbe6c" - }, - "\u0000bid\u0000auction1\u000063c8a192dae1332ae42af890f8a966fea2ae8365ca9746447e014a7c0494d64e\u0000": { - "org": "Org2MSP", - "hash": "de82232141bac06ea3818146fb650dc9930d45b9ceab506ac66942b119eec094" - }, - "\u0000bid\u0000auction1\u000066ff6d8bbe81e98654fc417915808031d49e93cd8d7475f15317d801317254fa\u0000": { - "org": "Org2MSP", - "hash": "eefcadf8e9e5cb8322a6e642ab6d5512d62e6d68f37a72b00f5b0d9e580eddb9" - } - }, - "revealedBids": { - "\u0000bid\u0000auction1\u0000482b2a68fbbfae329b0b4bc9d70b90f3a55fdcbae5f5274dec34d438efb6847e\u0000": { - "objectType": "bid", - "quantity": 50, - "price": 80, - "org": "Org1MSP", - "buyer": "x509::CN=bidder1,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US" - }, - "\u0000bid\u0000auction1\u000048d93017ac65cff0dd23406cc29918724fd84c8e7014eee30fd492fef760e6a4\u0000": { - "objectType": "bid", - "quantity": 30, - "price": 70, - "org": "Org2MSP", - "buyer": "x509::CN=bidder3,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK" - }, - "\u0000bid\u0000auction1\u00005ba4c856224cdc8209b0e42f30a757331e3fb8a8b660b64a55e1bcf688b745ad\u0000": { - "objectType": "bid", - "quantity": 40, - "price": 50, - "org": "Org1MSP", - "buyer": "x509::CN=bidder2,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US" - }, - "\u0000bid\u0000auction1\u000063c8a192dae1332ae42af890f8a966fea2ae8365ca9746447e014a7c0494d64e\u0000": { - "objectType": "bid", - "quantity": 20, - "price": 60, - "org": "Org2MSP", - "buyer": "x509::CN=bidder5,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK" - }, - "\u0000bid\u0000auction1\u000066ff6d8bbe81e98654fc417915808031d49e93cd8d7475f15317d801317254fa\u0000": { - "objectType": "bid", - "quantity": 15, - "price": 60, - "org": "Org2MSP", - "buyer": "x509::CN=bidder4,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK" - } - }, - "winners": [ - { - "buyer": "x509::CN=bidder1,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "quantity": 50 - }, - { - "buyer": "x509::CN=bidder3,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK", - "quantity": 30 - }, - { - "buyer": "x509::CN=bidder4,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK", - "quantity": 15 - }, - { - "buyer": "x509::CN=bidder5,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK", - "quantity": 5 - } - ], - "price": 60, - "status": "ended", - "auditor": false -} -``` - -The auction allocates tickets to the highest bids first. Because all 100 tickets are sold after allocating tickets to the bids that were submitted at 60, 60 is the `"price"` that clears the auction. The first 80 tickets are allocated to Bidder1 and Bidder3. The remaining 20 tickers are allocated to Bidder4 and Bidder5. When bids are tied, the auction smart contract fills the smaller bids first. As a result, Bidder4 is awarded their full bid of 15 tickets, while Bidder5 is allocated the remaining 5 tickets. - -## Clean up - -When your are done using the auction smart contract, you can bring down the network and clean up the environment. In the `auction-dutch/application-javascript` directory, run the following command to remove the wallets used to run the applications: -``` -rm -rf wallet -``` - -You can then navigate to the test network directory and bring down the network: -```` -cd ../../test-network/ -./network.sh down -```` diff --git a/auction-dutch/application-javascript/.eslintignore b/auction-dutch/application-javascript/.eslintignore deleted file mode 100644 index 15958470..00000000 --- a/auction-dutch/application-javascript/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -coverage diff --git a/auction-dutch/application-javascript/.eslintrc.js b/auction-dutch/application-javascript/.eslintrc.js deleted file mode 100644 index 20d4fcbd..00000000 --- a/auction-dutch/application-javascript/.eslintrc.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -module.exports = { - env: { - node: true, - mocha: true - }, - parserOptions: { - ecmaVersion: 8, - sourceType: 'script' - }, - extends: 'eslint:recommended', - rules: { - indent: ['error', 'tab'], - 'linebreak-style': ['error', 'unix'], - quotes: ['error', 'single'], - semi: ['error', 'always'], - 'no-unused-vars': ['error', { args: 'none' }], - 'no-console': 'off', - curly: 'error', - eqeqeq: 'error', - 'no-throw-literal': 'error', - strict: 'error', - 'no-var': 'error', - 'dot-notation': 'error', - 'no-trailing-spaces': 'error', - 'no-use-before-define': 'error', - 'no-useless-call': 'error', - 'no-with': 'error', - 'operator-linebreak': 'error', - yoda: 'error', - 'quote-props': ['error', 'as-needed'] - } -}; diff --git a/auction-dutch/application-javascript/bid.js b/auction-dutch/application-javascript/bid.js deleted file mode 100644 index aff30d65..00000000 --- a/auction-dutch/application-javascript/bid.js +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString } = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function bid (ccp, wallet, user, orgMSP, auctionID, quantity, price) { - try { - const gateway = new Gateway(); - // connect using Discovery enabled - - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - console.log('\n--> Evaluate Transaction: get your client ID'); - const buyer = await contract.evaluateTransaction('GetSubmittingClientIdentity'); - console.log('*** Result: Buyer ID is ' + buyer.toString()); - - const bidData = { objectType: 'bid', quantity: parseInt(quantity), price: parseInt(price), org: orgMSP, buyer: buyer.toString() }; - - const statefulTxn = contract.createTransaction('Bid'); - statefulTxn.setEndorsingOrganizations(orgMSP); - const tmapData = Buffer.from(JSON.stringify(bidData)); - statefulTxn.setTransient({ - bid: tmapData - }); - - const bidID = statefulTxn.getTransactionId(); - - console.log('\n--> Submit Transaction: Create the bid that is stored in your private data collection of your organization'); - await statefulTxn.submit(auctionID); - console.log('*** Result: committed'); - console.log('*** Result ***SAVE THIS VALUE*** BidID: ' + bidID.toString()); - - console.log('\n--> Evaluate Transaction: read the bid that was just created'); - const result = await contract.evaluateTransaction('QueryBid', auctionID, bidID); - console.log('*** Result: Bid: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - -async function main () { - try { - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined || process.argv[5] === undefined || - process.argv[6] === undefined) { - console.log('Usage: node bid.js org userID auctionID quantity price'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - const quantity = process.argv[5]; - const price = process.argv[6]; - - if (org === 'Org1' || org === 'org1') { - const orgMSP = 'Org1MSP'; - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await bid(ccp, wallet, user, orgMSP, auctionID, quantity, price); - } else if (org === 'Org2' || org === 'org2') { - const orgMSP = 'Org2MSP'; - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await bid(ccp, wallet, user, orgMSP, auctionID, quantity, price); - } else { - console.log('Usage: node bid.js org userID auctionID quantity price'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - process.exit(1); - } -} - -main(); diff --git a/auction-dutch/application-javascript/closeAuction.js b/auction-dutch/application-javascript/closeAuction.js deleted file mode 100644 index 55410fb5..00000000 --- a/auction-dutch/application-javascript/closeAuction.js +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString } = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function closeAuction (ccp, wallet, user, auctionID) { - try { - const gateway = new Gateway(); - // connect using Discovery enabled - - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - // Query the auction to get the list of endorsing orgs. - // console.log('\n--> Evaluate Transaction: query the auction you want to close'); - const auctionString = await contract.evaluateTransaction('QueryAuction', auctionID); - // console.log('*** Result: Bid: ' + prettyJSONString(auctionString.toString())); - const auctionJSON = JSON.parse(auctionString); - - const statefulTxn = contract.createTransaction('CloseAuction'); - - if (auctionJSON.organizations.length === 2) { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0], auctionJSON.organizations[1]); - } else { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0]); - } - - console.log('\n--> Submit Transaction: close auction'); - await statefulTxn.submit(auctionID); - console.log('*** Result: committed'); - - console.log('\n--> Evaluate Transaction: query the updated auction'); - const result = await contract.evaluateTransaction('QueryAuction', auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - process.exit(1); - } -} - -async function main () { - try { - if (process.argv[2] === undefined || process.argv[3] === undefined || process.argv[4] === undefined) { - console.log('Usage: node closeAuction.js org userID auctionID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await closeAuction(ccp, wallet, user, auctionID); - } else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await closeAuction(ccp, wallet, user, auctionID); - } else { - console.log('Usage: node closeAuction.js org userID auctionID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - -main(); diff --git a/auction-dutch/application-javascript/createAuction.js b/auction-dutch/application-javascript/createAuction.js deleted file mode 100644 index 2f46a248..00000000 --- a/auction-dutch/application-javascript/createAuction.js +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString } = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function createAuction (ccp, wallet, user, auctionID, item, quantity, auditor) { - try { - const gateway = new Gateway(); - // connect using Discovery enabled - - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - const statefulTxn = contract.createTransaction('CreateAuction'); - - console.log('\n--> Submit Transaction: Propose a new auction'); - await statefulTxn.submit(auctionID, item, parseInt(quantity), auditor); - console.log('*** Result: committed'); - - console.log('\n--> Evaluate Transaction: query the auction that was just created'); - const result = await contract.evaluateTransaction('QueryAuction', auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - } -} - -async function main () { - try { - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined || process.argv[5] === undefined || - process.argv[6] === undefined) { - console.log('Usage: node createAuction.js org userID auctionID item quantity'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - const item = process.argv[5]; - const quantity = process.argv[6]; - const auditor = process.argv[7]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await createAuction(ccp, wallet, user, auctionID, item, quantity, auditor); - } else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await createAuction(ccp, wallet, user, auctionID, item, quantity, auditor); - } else { - console.log('Usage: node createAuction.js org userID auctionID item quantity'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - } -} - -main(); diff --git a/auction-dutch/application-javascript/endAuction.js b/auction-dutch/application-javascript/endAuction.js deleted file mode 100644 index daec75d2..00000000 --- a/auction-dutch/application-javascript/endAuction.js +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString } = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function endAuction (ccp, wallet, user, auctionID) { - try { - const gateway = new Gateway(); - // connect using Discovery enabled - - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - // Query the auction to get the list of endorsing orgs. - // console.log('\n--> Evaluate Transaction: query the auction you want to end'); - const auctionString = await contract.evaluateTransaction('QueryAuction', auctionID); - // console.log('*** Result: Bid: ' + prettyJSONString(auctionString.toString())); - const auctionJSON = JSON.parse(auctionString); - - const statefulTxn = contract.createTransaction('EndAuction'); - - if (auctionJSON.organizations.length === 2) { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0], auctionJSON.organizations[1]); - } else { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0]); - } - - console.log('\n--> Submit the transaction to end the auction'); - await statefulTxn.submit(auctionID); - console.log('*** Result: committed'); - - console.log('\n--> Evaluate Transaction: query the updated auction'); - const result = await contract.evaluateTransaction('QueryAuction', auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - process.exit(1); - } -} - -async function main () { - try { - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined) { - console.log('Usage: node endAuction.js org userID auctionID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await endAuction(ccp, wallet, user, auctionID); - } else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await endAuction(ccp, wallet, user, auctionID); - } else { - console.log('Usage: node endAuction.js org userID auctionID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - -main(); diff --git a/auction-dutch/application-javascript/endAuctionwithAuditor.js b/auction-dutch/application-javascript/endAuctionwithAuditor.js deleted file mode 100644 index 5e085258..00000000 --- a/auction-dutch/application-javascript/endAuctionwithAuditor.js +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString } = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function endAuction (ccp, wallet, org, user, auctionID) { - try { - const gateway = new Gateway(); - // connect using Discovery enabled - - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - const statefulTxn = contract.createTransaction('EndAuction'); - - statefulTxn.setEndorsingOrganizations(org, 'Org3MSP'); - - console.log('\n--> Submit the transaction to end the auction'); - await statefulTxn.submit(auctionID); - console.log('*** Result: committed'); - - console.log('\n--> Evaluate Transaction: query the updated auction'); - const result = await contract.evaluateTransaction('QueryAuction', auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - process.exit(1); - } -} - -async function main () { - try { - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined) { - console.log('Usage: node endAuction.js org userID auctionID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - - if (org === 'Org1' || org === 'org1') { - const orgMSP = 'Org1MSP'; - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await endAuction(ccp, wallet, orgMSP, user, auctionID); - } else if (org === 'Org2' || org === 'org2') { - const orgMSP = 'Org2MSP'; - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await endAuction(ccp, wallet, orgMSP, user, auctionID); - } else { - console.log('Usage: node endAuction.js org userID auctionID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - -main(); diff --git a/auction-dutch/application-javascript/enrollAdmin.js b/auction-dutch/application-javascript/enrollAdmin.js deleted file mode 100644 index 90998fd8..00000000 --- a/auction-dutch/application-javascript/enrollAdmin.js +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Wallets } = require('fabric-network'); -const FabricCAServices = require('fabric-ca-client'); -const path = require('path'); -const { buildCAClient, enrollAdmin } = require('../../test-application/javascript/CAUtil.js'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); - -const mspOrg1 = 'Org1MSP'; -const mspOrg2 = 'Org2MSP'; - -async function connectToOrg1CA () { - console.log('\n--> Enrolling the Org1 CA admin'); - const ccpOrg1 = buildCCPOrg1(); - const caOrg1Client = buildCAClient(FabricCAServices, ccpOrg1, 'ca.org1.example.com'); - - const walletPathOrg1 = path.join(__dirname, 'wallet/org1'); - const walletOrg1 = await buildWallet(Wallets, walletPathOrg1); - - await enrollAdmin(caOrg1Client, walletOrg1, mspOrg1); -} - -async function connectToOrg2CA () { - console.log('\n--> Enrolling the Org2 CA admin'); - const ccpOrg2 = buildCCPOrg2(); - const caOrg2Client = buildCAClient(FabricCAServices, ccpOrg2, 'ca.org2.example.com'); - - const walletPathOrg2 = path.join(__dirname, 'wallet/org2'); - const walletOrg2 = await buildWallet(Wallets, walletPathOrg2); - - await enrollAdmin(caOrg2Client, walletOrg2, mspOrg2); -} -async function main () { - if (process.argv[2] === undefined) { - console.log('Usage: node enrollAdmin.js Org'); - process.exit(1); - } - - const org = process.argv[2]; - - try { - if (org === 'Org1' || org === 'org1') { - await connectToOrg1CA(); - } else if (org === 'Org2' || org === 'org2') { - await connectToOrg2CA(); - } else { - console.log('Usage: node registerUser.js org userID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`Error in enrolling admin: ${error}`); - process.exit(1); - } -} - -main(); diff --git a/auction-dutch/application-javascript/package.json b/auction-dutch/application-javascript/package.json deleted file mode 100644 index 33954681..00000000 --- a/auction-dutch/application-javascript/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "auction", - "version": "1.0.0", - "description": "auction application implemented in JavaScript", - "engines": { - "node": ">=12", - "npm": ">=5" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "scripts": { - "lint": "eslint *.js" - }, - "dependencies": { - "fabric-ca-client": "^2.2.19", - "fabric-network": "^2.2.19" - }, - "devDependencies": { - "eslint": "^7.20.0", - "eslint-config-standard": "^16.0.2", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.3.1" - } -} diff --git a/auction-dutch/application-javascript/queryAuction.js b/auction-dutch/application-javascript/queryAuction.js deleted file mode 100644 index 06471d5e..00000000 --- a/auction-dutch/application-javascript/queryAuction.js +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString } = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function queryAuction (ccp, wallet, user, auctionID) { - try { - const gateway = new Gateway(); - // connect using Discovery enabled - - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - console.log('\n--> Evaluate Transaction: query the auction'); - const result = await contract.evaluateTransaction('QueryAuction', auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - } -} - -async function main () { - try { - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined) { - console.log('Usage: node queryAuction.js org userID auctionID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await queryAuction(ccp, wallet, user, auctionID); - } else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await queryAuction(ccp, wallet, user, auctionID); - } else { - console.log('Usage: node queryAuction.js org userID auctionID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - } -} - -main(); diff --git a/auction-dutch/application-javascript/queryBid.js b/auction-dutch/application-javascript/queryBid.js deleted file mode 100644 index 1bb17e7d..00000000 --- a/auction-dutch/application-javascript/queryBid.js +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString } = require('../../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function queryBid (ccp, wallet, user, auctionID, bidID) { - try { - const gateway = new Gateway(); - // connect using Discovery enabled - - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - console.log('\n--> Evaluate Transaction: read bid from private data store'); - const result = await contract.evaluateTransaction('QueryBid', auctionID, bidID); - console.log('*** Result: Bid: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - } -} - -async function main () { - try { - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined || process.argv[5] === undefined) { - console.log('Usage: node bid.js org userID auctionID bidID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - const bidID = process.argv[5]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await queryBid(ccp, wallet, user, auctionID, bidID); - } else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await queryBid(ccp, wallet, user, auctionID, bidID); - } else { - console.log('Usage: node bid.js org userID auctionID bidID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - } -} - -main(); diff --git a/auction-dutch/application-javascript/registerEnrollUser.js b/auction-dutch/application-javascript/registerEnrollUser.js deleted file mode 100644 index 9b7abc32..00000000 --- a/auction-dutch/application-javascript/registerEnrollUser.js +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Wallets } = require('fabric-network'); -const FabricCAServices = require('fabric-ca-client'); -const path = require('path'); -const { buildCAClient, registerAndEnrollUser } = require('../../test-application/javascript/CAUtil.js'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); - -const mspOrg1 = 'Org1MSP'; -const mspOrg2 = 'Org2MSP'; - -async function connectToOrg1CA (UserID) { - console.log('\n--> Register and enrolling new user'); - const ccpOrg1 = buildCCPOrg1(); - const caOrg1Client = buildCAClient(FabricCAServices, ccpOrg1, 'ca.org1.example.com'); - - const walletPathOrg1 = path.join(__dirname, 'wallet/org1'); - const walletOrg1 = await buildWallet(Wallets, walletPathOrg1); - - await registerAndEnrollUser(caOrg1Client, walletOrg1, mspOrg1, UserID, 'org1.department1'); -} - -async function connectToOrg2CA (UserID) { - console.log('\n--> Register and enrolling new user'); - const ccpOrg2 = buildCCPOrg2(); - const caOrg2Client = buildCAClient(FabricCAServices, ccpOrg2, 'ca.org2.example.com'); - - const walletPathOrg2 = path.join(__dirname, 'wallet/org2'); - const walletOrg2 = await buildWallet(Wallets, walletPathOrg2); - - await registerAndEnrollUser(caOrg2Client, walletOrg2, mspOrg2, UserID, 'org2.department1'); -} -async function main () { - if (process.argv[2] === undefined && process.argv[3] === undefined) { - console.log('Usage: node registerEnrollUser.js org userID'); - process.exit(1); - } - - const org = process.argv[2]; - const userId = process.argv[3]; - - try { - if (org === 'Org1' || org === 'org1') { - await connectToOrg1CA(userId); - } else if (org === 'Org2' || org === 'org2') { - await connectToOrg2CA(userId); - } else { - console.log('Usage: node registerEnrollUser.js org userID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`Error in enrolling admin: ${error}`); - process.exit(1); - } -} - -main(); diff --git a/auction-dutch/application-javascript/revealBid.js b/auction-dutch/application-javascript/revealBid.js deleted file mode 100644 index b1fc8dc9..00000000 --- a/auction-dutch/application-javascript/revealBid.js +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString } = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function addBid (ccp, wallet, user, auctionID, bidID) { - try { - const gateway = new Gateway(); - // connect using Discovery enabled - - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - console.log('\n--> Evaluate Transaction: read your bid'); - const bidString = await contract.evaluateTransaction('QueryBid', auctionID, bidID); - const bidJSON = JSON.parse(bidString); - - // console.log('\n--> Evaluate Transaction: query the auction you want to join'); - const auctionString = await contract.evaluateTransaction('QueryAuction', auctionID); - // console.log('*** Result: Bid: ' + prettyJSONString(auctionString.toString())); - const auctionJSON = JSON.parse(auctionString); - - const bidData = { objectType: 'bid', quantity: parseInt(bidJSON.quantity), price: parseInt(bidJSON.price), org: bidJSON.org, buyer: bidJSON.buyer }; - console.log('*** Result: Bid: ' + JSON.stringify(bidData, null, 2)); - - const statefulTxn = contract.createTransaction('RevealBid'); - const tmapData = Buffer.from(JSON.stringify(bidData)); - statefulTxn.setTransient({ - bid: tmapData - }); - - if (auctionJSON.organizations.length === 2) { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0], auctionJSON.organizations[1]); - } else { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0]); - } - - await statefulTxn.submit(auctionID, bidID); - - console.log('\n--> Evaluate Transaction: query the auction to see that our bid was added'); - const result = await contract.evaluateTransaction('QueryAuction', auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - process.exit(1); - } -} - -async function main () { - try { - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined || process.argv[5] === undefined) { - console.log('Usage: node revealBid.js org userID auctionID bidID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - const bidID = process.argv[5]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await addBid(ccp, wallet, user, auctionID, bidID); - } else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await addBid(ccp, wallet, user, auctionID, bidID); - } else { - console.log('Usage: node revealBid.js org userID auctionID bidID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - -main(); diff --git a/auction-dutch/application-javascript/submitBid.js b/auction-dutch/application-javascript/submitBid.js deleted file mode 100644 index adb3070f..00000000 --- a/auction-dutch/application-javascript/submitBid.js +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString } = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function submitBid (ccp, wallet, user, auctionID, bidID) { - try { - const gateway = new Gateway(); - // connect using Discovery enabled - - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - console.log('\n--> Evaluate Transaction: query the auction you want to join'); - const auctionString = await contract.evaluateTransaction('QueryAuction', auctionID); - const auctionJSON = JSON.parse(auctionString); - - const statefulTxn = contract.createTransaction('SubmitBid'); - - if (auctionJSON.organizations.length === 2) { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0], auctionJSON.organizations[1]); - } else { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0]); - } - - console.log('\n--> Submit Transaction: add bid to the auction'); - await statefulTxn.submit(auctionID, bidID); - - console.log('\n--> Evaluate Transaction: query the auction to see that our bid was added'); - const result = await contract.evaluateTransaction('QueryAuction', auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - process.exit(1); - } -} - -async function main () { - try { - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined || process.argv[5] === undefined) { - console.log('Usage: node submitBid.js org userID auctionID bidID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - const bidID = process.argv[5]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await submitBid(ccp, wallet, user, auctionID, bidID); - } else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await submitBid(ccp, wallet, user, auctionID, bidID); - } else { - console.log('Usage: node submitBid.js org userID auctionID bidID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - -main(); diff --git a/auction-dutch/chaincode-go-auditor/go.mod b/auction-dutch/chaincode-go-auditor/go.mod deleted file mode 100644 index efdae2fc..00000000 --- a/auction-dutch/chaincode-go-auditor/go.mod +++ /dev/null @@ -1,28 +0,0 @@ -module github.com/hyperledger/fabric-samples/auction/dutch-auction/chaincode-go-auditor - -go 1.22.0 - -require ( - github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 - github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 - google.golang.org/protobuf v1.36.1 -) - -require ( - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/auction-dutch/chaincode-go-auditor/go.sum b/auction-dutch/chaincode-go-auditor/go.sum deleted file mode 100644 index fa4d3b24..00000000 --- a/auction-dutch/chaincode-go-auditor/go.sum +++ /dev/null @@ -1,61 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 h1:IhkHfrl5X/fVnmB6pWeCYCdIJRi9bxj+WTnVN8DtW3c= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0/go.mod h1:PHHaFffjw7p7n9bmCfcm7RqDqYdivNEsJdiNIKZo5Lk= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 h1:rmUoBmciB0GL/miqcbJmJbgp5QTWoJUrZo+CNxrNLF4= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0/go.mod h1:FeWeO/jwGjiME7ak3GufqKIcwkejtzrDG4QxbfKydWs= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/auction-dutch/chaincode-go-auditor/smart-contract/auction.go b/auction-dutch/chaincode-go-auditor/smart-contract/auction.go deleted file mode 100644 index c56daedd..00000000 --- a/auction-dutch/chaincode-go-auditor/smart-contract/auction.go +++ /dev/null @@ -1,440 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package auction - -import ( - "bytes" - "crypto/sha256" - "encoding/json" - "errors" - "fmt" - "sort" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -type SmartContract struct { - contractapi.Contract -} - -// Auction data -type Auction struct { - Type string `json:"objectType"` - ItemSold string `json:"item"` - Seller string `json:"seller"` - Quantity int `json:"quantity"` - Orgs []string `json:"organizations"` - PrivateBids map[string]BidHash `json:"privateBids"` - RevealedBids map[string]FullBid `json:"revealedBids"` - Winners []Winners `json:"winners"` - Price int `json:"price"` - Status string `json:"status"` - Auditor bool `json:"auditor"` -} - -// FullBid is the structure of a revealed bid -type FullBid struct { - Type string `json:"objectType"` - Quantity int `json:"quantity"` - Price int `json:"price"` - Org string `json:"org"` - Buyer string `json:"buyer"` -} - -// BidHash is the structure of a private bid -type BidHash struct { - Org string `json:"org"` - Hash string `json:"hash"` -} - -// Winners stores the winners of the auction -type Winners struct { - Buyer string `json:"buyer"` - Quantity int `json:"quantity"` -} - -const bidKeyType = "bid" - -// SubmitBid is used by the bidder to add the hash of that bid stored in private data to the -// auction. Note that this function alters the auction in private state, and needs -// to meet the auction endorsement policy. Transaction ID is used identify the bid -func (s *SmartContract) SubmitBid(ctx contractapi.TransactionContextInterface, auctionID string, txID string) error { - - // get the MSP ID of the bidder's org - clientOrgID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return fmt.Errorf("failed to get client MSP ID: %v", err) - } - - // get the auction from public state - auction, err := s.QueryAuction(ctx, auctionID) - if err != nil { - return fmt.Errorf("failed to get auction from public state %v", err) - } - - // the auction needs to be open for users to add their bid - status := auction.Status - if status != "open" { - return fmt.Errorf("cannot join closed or ended auction") - } - - // get the inplicit collection name of bidder's org - collection, err := getCollectionName(ctx) - if err != nil { - return fmt.Errorf("failed to get implicit collection name: %v", err) - } - - // use the transaction ID passed as a parameter to create composite bid key - bidKey, err := ctx.GetStub().CreateCompositeKey(bidKeyType, []string{auctionID, txID}) - if err != nil { - return fmt.Errorf("failed to create composite key: %v", err) - } - - // get the hash of the bid if found in private collection - bidHash, err := ctx.GetStub().GetPrivateDataHash(collection, bidKey) - if err != nil { - return fmt.Errorf("failed to read bid bash from collection: %v", err) - } - if bidHash == nil { - return fmt.Errorf("bid hash does not exist: %s", bidKey) - } - - // store the hash along with the bidder's organization - newHash := BidHash{ - Org: clientOrgID, - Hash: fmt.Sprintf("%x", bidHash), - } - - auction.PrivateBids[bidKey] = newHash - - // Add the bidding organization to the list of participating organization's if it is not already - orgs := auction.Orgs - if !(contains(orgs, clientOrgID)) { - newOrgs := append(orgs, clientOrgID) - auction.Orgs = newOrgs - - err = setAssetStateBasedEndorsement(ctx, auctionID, newOrgs, auction.Auditor) - if err != nil { - return fmt.Errorf("failed setting state based endorsement for new organization: %v", err) - } - } - - newAuctionJSON, _ := json.Marshal(auction) - - err = ctx.GetStub().PutState(auctionID, newAuctionJSON) - if err != nil { - return fmt.Errorf("failed to update auction: %v", err) - } - - return nil -} - -// RevealBid is used by a bidder to reveal their bid after the auction is closed -func (s *SmartContract) RevealBid(ctx contractapi.TransactionContextInterface, auctionID string, txID string) error { - - // get the MSP ID of the bidder's org - clientOrgID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return fmt.Errorf("failed to get client MSP ID: %v", err) - } - - // get bid from transient map - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return fmt.Errorf("error getting transient: %v", err) - } - - transientBidJSON, ok := transientMap["bid"] - if !ok { - return errors.New("bid key not found in the transient map") - } - - // get implicit collection name of organization ID - collection, err := getCollectionName(ctx) - if err != nil { - return fmt.Errorf("failed to get implicit collection name: %v", err) - } - - // use transaction ID to create composit bid key - bidKey, err := ctx.GetStub().CreateCompositeKey(bidKeyType, []string{auctionID, txID}) - if err != nil { - return fmt.Errorf("failed to create composite key: %v", err) - } - - // get bid hash of bid if private bid on the public ledger - bidHash, err := ctx.GetStub().GetPrivateDataHash(collection, bidKey) - if err != nil { - return fmt.Errorf("failed to read bid bash from collection: %v", err) - } - if bidHash == nil { - return fmt.Errorf("bid hash does not exist: %s", bidKey) - } - - // get auction from public state - auction, err := s.QueryAuction(ctx, auctionID) - if err != nil { - return fmt.Errorf("failed to get auction from public state %v", err) - } - - // check that the bidders org is a participant in the auction - orgs := auction.Orgs - if !(contains(orgs, clientOrgID)) { - return fmt.Errorf("particiant %s is not a member of the auction", clientOrgID) - } - - // Complete a series of three checks before we add the bid to the auction - - // check 1: check that the auction is closed. We cannot reveal an - // bid to an open auction - status := auction.Status - if status != "closed" { - return errors.New("cannot reveal bid for open or ended auction") - } - - // check 2: check that hash of revealed bid matches hash of private bid - // on the public ledger. This checks that the bidder is telling the truth - // about the value of their bid - - hash := sha256.New() - hash.Write(transientBidJSON) - calculatedBidJSONHash := hash.Sum(nil) - - // verify that the hash of the passed immutable properties matches the on-chain hash - if !bytes.Equal(calculatedBidJSONHash, bidHash) { - return fmt.Errorf("hash %x for bid JSON %s does not match hash in auction: %x", - calculatedBidJSONHash, - transientBidJSON, - bidHash, - ) - } - - // check 3; check hash of relealed bid matches hash of private bid that was - // added earlier. This ensures that the bid has not changed since it - // was added to the auction - - privateBidHashString := auction.PrivateBids[bidKey].Hash - - onChainBidHashString := fmt.Sprintf("%x", bidHash) - if privateBidHashString != onChainBidHashString { - return fmt.Errorf("hash %s for bid JSON %s does not match hash in auction: %s, bidder must have changed bid", - privateBidHashString, - transientBidJSON, - onChainBidHashString, - ) - } - - // we can add the bid to the auction if all checks have passed - type transientBidInput struct { - Quantity int `json:"quantity"` - Price int `json:"price"` - Org string `json:"org"` - Buyer string `json:"buyer"` - } - - // unmarshal bid imput - var bidInput transientBidInput - err = json.Unmarshal(transientBidJSON, &bidInput) - if err != nil { - return fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - // get ID of submitting client - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - // marshal transient parameters and ID and MSPID into bid object - newBid := FullBid{ - Type: bidKeyType, - Quantity: bidInput.Quantity, - Price: bidInput.Price, - Org: bidInput.Org, - Buyer: bidInput.Buyer, - } - - // check 4: make sure that the transaction is being submitted is the bidder - if bidInput.Buyer != clientID { - return fmt.Errorf("permission denied, client id %v is not the owner of the bid", clientID) - } - - auction.RevealedBids[bidKey] = newBid - - auctionJSON, _ := json.Marshal(auction) - - // put auction with bid added back into state - err = ctx.GetStub().PutState(auctionID, auctionJSON) - if err != nil { - return fmt.Errorf("failed to update auction: %v", err) - } - - return nil -} - -// CloseAuction can be used by the seller to close the auction. This prevents -// bids from being added to the auction, and allows users to reveal their bid -func (s *SmartContract) CloseAuction(ctx contractapi.TransactionContextInterface, auctionID string) error { - - // get the MSP ID of the bidder's org - clientOrgID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return fmt.Errorf("failed to get client MSP ID: %v", err) - } - - // get auction from public state - auction, err := s.QueryAuction(ctx, auctionID) - if err != nil { - return fmt.Errorf("failed to get auction from public state %v", err) - } - - // check that the bidders org is a participant in the auction - orgs := auction.Orgs - if !(contains(orgs, clientOrgID)) { - return fmt.Errorf("particiant %s is not a member of the auction", clientOrgID) - } - - // the auction can only be closed by the seller - - // get ID of submitting client - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - seller := auction.Seller - if seller != clientID { - return fmt.Errorf("auction can only be closed by seller: %v", err) - } - - status := auction.Status - if status != "open" { - return errors.New("cannot close auction that is not open") - } - - auction.Status = string("closed") - - closedAuctionJSON, _ := json.Marshal(auction) - - err = ctx.GetStub().PutState(auctionID, closedAuctionJSON) - if err != nil { - return fmt.Errorf("failed to close auction: %v", err) - } - - return nil -} - -// EndAuction both changes the auction status to closed and calculates the winners -// of the auction -func (s *SmartContract) EndAuction(ctx contractapi.TransactionContextInterface, auctionID string) error { - - // get the MSP ID of the bidder's org - clientOrgID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return fmt.Errorf("failed to get client MSP ID: %v", err) - } - - // get auction from public state - auction, err := s.QueryAuction(ctx, auctionID) - if err != nil { - return fmt.Errorf("failed to get auction from public state %v", err) - } - - // check that the bidders org is a participant in the auction - orgs := auction.Orgs - if !(contains(orgs, clientOrgID)) { - return fmt.Errorf("particiant %s is not a member of the auction", clientOrgID) - } - - // Check that the auction is being ended by the seller - - // get ID of submitting client - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - seller := auction.Seller - if seller != clientID { - return fmt.Errorf("auction can only be ended by seller: %v", err) - } - - status := auction.Status - if status != "closed" { - return errors.New("can only end a closed auction") - } - - // get the list of revealed bids - - revealedBidMap := auction.RevealedBids - if len(auction.RevealedBids) == 0 { - return fmt.Errorf("no bids have been revealed, cannot end auction: %v", err) - } - - // sort the map of revealed bids to make it easier to calculate winners - // if bids are tied, fill smaller bids first - var bidders []FullBid - - for _, bid := range revealedBidMap { - bidders = append(bidders, bid) - } - - sort.Slice(bidders, func(p, q int) bool { - if bidders[p].Price > bidders[q].Price { - return true - } - if bidders[p].Price < bidders[q].Price { - return false - } - return bidders[p].Quantity < bidders[q].Quantity - }) - - i := 0 - remainingQuantity := auction.Quantity - - // calculate the winners - for remainingQuantity > 0 { - - // create the next winning bid - winner := Winners{ - Buyer: bidders[i].Buyer, - Quantity: bidders[i].Quantity, - } - - // add them to the list of winners and change the winning price - auction.Winners = append(auction.Winners, winner) - auction.Price = bidders[i].Price - - // Calculate the quantity that goes to the winner - // if there is sufficient quantity to give them the full bid - if remainingQuantity > bidders[i].Quantity { - remainingQuantity = remainingQuantity - bidders[i].Quantity - - // if there is not, give the remainder - } else { - auction.Winners[i].Quantity = remainingQuantity - remainingQuantity = 0 - } - i++ - if i == len(bidders) { - remainingQuantity = 0 - } - } - - // check if there is a winning bid that has yet to be revealed - err = checkForHigherBid(ctx, auction.Price, auction.RevealedBids, auction.PrivateBids) - if err != nil { - return fmt.Errorf("cannot end auction: %v", err) - } - - auction.Status = "ended" - - endedAuctionJSON, _ := json.Marshal(auction) - - err = ctx.GetStub().PutState(auctionID, endedAuctionJSON) - if err != nil { - return fmt.Errorf("failed to end auction: %v", err) - } - return nil -} diff --git a/auction-dutch/chaincode-go-auditor/smart-contract/auctionQueries.go b/auction-dutch/chaincode-go-auditor/smart-contract/auctionQueries.go deleted file mode 100644 index 45b84762..00000000 --- a/auction-dutch/chaincode-go-auditor/smart-contract/auctionQueries.go +++ /dev/null @@ -1,92 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package auction - -import ( - "encoding/json" - "errors" - "fmt" - - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -// QueryAuction allows all members of the channel to read a public auction -func (s *SmartContract) QueryAuction(ctx contractapi.TransactionContextInterface, auctionID string) (*Auction, error) { - - auctionJSON, err := ctx.GetStub().GetState(auctionID) - if err != nil { - return nil, fmt.Errorf("failed to get auction object %v: %v", auctionID, err) - } - if auctionJSON == nil { - return nil, errors.New("auction does not exist") - } - - var auction *Auction - err = json.Unmarshal(auctionJSON, &auction) - if err != nil { - return nil, err - } - - return auction, nil -} - -// checkForHigherBid is an internal function that is used to determine if a winning bid has yet to be revealed -func checkForHigherBid(ctx contractapi.TransactionContextInterface, auctionPrice int, revealedBidders map[string]FullBid, bidders map[string]BidHash) error { - - // Get MSP ID of peer org - peerMSPID, err := shim.GetMSPID() - if err != nil { - return fmt.Errorf("failed getting the peer's MSPID: %v", err) - } - - var error error - error = nil - - for bidKey, privateBid := range bidders { - - if _, bidInAuction := revealedBidders[bidKey]; bidInAuction { - - // bid is already revealed, no action to take - - } else { - - collection := "_implicit_org_" + privateBid.Org - - if privateBid.Org == peerMSPID { - - bidJSON, err := ctx.GetStub().GetPrivateData(collection, bidKey) - if err != nil { - return fmt.Errorf("failed to get bid %v: %v", bidKey, err) - } - if bidJSON == nil { - return fmt.Errorf("bid %v does not exist", bidKey) - } - - var bid *FullBid - err = json.Unmarshal(bidJSON, &bid) - if err != nil { - return err - } - - if bid.Price > auctionPrice { - error = fmt.Errorf("Cannot close auction, bidder has a higher price: %v", err) - } - - } else { - - hash, err := ctx.GetStub().GetPrivateDataHash(collection, bidKey) - if err != nil { - return fmt.Errorf("failed to read bid hash from collection: %v", err) - } - if hash == nil { - return fmt.Errorf("bid hash does not exist: %s", bidKey) - } - } - } - } - - return error -} diff --git a/auction-dutch/chaincode-go-auditor/smart-contract/utils.go b/auction-dutch/chaincode-go-auditor/smart-contract/utils.go deleted file mode 100644 index 4b73a7f3..00000000 --- a/auction-dutch/chaincode-go-auditor/smart-contract/utils.go +++ /dev/null @@ -1,203 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package auction - -import ( - "encoding/base64" - "fmt" - - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" - "github.com/hyperledger/fabric-protos-go-apiv2/common" - "github.com/hyperledger/fabric-protos-go-apiv2/msp" - "google.golang.org/protobuf/proto" -) - -func (s *SmartContract) GetSubmittingClientIdentity(ctx contractapi.TransactionContextInterface) (string, error) { - - b64ID, err := ctx.GetClientIdentity().GetID() - if err != nil { - return "", fmt.Errorf("Failed to read clientID: %v", err) - } - decodeID, err := base64.StdEncoding.DecodeString(b64ID) - if err != nil { - return "", fmt.Errorf("failed to base64 decode clientID: %v", err) - } - return string(decodeID), nil -} - -// getCollectionName is an internal helper function to get collection of submitting client identity. -func getCollectionName(ctx contractapi.TransactionContextInterface) (string, error) { - - // Get the MSP ID of submitting client identity - clientMSPID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return "", fmt.Errorf("failed to get verified MSPID: %v", err) - } - - // Create the collection name - orgCollection := "_implicit_org_" + clientMSPID - - return orgCollection, nil -} - -// verifyClientOrgMatchesPeerOrg is an internal function used to verify that client org id matches peer org id. -func verifyClientOrgMatchesPeerOrg(ctx contractapi.TransactionContextInterface) error { - - clientMSPID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return fmt.Errorf("failed getting the client's MSPID: %v", err) - } - peerMSPID, err := shim.GetMSPID() - if err != nil { - return fmt.Errorf("failed getting the peer's MSPID: %v", err) - } - - if clientMSPID != peerMSPID { - return fmt.Errorf("client from org %v is not authorized to read or write private data from an org %v peer", clientMSPID, peerMSPID) - } - - return nil -} - -func contains(sli []string, str string) bool { - for _, a := range sli { - if a == str { - return true - } - } - return false -} - -func setAssetStateBasedEndorsement(ctx contractapi.TransactionContextInterface, assetId string, mspids []string, auditor bool) error { - - principals := make([]*msp.MSPPrincipal, len(mspids)) - participantSigsPolicy := make([]*common.SignaturePolicy, len(mspids)) - - for i, id := range mspids { - principal, err := proto.Marshal( - &msp.MSPRole{ - Role: msp.MSPRole_PEER, - MspIdentifier: id, - }, - ) - if err != nil { - return err - } - principals[i] = &msp.MSPPrincipal{ - PrincipalClassification: msp.MSPPrincipal_ROLE, - Principal: principal, - } - participantSigsPolicy[i] = &common.SignaturePolicy{ - Type: &common.SignaturePolicy_SignedBy{ - SignedBy: int32(i), - }, - } - } - - if auditor == false { - // create the defalt policy for an auction without an auditor - - policy := &common.SignaturePolicyEnvelope{ - Version: 0, - Rule: &common.SignaturePolicy{ - Type: &common.SignaturePolicy_NOutOf_{ - NOutOf: &common.SignaturePolicy_NOutOf{ - N: int32(len(mspids)), - Rules: participantSigsPolicy, - }, - }, - }, - Identities: principals, - } - - spBytes, err := proto.Marshal(policy) - if err != nil { - return err - } - err = ctx.GetStub().SetStateValidationParameter(assetId, spBytes) - if err != nil { - return fmt.Errorf("failed to set validation parameter on auction: %v", err) - } - } else { - - // create the defalt policy for an auction with an auditor - - // create the auditor identity and signature policy - auditorMSP, err := proto.Marshal( - &msp.MSPRole{ - Role: msp.MSPRole_PEER, - MspIdentifier: "Org3MSP", - }, - ) - if err != nil { - return err - } - principals = append(principals, &msp.MSPPrincipal{ - PrincipalClassification: msp.MSPPrincipal_ROLE, - Principal: auditorMSP, - }, - ) - // Create the policies in case the auditor is needed. In this case, an - // auditor and 1 participant can update the auction. - auditorPolicies := make([]*common.SignaturePolicy, 2) - auditorPolicies[0] = &common.SignaturePolicy{ - Type: &common.SignaturePolicy_SignedBy{ - SignedBy: int32(len(principals) - 1), - }, - } - auditorPolicies[1] = &common.SignaturePolicy{ - Type: &common.SignaturePolicy_NOutOf_{ - NOutOf: &common.SignaturePolicy_NOutOf{ - N: 1, - Rules: participantSigsPolicy, - }, - }, - } - - // The auditor policy below is equivilent to AND(auditor, OR(participants)) - policies := make([]*common.SignaturePolicy, 2) - policies[0] = &common.SignaturePolicy{ - Type: &common.SignaturePolicy_NOutOf_{ - NOutOf: &common.SignaturePolicy_NOutOf{ - N: 2, - Rules: auditorPolicies, - }, - }, - } - // Participants can also update the auction without an auditor - policies[1] = &common.SignaturePolicy{ - Type: &common.SignaturePolicy_NOutOf_{ - NOutOf: &common.SignaturePolicy_NOutOf{ - N: int32(len(mspids)), - Rules: participantSigsPolicy, - }, - }, - } - // Either the auditor policy or the participant policy can update - // the auction - policy := &common.SignaturePolicyEnvelope{ - Version: 0, - Rule: &common.SignaturePolicy{ - Type: &common.SignaturePolicy_NOutOf_{ - NOutOf: &common.SignaturePolicy_NOutOf{ - N: 1, - Rules: policies, - }, - }, - }, - Identities: principals, - } - spBytes, err := proto.Marshal(policy) - if err != nil { - return err - } - err = ctx.GetStub().SetStateValidationParameter(assetId, spBytes) - if err != nil { - return fmt.Errorf("failed to set validation parameter on auction: %v", err) - } - } - return nil -} diff --git a/auction-dutch/chaincode-go-auditor/smartContract.go b/auction-dutch/chaincode-go-auditor/smartContract.go deleted file mode 100644 index f5feca58..00000000 --- a/auction-dutch/chaincode-go-auditor/smartContract.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "log" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" - auction "github.com/hyperledger/fabric-samples/auction/dutch-auction/chaincode-go-auditor/smart-contract" -) - -func main() { - auctionSmartContract, err := contractapi.NewChaincode(&auction.SmartContract{}) - if err != nil { - log.Panicf("Error creating auction chaincode: %v", err) - } - - if err := auctionSmartContract.Start(); err != nil { - log.Panicf("Error starting auction chaincode: %v", err) - } -} diff --git a/auction-dutch/chaincode-go/go.mod b/auction-dutch/chaincode-go/go.mod deleted file mode 100644 index 24f1f572..00000000 --- a/auction-dutch/chaincode-go/go.mod +++ /dev/null @@ -1,28 +0,0 @@ -module github.com/hyperledger/fabric-samples/auction/dutch-auction/chaincode-go - -go 1.22.0 - -require ( - github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 - github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 - google.golang.org/protobuf v1.36.1 -) - -require ( - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/auction-dutch/chaincode-go/go.sum b/auction-dutch/chaincode-go/go.sum deleted file mode 100644 index fa4d3b24..00000000 --- a/auction-dutch/chaincode-go/go.sum +++ /dev/null @@ -1,61 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 h1:IhkHfrl5X/fVnmB6pWeCYCdIJRi9bxj+WTnVN8DtW3c= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0/go.mod h1:PHHaFffjw7p7n9bmCfcm7RqDqYdivNEsJdiNIKZo5Lk= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 h1:rmUoBmciB0GL/miqcbJmJbgp5QTWoJUrZo+CNxrNLF4= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0/go.mod h1:FeWeO/jwGjiME7ak3GufqKIcwkejtzrDG4QxbfKydWs= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/auction-dutch/chaincode-go/smart-contract/auction.go b/auction-dutch/chaincode-go/smart-contract/auction.go deleted file mode 100644 index 90a9097b..00000000 --- a/auction-dutch/chaincode-go/smart-contract/auction.go +++ /dev/null @@ -1,513 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package auction - -import ( - "bytes" - "crypto/sha256" - "encoding/json" - "errors" - "fmt" - "sort" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -type SmartContract struct { - contractapi.Contract -} - -// Auction data -type Auction struct { - Type string `json:"objectType"` - ItemSold string `json:"item"` - Seller string `json:"seller"` - Quantity int `json:"quantity"` - Orgs []string `json:"organizations"` - PrivateBids map[string]BidHash `json:"privateBids"` - RevealedBids map[string]FullBid `json:"revealedBids"` - Winners []Winners `json:"winners"` - Price int `json:"price"` - Status string `json:"status"` - Auditor bool `json:"auditor"` -} - -// FullBid is the structure of a revealed bid -type FullBid struct { - Type string `json:"objectType"` - Quantity int `json:"quantity"` - Price int `json:"price"` - Org string `json:"org"` - Buyer string `json:"buyer"` -} - -// BidHash is the structure of a private bid -type BidHash struct { - Org string `json:"org"` - Hash string `json:"hash"` -} - -// Winners stores the winners of the auction -type Winners struct { - Buyer string `json:"buyer"` - Quantity int `json:"quantity"` -} - -const bidKeyType = "bid" - -// CreateAuction creates on auction on the public channel. The identity that -// submits the transacion becomes the seller of the auction -func (s *SmartContract) CreateAuction(ctx contractapi.TransactionContextInterface, auctionID string, itemsold string, quantity int, withAuditor string) error { - - // get ID of submitting client - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - // get org of submitting client - clientOrgID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - auditor := false - - if withAuditor == "withAuditor" { - auditor = true - } - - // Create auction - bidders := make(map[string]BidHash) - revealedBids := make(map[string]FullBid) - - auction := Auction{ - Type: "auction", - ItemSold: itemsold, - Quantity: quantity, - Price: 0, - Seller: clientID, - Orgs: []string{clientOrgID}, - PrivateBids: bidders, - RevealedBids: revealedBids, - Winners: []Winners{}, - Status: "open", - Auditor: auditor, - } - - auctionJSON, err := json.Marshal(auction) - if err != nil { - return err - } - - // put auction into state - err = ctx.GetStub().PutState(auctionID, auctionJSON) - if err != nil { - return fmt.Errorf("failed to put auction in public data: %v", err) - } - - // set the seller of the auction as an endorser - err = setAssetStateBasedEndorsement(ctx, auctionID, []string{clientOrgID}, auditor) - if err != nil { - return fmt.Errorf("failed setting state based endorsement for new organization: %v", err) - } - - return nil -} - -// Bid is used to add a users bid to the auction. The bid is stored in the private -// data collection on the peer of the bidder's organization. The function returns -// the transaction ID so that users can identify and query their bid -func (s *SmartContract) Bid(ctx contractapi.TransactionContextInterface, auctionID string) (string, error) { - - // get bid from transient map - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return "", fmt.Errorf("error getting transient: %v", err) - } - - bidJSON, ok := transientMap["bid"] - if !ok { - return "", errors.New("bid key not found in the transient map") - } - - // get the implicit collection name using the bidder's organization ID - collection, err := getCollectionName(ctx) - if err != nil { - return "", fmt.Errorf("failed to get implicit collection name: %v", err) - } - - // the bidder has to target their peer to store the bid - err = verifyClientOrgMatchesPeerOrg(ctx) - if err != nil { - return "", fmt.Errorf("cannot store bid on this peer, not a member of this org: %v", err) - } - - // the transaction ID is used as a unique index for the bid - txID := ctx.GetStub().GetTxID() - - // create a composite key using the transaction ID - bidKey, err := ctx.GetStub().CreateCompositeKey(bidKeyType, []string{auctionID, txID}) - if err != nil { - return "", fmt.Errorf("failed to create composite key: %v", err) - } - - // put the bid into the organization's implicit data collection - err = ctx.GetStub().PutPrivateData(collection, bidKey, bidJSON) - if err != nil { - return "", fmt.Errorf("failed to input price into collection: %v", err) - } - - // return the trannsaction ID so that the uset can identify their bid - return txID, nil -} - -// SubmitBid is used by the bidder to add the hash of that bid stored in private data to the -// auction. Note that this function alters the auction in private state, and needs -// to meet the auction endorsement policy. Transaction ID is used identify the bid -func (s *SmartContract) SubmitBid(ctx contractapi.TransactionContextInterface, auctionID string, txID string) error { - - // get the MSP ID of the bidder's org - clientOrgID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return fmt.Errorf("failed to get client MSP ID: %v", err) - } - - // get the auction from public state - auction, err := s.QueryAuction(ctx, auctionID) - if err != nil { - return fmt.Errorf("failed to get auction from public state %v", err) - } - - // the auction needs to be open for users to add their bid - status := auction.Status - if status != "open" { - return fmt.Errorf("cannot join closed or ended auction") - } - - // get the inplicit collection name of bidder's org - collection, err := getCollectionName(ctx) - if err != nil { - return fmt.Errorf("failed to get implicit collection name: %v", err) - } - - // use the transaction ID passed as a parameter to create composite bid key - bidKey, err := ctx.GetStub().CreateCompositeKey(bidKeyType, []string{auctionID, txID}) - if err != nil { - return fmt.Errorf("failed to create composite key: %v", err) - } - - // get the hash of the bid if found in private collection - bidHash, err := ctx.GetStub().GetPrivateDataHash(collection, bidKey) - if err != nil { - return fmt.Errorf("failed to read bid bash from collection: %v", err) - } - if bidHash == nil { - return fmt.Errorf("bid hash does not exist: %s", bidKey) - } - - // store the hash along with the bidder's organization - newHash := BidHash{ - Org: clientOrgID, - Hash: fmt.Sprintf("%x", bidHash), - } - - auction.PrivateBids[bidKey] = newHash - - // Add the bidding organization to the list of participating organization's if it is not already - orgs := auction.Orgs - if !(contains(orgs, clientOrgID)) { - newOrgs := append(orgs, clientOrgID) - auction.Orgs = newOrgs - - err = setAssetStateBasedEndorsement(ctx, auctionID, newOrgs, auction.Auditor) - if err != nil { - return fmt.Errorf("failed setting state based endorsement for new organization: %v", err) - } - } - - newAuctionJSON, _ := json.Marshal(auction) - - err = ctx.GetStub().PutState(auctionID, newAuctionJSON) - if err != nil { - return fmt.Errorf("failed to update auction: %v", err) - } - - return nil -} - -// RevealBid is used by a bidder to reveal their bid after the auction is closed -func (s *SmartContract) RevealBid(ctx contractapi.TransactionContextInterface, auctionID string, txID string) error { - - // get bid from transient map - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return fmt.Errorf("error getting transient: %v", err) - } - - transientBidJSON, ok := transientMap["bid"] - if !ok { - return fmt.Errorf("bid key not found in the transient map") - } - - // get implicit collection name of organization ID - collection, err := getCollectionName(ctx) - if err != nil { - return fmt.Errorf("failed to get implicit collection name: %v", err) - } - - // use transaction ID to create composit bid key - bidKey, err := ctx.GetStub().CreateCompositeKey(bidKeyType, []string{auctionID, txID}) - if err != nil { - return fmt.Errorf("failed to create composite key: %v", err) - } - - // get bid hash of bid if private bid on the public ledger - bidHash, err := ctx.GetStub().GetPrivateDataHash(collection, bidKey) - if err != nil { - return fmt.Errorf("failed to read bid bash from collection: %v", err) - } - if bidHash == nil { - return fmt.Errorf("bid hash does not exist: %s", bidKey) - } - - // get auction from public state - auction, err := s.QueryAuction(ctx, auctionID) - if err != nil { - return fmt.Errorf("failed to get auction from public state %v", err) - } - - // Complete a series of three checks before we add the bid to the auction - - // check 1: check that the auction is closed. We cannot reveal an - // bid to an open auction - status := auction.Status - if status != "closed" { - return fmt.Errorf("cannot reveal bid for open or ended auction") - } - - // check 2: check that hash of revealed bid matches hash of private bid - // on the public ledger. This checks that the bidder is telling the truth - // about the value of their bid - - hash := sha256.New() - hash.Write(transientBidJSON) - calculatedBidJSONHash := hash.Sum(nil) - - // verify that the hash of the passed immutable properties matches the on-chain hash - if !bytes.Equal(calculatedBidJSONHash, bidHash) { - return fmt.Errorf("hash %x for bid JSON %s does not match hash in auction: %x", - calculatedBidJSONHash, - transientBidJSON, - bidHash, - ) - } - - // check 3; check hash of relealed bid matches hash of private bid that was - // added earlier. This ensures that the bid has not changed since it - // was added to the auction - - privateBidHashString := auction.PrivateBids[bidKey].Hash - - onChainBidHashString := fmt.Sprintf("%x", bidHash) - if privateBidHashString != onChainBidHashString { - return fmt.Errorf("hash %s for bid JSON %s does not match hash in auction: %s, bidder must have changed bid", - privateBidHashString, - transientBidJSON, - onChainBidHashString, - ) - } - - // we can add the bid to the auction if all checks have passed - type transientBidInput struct { - Quantity int `json:"quantity"` - Price int `json:"price"` - Org string `json:"org"` - Buyer string `json:"buyer"` - } - - // unmarshal bid imput - var bidInput transientBidInput - err = json.Unmarshal(transientBidJSON, &bidInput) - if err != nil { - return fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - // get ID of submitting client - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - // marshal transient parameters and ID and MSPID into bid object - newBid := FullBid{ - Type: bidKeyType, - Quantity: bidInput.Quantity, - Price: bidInput.Price, - Org: bidInput.Org, - Buyer: bidInput.Buyer, - } - - // check 4: make sure that the transaction is being submitted is the bidder - if bidInput.Buyer != clientID { - return fmt.Errorf("permission denied, client id %v is not the owner of the bid", clientID) - } - - revealedBids := auction.RevealedBids - revealedBids[bidKey] = newBid - auction.RevealedBids = revealedBids - - auctionJSON, _ := json.Marshal(auction) - - // put auction with bid added back into state - err = ctx.GetStub().PutState(auctionID, auctionJSON) - if err != nil { - return fmt.Errorf("failed to update auction: %v", err) - } - - return nil -} - -// CloseAuction can be used by the seller to close the auction. This prevents -// bids from being added to the auction, and allows users to reveal their bid -func (s *SmartContract) CloseAuction(ctx contractapi.TransactionContextInterface, auctionID string) error { - - // get auction from public state - auction, err := s.QueryAuction(ctx, auctionID) - if err != nil { - return fmt.Errorf("failed to get auction from public state %v", err) - } - - // the auction can only be closed by the seller - - // get ID of submitting client - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - seller := auction.Seller - if seller != clientID { - return fmt.Errorf("auction can only be closed by seller: %v", err) - } - - status := auction.Status - if status != "open" { - return fmt.Errorf("cannot close auction that is not open") - } - - auction.Status = string("closed") - - closedAuctionJSON, _ := json.Marshal(auction) - - err = ctx.GetStub().PutState(auctionID, closedAuctionJSON) - if err != nil { - return fmt.Errorf("failed to close auction: %v", err) - } - - return nil -} - -// EndAuction both changes the auction status to closed and calculates the winners -// of the auction -func (s *SmartContract) EndAuction(ctx contractapi.TransactionContextInterface, auctionID string) error { - - // get auction from public state - auction, err := s.QueryAuction(ctx, auctionID) - if err != nil { - return fmt.Errorf("failed to get auction from public state %v", err) - } - - // Check that the auction is being ended by the seller - - // get ID of submitting client - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - seller := auction.Seller - if seller != clientID { - return fmt.Errorf("auction can only be ended by seller: %v", err) - } - - status := auction.Status - if status != "closed" { - return fmt.Errorf("can only end a closed auction") - } - - // get the list of revealed bids - - revealedBidMap := auction.RevealedBids - if len(auction.RevealedBids) == 0 { - return fmt.Errorf("no bids have been revealed, cannot end auction: %v", err) - } - - // sort the map of revealed bids to make it easier to calculate winners - // if bids are tied, fill smaller bids first - var bidders []FullBid - - for _, bid := range revealedBidMap { - bidders = append(bidders, bid) - } - - sort.Slice(bidders, func(p, q int) bool { - if bidders[p].Price > bidders[q].Price { - return true - } - if bidders[p].Price < bidders[q].Price { - return false - } - return bidders[p].Quantity < bidders[q].Quantity - }) - - i := 0 - remainingQuantity := auction.Quantity - - // calculate the winners - for remainingQuantity > 0 { - - // create the next winning bid - winner := Winners{ - Buyer: bidders[i].Buyer, - Quantity: bidders[i].Quantity, - } - - // add them to the list of winners and change the winning price - auction.Winners = append(auction.Winners, winner) - auction.Price = bidders[i].Price - - // Calculate the quantity that goes to the winner - // if there is sufficient quantity to give them the full bid - if remainingQuantity > bidders[i].Quantity { - remainingQuantity = remainingQuantity - bidders[i].Quantity - - // if there is not, give the remainder - } else { - auction.Winners[i].Quantity = remainingQuantity - remainingQuantity = 0 - } - i++ - if i == len(bidders) { - remainingQuantity = 0 - } - } - - // check if there is a winning bid that has yet to be revealed - err = checkForHigherBid(ctx, auction.Price, auction.RevealedBids, auction.PrivateBids) - if err != nil { - return fmt.Errorf("cannot end auction: %v", err) - } - - auction.Status = "ended" - - endedAuctionJSON, _ := json.Marshal(auction) - - err = ctx.GetStub().PutState(auctionID, endedAuctionJSON) - if err != nil { - return fmt.Errorf("failed to end auction: %v", err) - } - return nil -} diff --git a/auction-dutch/chaincode-go/smart-contract/auctionQueries.go b/auction-dutch/chaincode-go/smart-contract/auctionQueries.go deleted file mode 100644 index d5024fb4..00000000 --- a/auction-dutch/chaincode-go/smart-contract/auctionQueries.go +++ /dev/null @@ -1,137 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package auction - -import ( - "encoding/json" - "errors" - "fmt" - - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -// QueryAuction allows all members of the channel to read a public auction -func (s *SmartContract) QueryAuction(ctx contractapi.TransactionContextInterface, auctionID string) (*Auction, error) { - - auctionJSON, err := ctx.GetStub().GetState(auctionID) - if err != nil { - return nil, fmt.Errorf("failed to get auction object %v: %v", auctionID, err) - } - if auctionJSON == nil { - return nil, errors.New("auction does not exist") - } - - var auction *Auction - err = json.Unmarshal(auctionJSON, &auction) - if err != nil { - return nil, err - } - - return auction, nil -} - -// QueryBid allows the submitter of the bid to read their bid from public state -func (s *SmartContract) QueryBid(ctx contractapi.TransactionContextInterface, auctionID string, txID string) (*FullBid, error) { - - err := verifyClientOrgMatchesPeerOrg(ctx) - if err != nil { - return nil, fmt.Errorf("failed to get implicit collection name: %v", err) - } - - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return nil, fmt.Errorf("failed to get client identity %v", err) - } - - collection, err := getCollectionName(ctx) - if err != nil { - return nil, fmt.Errorf("failed to get implicit collection name: %v", err) - } - - bidKey, err := ctx.GetStub().CreateCompositeKey(bidKeyType, []string{auctionID, txID}) - if err != nil { - return nil, fmt.Errorf("failed to create composite key: %v", err) - } - - bidJSON, err := ctx.GetStub().GetPrivateData(collection, bidKey) - if err != nil { - return nil, fmt.Errorf("failed to get bid %v: %v", bidKey, err) - } - if bidJSON == nil { - return nil, fmt.Errorf("bid %v does not exist", bidKey) - } - - var bid *FullBid - err = json.Unmarshal(bidJSON, &bid) - if err != nil { - return nil, err - } - - // check that the client querying the bid is the bid owner - if bid.Buyer != clientID { - return nil, fmt.Errorf("permission denied, client id %v is not the owner of the bid", clientID) - } - - return bid, nil -} - -// checkForHigherBid is an internal function that is used to determine if a winning bid has yet to be revealed -func checkForHigherBid(ctx contractapi.TransactionContextInterface, auctionPrice int, revealedBidders map[string]FullBid, bidders map[string]BidHash) error { - - // Get MSP ID of peer org - peerMSPID, err := shim.GetMSPID() - if err != nil { - return fmt.Errorf("failed getting the peer's MSPID: %v", err) - } - - var error error - error = nil - - for bidKey, privateBid := range bidders { - - if _, bidInAuction := revealedBidders[bidKey]; bidInAuction { - - // bid is already revealed, no action to take - - } else { - - collection := "_implicit_org_" + privateBid.Org - - if privateBid.Org == peerMSPID { - - bidJSON, err := ctx.GetStub().GetPrivateData(collection, bidKey) - if err != nil { - return fmt.Errorf("failed to get bid %v: %v", bidKey, err) - } - if bidJSON == nil { - return fmt.Errorf("bid %v does not exist", bidKey) - } - - var bid *FullBid - err = json.Unmarshal(bidJSON, &bid) - if err != nil { - return err - } - - if bid.Price > auctionPrice { - error = fmt.Errorf("cannot close auction, bidder has a higher price: %v", err) - } - - } else { - - hash, err := ctx.GetStub().GetPrivateDataHash(collection, bidKey) - if err != nil { - return fmt.Errorf("failed to read bid hash from collection: %v", err) - } - if hash == nil { - return fmt.Errorf("bid hash does not exist: %s", bidKey) - } - } - } - } - - return error -} diff --git a/auction-dutch/chaincode-go/smart-contract/utils.go b/auction-dutch/chaincode-go/smart-contract/utils.go deleted file mode 100644 index 351826fb..00000000 --- a/auction-dutch/chaincode-go/smart-contract/utils.go +++ /dev/null @@ -1,205 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package auction - -import ( - "encoding/base64" - "fmt" - - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" - "github.com/hyperledger/fabric-protos-go-apiv2/common" - "github.com/hyperledger/fabric-protos-go-apiv2/msp" - "google.golang.org/protobuf/proto" -) - -func (s *SmartContract) GetSubmittingClientIdentity(ctx contractapi.TransactionContextInterface) (string, error) { - - b64ID, err := ctx.GetClientIdentity().GetID() - if err != nil { - return "", fmt.Errorf("failed to read clientID: %v", err) - } - decodeID, err := base64.StdEncoding.DecodeString(b64ID) - if err != nil { - return "", fmt.Errorf("failed to base64 decode clientID: %v", err) - } - return string(decodeID), nil -} - -// getCollectionName is an internal helper function to get collection of submitting client identity. -func getCollectionName(ctx contractapi.TransactionContextInterface) (string, error) { - - // Get the MSP ID of submitting client identity - clientMSPID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return "", fmt.Errorf("failed to get verified MSPID: %v", err) - } - - // Create the collection name - orgCollection := "_implicit_org_" + clientMSPID - - return orgCollection, nil -} - -// verifyClientOrgMatchesPeerOrg is an internal function used to verify that client org id matches peer org id. -func verifyClientOrgMatchesPeerOrg(ctx contractapi.TransactionContextInterface) error { - - clientMSPID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return fmt.Errorf("failed getting the client's MSPID: %v", err) - } - peerMSPID, err := shim.GetMSPID() - if err != nil { - return fmt.Errorf("failed getting the peer's MSPID: %v", err) - } - - if clientMSPID != peerMSPID { - return fmt.Errorf("client from org %v is not authorized to read or write private data from an org %v peer", clientMSPID, peerMSPID) - } - - return nil -} - -func contains(sli []string, str string) bool { - for _, a := range sli { - if a == str { - return true - } - } - return false -} - -func setAssetStateBasedEndorsement(ctx contractapi.TransactionContextInterface, assetId string, mspids []string, auditor bool) error { - - principals := make([]*msp.MSPPrincipal, len(mspids)) - participantSigsPolicy := make([]*common.SignaturePolicy, len(mspids)) - - for i, id := range mspids { - principal, err := proto.Marshal( - &msp.MSPRole{ - Role: msp.MSPRole_PEER, - MspIdentifier: id, - }, - ) - if err != nil { - return err - } - principals[i] = &msp.MSPPrincipal{ - PrincipalClassification: msp.MSPPrincipal_ROLE, - Principal: principal, - } - participantSigsPolicy[i] = &common.SignaturePolicy{ - Type: &common.SignaturePolicy_SignedBy{ - SignedBy: int32(i), - }, - } - } - - if !auditor { - // create the defalt policy for an auction without an auditor - - policy := &common.SignaturePolicyEnvelope{ - Version: 0, - Rule: &common.SignaturePolicy{ - Type: &common.SignaturePolicy_NOutOf_{ - NOutOf: &common.SignaturePolicy_NOutOf{ - N: int32(len(mspids)), - Rules: participantSigsPolicy, - }, - }, - }, - Identities: principals, - } - - spBytes, err := proto.Marshal(policy) - if err != nil { - return err - } - err = ctx.GetStub().SetStateValidationParameter(assetId, spBytes) - if err != nil { - return fmt.Errorf("failed to set validation parameter on auction: %v", err) - } - } else { - - // create the defalt policy for an auction with an auditor - - // create the auditor identity and signature policy - auditorMSP, err := proto.Marshal( - &msp.MSPRole{ - Role: msp.MSPRole_PEER, - MspIdentifier: "Org3MSP", - }, - ) - if err != nil { - return err - } - principals = append(principals, &msp.MSPPrincipal{ - PrincipalClassification: msp.MSPPrincipal_ROLE, - Principal: auditorMSP, - }, - ) - // Create the policies in case the auditor is needed. In this case, an - // auditor and 1 participant can update the auction. - auditorPolicies := make([]*common.SignaturePolicy, 2) - auditorPolicies[0] = &common.SignaturePolicy{ - Type: &common.SignaturePolicy_SignedBy{ - SignedBy: int32(len(principals) - 1), - }, - } - auditorPolicies[1] = &common.SignaturePolicy{ - Type: &common.SignaturePolicy_NOutOf_{ - NOutOf: &common.SignaturePolicy_NOutOf{ - N: 1, - Rules: participantSigsPolicy, - }, - }, - } - - // For two organizations, the auditor policy below is equivilent to - // AND(auditor, OR(Org1, Org2)) - policies := make([]*common.SignaturePolicy, 2) - policies[0] = &common.SignaturePolicy{ - Type: &common.SignaturePolicy_NOutOf_{ - NOutOf: &common.SignaturePolicy_NOutOf{ - N: 2, - Rules: auditorPolicies, - }, - }, - } - // Participants can also update the auction without an auditor - policies[1] = &common.SignaturePolicy{ - Type: &common.SignaturePolicy_NOutOf_{ - NOutOf: &common.SignaturePolicy_NOutOf{ - N: int32(len(mspids)), - Rules: participantSigsPolicy, - }, - }, - } - // Either the auditor policy or the participant policy can update - // the auction. For example, for two organizations, the full policy would be - // equivilent to OR(AND(Org1, Org2),AND(auditor, OR(Org1, Org2))) - policy := &common.SignaturePolicyEnvelope{ - Version: 0, - Rule: &common.SignaturePolicy{ - Type: &common.SignaturePolicy_NOutOf_{ - NOutOf: &common.SignaturePolicy_NOutOf{ - N: 1, - Rules: policies, - }, - }, - }, - Identities: principals, - } - spBytes, err := proto.Marshal(policy) - if err != nil { - return err - } - err = ctx.GetStub().SetStateValidationParameter(assetId, spBytes) - if err != nil { - return fmt.Errorf("failed to set validation parameter on auction: %v", err) - } - } - return nil -} diff --git a/auction-dutch/chaincode-go/smartContract.go b/auction-dutch/chaincode-go/smartContract.go deleted file mode 100644 index 939a519c..00000000 --- a/auction-dutch/chaincode-go/smartContract.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "log" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" - auction "github.com/hyperledger/fabric-samples/auction/dutch-auction/chaincode-go/smart-contract" -) - -func main() { - auctionSmartContract, err := contractapi.NewChaincode(&auction.SmartContract{}) - if err != nil { - log.Panicf("Error creating auction chaincode: %v", err) - } - - if err := auctionSmartContract.Start(); err != nil { - log.Panicf("Error starting auction chaincode: %v", err) - } -} diff --git a/auction-simple/README.md b/auction-simple/README.md deleted file mode 100644 index e6bb6308..00000000 --- a/auction-simple/README.md +++ /dev/null @@ -1,410 +0,0 @@ -## Simple blind auction sample - -The simple blind auction sample uses Hyperledger Fabric to run an auction where bids are kept private until the auction period is over. Instead of displaying the full bid on the public ledger, buyers can only see hashes of other bids while bidding is underway. This prevents buyers from changing their bids in response to bids submitted by others. After the bidding period ends, participants reveal their bid to try to win the auction. The organizations participating in the auction verify that a revealed bid matches the hash on the public ledger. Whichever has the highest bid wins. - -A user that wants to sell one item can use the smart contract to create an auction. The auction is stored on the channel ledger and can be read by all channel members. The auctions created by the smart contract are run in three steps: -1. Each auction is created with the status **open**. While the auction is open, buyers can add new bids to the auction. The full bids of each buyer are stored in the implicit private data collections of their organization. After the bid is created, the bidder can submit the hash of the bid to the auction. A bid is added to the auction in two steps because the transaction that creates the bid only needs to be endorsed by a peer of the bidders organization, while a transaction that updates the auction may need to be endorsed by multiple organizations. When the bid is added to the auction, the bidder's organization is added to the list of organizations that need to endorse any updates to the auction. -2. The auction is **closed** to prevent additional bids from being added to the auction. After the auction is closed, bidders that submitted bids to the auction can reveal their full bid. Only revealed bids can win the auction. -3. The auction is **ended** to calculate the winner from the set of revealed bids. All organizations participating in the auction calculate the price that clears the auction and the winning bid. The seller can end the auction only if all bidding organizations endorse the same winner and price. - -Before endorsing the transaction that ends the auction, each organization queries the implicit private data collection on their peers to check if any organization member has a winning bid that has not yet been revealed. If a winning bid is found, the organization will withhold their endorsement and prevent the auction from being closed. This prevents the seller from ending the auction prematurely, or colluding with buyers to end the auction at an artificially low price. - -The sample uses several Fabric features to make the auction private and secure. Bids are stored in private data collections to prevent bids from being distributed to other peers in the channel. When bidding is closed, the auction smart contract uses the `GetPrivateDataHash()` API to verify that the bid stored in private data is the same bid that is being revealed. State based endorsement is used to add the organization of each bidder to the auction endorsement policy. The smart contract uses the `GetClientIdentity.GetID()` API to ensure that only the potential buyer can read their bid from private state and only the seller can close or end the auction. - -This tutorial uses the auction smart contract in a scenario where one seller wants to auction a painting. Four potential buyers from two different organizations will submit bids to the auction and try to win the auction. - -## Deploy the chaincode - -We will run the auction smart contract using the Fabric test network. Open a command terminal and navigate to the test network directory: -``` -cd fabric-samples/test-network -``` - -You can then run the following command to deploy the test network. -``` -./network.sh up createChannel -ca -``` - -Note that we use the `-ca` flag to deploy the network using certificate authorities. We will use the CA to register and enroll our sellers and buyers. - -Run the following command to deploy the auction smart contract. We will override the default endorsement policy to allow any channel member to create an auction without requiring an endorsement from another organization. -``` -./network.sh deployCC -ccn auction -ccp ../auction-simple/chaincode-go/ -ccl go -ccep "OR('Org1MSP.peer','Org2MSP.peer')" -``` - -## Install the application dependencies - -We will interact with the auction smart contract through a set of Node.js applications. Change into the `application-javascript` directory: -``` -cd fabric-samples/auction-simple/application-javascript -``` - -From this directory, run the following command to download the application dependencies: -``` -npm install -``` - -## Register and enroll the application identities - -To interact with the network, you will need to enroll the Certificate Authority administrators of Org1 and Org2. You can use the `enrollAdmin.js` program for this task. Run the following command to enroll the Org1 admin: -``` -node enrollAdmin.js org1 -``` -You should see the logs of the admin wallet being created on your local file system. Now run the command to enroll the CA admin of Org2: -``` -node enrollAdmin.js org2 -``` - -We can use the CA admins of both organizations to register and enroll the identities of the seller that will create the auction and the bidders who will try to purchase the painting. - -Run the following command to register and enroll the seller identity that will create the auction. The seller will belong to Org1. -``` -node registerEnrollUser.js org1 seller -``` - -You should see the logs of the seller wallet being created as well. Run the following commands to register and enroll 2 bidders from Org1 and another 2 bidders from Org2: -``` -node registerEnrollUser.js org1 bidder1 -node registerEnrollUser.js org1 bidder2 -node registerEnrollUser.js org2 bidder3 -node registerEnrollUser.js org2 bidder4 -``` - -## Create the auction - -The seller from Org1 would like to create an auction to sell a vintage Matchbox painting. Run the following command to use the seller wallet to run the `createAuction.js` application. The program will submit a transaction to the network that creates the auction on the channel ledger. The organization and identity name are passed to the application to use the wallet that was created by the `registerEnrollUser.js` application. The seller needs to provide an ID for the auction and the item to be sold to create the auction: -``` -node createAuction.js org1 seller PaintingAuction painting -``` - -After the transaction is complete, the `createAuction.js` application will query the auction stored in the public channel ledger: -``` -*** Result: Auction: { - "objectType": "auction", - "item": "painting", - "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "organizations": [ - "Org1MSP" - ], - "privateBids": {}, - "revealedBids": {}, - "winner": "", - "price": 0, - "status": "open" -} -``` -The smart contract uses the `GetClientIdentity().GetID()` API to read the identity that creates the auction and defines that identity as the auction `"seller"`. The seller is identified by the name and issuer of the seller's certificate. - -## Bid on the auction - -We can now use the bidder wallets to submit bids to the auction: - -### Bid as bidder1 - -Bidder1 will create a bid to purchase the painting for 800 dollars. -``` -node bid.js org1 bidder1 PaintingAuction 800 -``` - -The application will query the bid after it is created: -``` -*** Result: Bid: { - "objectType": "bid", - "price": 800, - "org": "Org1MSP", - "bidder": "x509::CN=bidder1,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US" -} -``` - -The bid is stored in the Org1 implicit data collection. The `"bidder"` parameter is the information from the certificate of the user that created the bid. Only this identity will be able can query the bid from private state or reveal the bid during the auction. - -The `bid.js` application also prints the bidID: -``` -*** Result ***SAVE THIS VALUE*** BidID: 67d85ef08e32de20994c816362d0952fe5c2ae3f2d1083600c3ac61f65a89f60 -``` - -The BidID acts as the unique identifier for the bid. This ID allows you to query the bid using the `queryBid.js` program and add the bid to the auction. Save the bidID returned by the application as an environment variable in your terminal: -``` -export BIDDER1_BID_ID=67d85ef08e32de20994c816362d0952fe5c2ae3f2d1083600c3ac61f65a89f60 -``` -This value will be different for each transaction, so you will need to use the value returned in your terminal. - -Now that the bid has been created, you can submit the bid to the auction. Run the following command to submit the bid that was just created: -``` -node submitBid.js org1 bidder1 PaintingAuction $BIDDER1_BID_ID -``` - -The hash of bid will be added to the list private bids in that have been submitted to `PaintingAuction`. Storing the hash in the public auction allows users to accurately reveal the bid after bidding is closed. The application will query the auction to verify that the bid was added: -``` -*** Result: Auction: { - "objectType": "auction", - "item": "painting", - "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "organizations": [ - "Org1MSP" - ], - "privateBids": { - "\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": { - "org": "Org1MSP", - "hash": "0b8bbdb96b1d252e71ac1ed71df3580f7a0e31a743a4a09bbf5196dffef426b2" - } - }, - "revealedBids": {}, - "winner": "", - "price": 0, - "status": "open" -} -``` - -### Bid as bidder2 - -Let's submit another bid. Bidder2 would like to purchase the painting for 500 dollars. -``` -node bid.js org1 bidder2 PaintingAuction 500 -``` - -Save the Bid ID returned by the application: -``` -export BIDDER2_BID_ID=0fa8b3b15923966f205a1f5ebd163d2707d069ffa055105114fc654d225f511d -``` - -Submit bidder2's bid to the auction: -``` -node submitBid.js org1 bidder2 PaintingAuction $BIDDER2_BID_ID -``` - -### Bid as bidder3 from Org2 - -Bidder3 will bid 700 dollars for the painting: -``` -node bid.js org2 bidder3 PaintingAuction 700 -``` - -Save the Bid ID returned by the application: -``` -export BIDDER3_BID_ID=cda8bb2849fc0553efb036c56ea86d82791a695b5641941dac797dc6e2d75768 -``` - -Add bidder3's bid to the auction: -``` -node submitBid.js org2 bidder3 PaintingAuction $BIDDER3_BID_ID -``` - -Because bidder3 belongs to Org2, submitting the bid will add Org2 to the list of participating organizations. You can see the Org2 MSP ID has been added to the list of `"organizations"` in the updated auction returned by the application: -``` -*** Result: Auction: { - "objectType": "auction", - "item": "painting", - "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "organizations": [ - "Org1MSP", - "Org2MSP" - ], - "privateBids": { - "\u0000bid\u0000PaintingAuction\u00001b9dc0006fef10413df5cca927cabdf73ab854fe92b7a7b2eebfa00961fdac67\u0000": { - "org": "Org1MSP", - "hash": "15cd9a3e12825017f3e758499ac6138ebbe1adec4c49cc6ea6a0973fc6514666" - }, - "\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": { - "org": "Org1MSP", - "hash": "0b8bbdb96b1d252e71ac1ed71df3580f7a0e31a743a4a09bbf5196dffef426b2" - }, - "\u0000bid\u0000PaintingAuction\u00005ee4fa53b54ea0821e57a6884a1ada5eb04f136ee222e92d7399bcdf47556ea1\u0000": { - "org": "Org2MSP", - "hash": "14d47d17acceceb483e87c14a4349844874fce549d71c6a23457d953ed8ffbd3" - } - }, - "revealedBids": {}, - "winner": "", - "price": 0, - "status": "open" -} -``` - -Now that a bid from Org2 has been added to the auction, any updates to the auction need to be endorsed by the Org2 peer. The applications will use `"organizations"` field to specify which organizations need to endorse submitting a new bid, revealing a bid, or updating the auction status. - -### Bid as bidder4 - -Bidder4 from Org2 would like to purchase the painting for 900 dollars: -``` -node bid.js org2 bidder4 PaintingAuction 900 -``` - -Save the Bid ID returned by the application: -``` -export BIDDER4_BID_ID=83861eb17715ff537a1e73cd2d08509dc7199572806a5368706516759af1a257 -``` - -Add bidder4's bid to the auction: -``` -node submitBid.js org2 bidder4 PaintingAuction $BIDDER4_BID_ID -``` - -## Close the auction - -Now that all four bidders have joined the auction, the seller would like to close the auction and allow buyers to reveal their bids. The seller identity that created the auction needs to submit the transaction: -``` -node closeAuction.js org1 seller PaintingAuction -``` - -The application will query the auction to allow you to verify that the auction status has changed to closed. As a test, you can try to create and submit a new bid to verify that no new bids can be added to the auction. - -## Reveal bids - -After the auction is closed, bidders can try to win the auction by revealing their bids. The transaction to reveal a bid needs to pass four checks: -1. The auction is closed. -2. The transaction was submitted by the identity that created the bid. -3. The hash of the revealed bid matches the hash of the bid on the channel ledger. This confirms that the bid is the same as the bid that is stored in the private data collection. -4. The hash of the revealed bid matches the hash that was submitted to the auction. This confirms that the bid was not altered after the auction was closed. - -Use the `revealBid.js` application to reveal the bid of Bidder1: -``` -node revealBid.js org1 bidder1 PaintingAuction $BIDDER1_BID_ID -``` - -The full bid details, including the price, are now visible: -``` -*** Result: Auction: { - "objectType": "auction", - "item": "painting", - "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "organizations": [ - "Org1MSP", - "Org2MSP" - ], - "privateBids": { - "\u0000bid\u0000PaintingAuction\u000019a7a0dd2c5456a3f79c2f9ccb09dddd0f1c9ece514dfea7cbea06e7cbc79855\u0000": { - "org": "Org2MSP", - "hash": "08db66c6cc226577a3153dadeb0b77d3834162fcf5f008b344058a1bc5c1b3a4" - }, - "\u0000bid\u0000PaintingAuction\u00001b9dc0006fef10413df5cca927cabdf73ab854fe92b7a7b2eebfa00961fdac67\u0000": { - "org": "Org1MSP", - "hash": "15cd9a3e12825017f3e758499ac6138ebbe1adec4c49cc6ea6a0973fc6514666" - }, - "\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": { - "org": "Org1MSP", - "hash": "0b8bbdb96b1d252e71ac1ed71df3580f7a0e31a743a4a09bbf5196dffef426b2" - }, - "\u0000bid\u0000PaintingAuction\u00005ee4fa53b54ea0821e57a6884a1ada5eb04f136ee222e92d7399bcdf47556ea1\u0000": { - "org": "Org2MSP", - "hash": "14d47d17acceceb483e87c14a4349844874fce549d71c6a23457d953ed8ffbd3" - } - }, - "revealedBids": { - "\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": { - "objectType": "bid", - "price": 800, - "org": "Org1MSP", - "bidder": "x509::CN=bidder1,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US" - } - }, - "winner": "", - "price": 0, - "status": "closed" -} -``` - -Bidder3 from Org2 will also reveal their bid: -``` -node revealBid.js org2 bidder3 PaintingAuction $BIDDER3_BID_ID -``` - -If the auction ended now, Bidder1 would win. Let's try to end the auction using the seller identity and see what happens. - -``` -node endAuction.js org1 seller PaintingAuction -``` - -The output should look something like the following: - -``` ---> Submit the transaction to end the auction -2021-01-28T16:47:27.501Z - error: [DiscoveryHandler]: compareProposalResponseResults[undefined] - read/writes result sets do not match index=1 -2021-01-28T16:47:27.503Z - error: [Transaction]: Error: No valid responses from any peers. Errors: - peer=undefined, status=grpc, message=Peer endorsements do not match -******** FAILED to submit bid: Error: No valid responses from any peers. Errors: - peer=undefined, status=grpc, message=Peer endorsements do not match -``` - -Instead of ending the auction, the transaction results in an endorsement policy failure. The end of the auction needs to be endorsed by Org2. Before endorsing the transaction, the Org2 peer queries its private data collection for any winning bids that have not yet been revealed. Because Bidder4 created a bid that is above the winning price, the Org2 peer refuses to endorse the transaction that would end the auction. - -Before we can end the auction, we need to reveal the bid from bidder4. -``` -node revealBid.js org2 bidder4 PaintingAuction $BIDDER4_BID_ID -``` - -Bidder2 from Org1 would not win the auction in either case. As a result, Bidder2 decides not to reveal their bid. - -## End the auction - -Now that the winning bids have been revealed, we can end the auction: -``` -node endAuction org1 seller PaintingAuction -``` - -The transaction was successfully endorsed by both Org1 and Org2, who both calculated the same price and winner. The winning bidder is listed along with the price: -``` -*** Result: Auction: { - "objectType": "auction", - "item": "painting", - "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US", - "organizations": [ - "Org1MSP", - "Org2MSP" - ], - "privateBids": { - "\u0000bid\u0000PaintingAuction\u000019a7a0dd2c5456a3f79c2f9ccb09dddd0f1c9ece514dfea7cbea06e7cbc79855\u0000": { - "org": "Org2MSP", - "hash": "08db66c6cc226577a3153dadeb0b77d3834162fcf5f008b344058a1bc5c1b3a4" - }, - "\u0000bid\u0000PaintingAuction\u00001b9dc0006fef10413df5cca927cabdf73ab854fe92b7a7b2eebfa00961fdac67\u0000": { - "org": "Org1MSP", - "hash": "15cd9a3e12825017f3e758499ac6138ebbe1adec4c49cc6ea6a0973fc6514666" - }, - "\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": { - "org": "Org1MSP", - "hash": "0b8bbdb96b1d252e71ac1ed71df3580f7a0e31a743a4a09bbf5196dffef426b2" - }, - "\u0000bid\u0000PaintingAuction\u00005ee4fa53b54ea0821e57a6884a1ada5eb04f136ee222e92d7399bcdf47556ea1\u0000": { - "org": "Org2MSP", - "hash": "14d47d17acceceb483e87c14a4349844874fce549d71c6a23457d953ed8ffbd3" - } - }, - "revealedBids": { - "\u0000bid\u0000PaintingAuction\u000019a7a0dd2c5456a3f79c2f9ccb09dddd0f1c9ece514dfea7cbea06e7cbc79855\u0000": { - "objectType": "bid", - "price": 900, - "org": "Org2MSP", - "bidder": "x509::CN=bidder4,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK" - }, - "\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": { - "objectType": "bid", - "price": 800, - "org": "Org1MSP", - "bidder": "x509::CN=bidder1,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US" - }, - "\u0000bid\u0000PaintingAuction\u00005ee4fa53b54ea0821e57a6884a1ada5eb04f136ee222e92d7399bcdf47556ea1\u0000": { - "objectType": "bid", - "price": 700, - "org": "Org2MSP", - "bidder": "x509::CN=bidder3,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK" - } - }, - "winner": "x509::CN=bidder4,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK", - "price": 900, - "status": "ended" -} -``` - -## Clean up - -When your are done using the auction smart contract, you can bring down the network and clean up the environment. In the `auction-simple/application-javascript` directory, run the following command to remove the wallets used to run the applications: -``` -rm -rf wallet -``` - -You can then navigate to the test network directory and bring down the network: -```` -cd ../../test-network/ -./network.sh down -```` diff --git a/auction-simple/application-javascript/.eslintignore b/auction-simple/application-javascript/.eslintignore deleted file mode 100644 index 15958470..00000000 --- a/auction-simple/application-javascript/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -coverage diff --git a/auction-simple/application-javascript/.eslintrc.js b/auction-simple/application-javascript/.eslintrc.js deleted file mode 100644 index 20d4fcbd..00000000 --- a/auction-simple/application-javascript/.eslintrc.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -module.exports = { - env: { - node: true, - mocha: true - }, - parserOptions: { - ecmaVersion: 8, - sourceType: 'script' - }, - extends: 'eslint:recommended', - rules: { - indent: ['error', 'tab'], - 'linebreak-style': ['error', 'unix'], - quotes: ['error', 'single'], - semi: ['error', 'always'], - 'no-unused-vars': ['error', { args: 'none' }], - 'no-console': 'off', - curly: 'error', - eqeqeq: 'error', - 'no-throw-literal': 'error', - strict: 'error', - 'no-var': 'error', - 'dot-notation': 'error', - 'no-trailing-spaces': 'error', - 'no-use-before-define': 'error', - 'no-useless-call': 'error', - 'no-with': 'error', - 'operator-linebreak': 'error', - yoda: 'error', - 'quote-props': ['error', 'as-needed'] - } -}; diff --git a/auction-simple/application-javascript/bid.js b/auction-simple/application-javascript/bid.js deleted file mode 100644 index d4b4de56..00000000 --- a/auction-simple/application-javascript/bid.js +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function bid(ccp,wallet,user,orgMSP,auctionID,price) { - try { - - const gateway = new Gateway(); - // Connect using Discovery enabled - - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - console.log('\n--> Evaluate Transaction: get your client ID'); - let bidder = await contract.evaluateTransaction('GetSubmittingClientIdentity'); - console.log('*** Result: Bidder ID is ' + bidder.toString()); - - let bidData = { objectType: 'bid', price: parseInt(price), org: orgMSP, bidder: bidder.toString()}; - - let statefulTxn = contract.createTransaction('Bid'); - statefulTxn.setEndorsingOrganizations(orgMSP); - let tmapData = Buffer.from(JSON.stringify(bidData)); - statefulTxn.setTransient({ - bid: tmapData - }); - - let bidID = statefulTxn.getTransactionId(); - - console.log('\n--> Submit Transaction: Create the bid that is stored in your organization\'s private data collection'); - await statefulTxn.submit(auctionID); - console.log('*** Result: committed'); - console.log('*** Result ***SAVE THIS VALUE*** BidID: ' + bidID.toString()); - - console.log('\n--> Evaluate Transaction: read the bid that was just created'); - let result = await contract.evaluateTransaction('QueryBid',auctionID,bidID); - console.log('*** Result: Bid: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - -async function main() { - try { - - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined || process.argv[5] === undefined) { - console.log('Usage: node bid.js org userID auctionID price'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - const price = process.argv[5]; - - if (org === 'Org1' || org === 'org1') { - - const orgMSP = 'Org1MSP'; - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await bid(ccp,wallet,user,orgMSP,auctionID,price); - } - else if (org === 'Org2' || org === 'org2') { - - const orgMSP = 'Org2MSP'; - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await bid(ccp,wallet,user,orgMSP,auctionID,price); - } else { - console.log('Usage: node bid.js org userID auctionID price'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - process.exit(1); - } -} - -main(); diff --git a/auction-simple/application-javascript/closeAuction.js b/auction-simple/application-javascript/closeAuction.js deleted file mode 100644 index b637e761..00000000 --- a/auction-simple/application-javascript/closeAuction.js +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function closeAuction(ccp,wallet,user,auctionID) { - try { - - const gateway = new Gateway(); - - // Connect using Discovery enabled - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - // Query the auction to get the list of endorsing orgs. - let auctionString = await contract.evaluateTransaction('QueryAuction',auctionID); - let auctionJSON = JSON.parse(auctionString); - - let statefulTxn = contract.createTransaction('CloseAuction'); - - if (auctionJSON.organizations.length === 2) { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0],auctionJSON.organizations[1]); - } else { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0]); - } - - console.log('\n--> Submit Transaction: close auction'); - await statefulTxn.submit(auctionID); - console.log('*** Result: committed'); - - console.log('\n--> Evaluate Transaction: query the updated auction'); - let result = await contract.evaluateTransaction('QueryAuction',auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - process.exit(1); - } -} - -async function main() { - try { - - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined) { - console.log('Usage: node closeAuction.js org userID auctionID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await closeAuction(ccp,wallet,user,auctionID); - } - else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await closeAuction(ccp,wallet,user,auctionID); - } else { - console.log('Usage: node closeAuction.js org userID auctionID '); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - - -main(); diff --git a/auction-simple/application-javascript/createAuction.js b/auction-simple/application-javascript/createAuction.js deleted file mode 100644 index a05d4f96..00000000 --- a/auction-simple/application-javascript/createAuction.js +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function createAuction(ccp,wallet,user,auctionID,item) { - try { - - const gateway = new Gateway(); - - // Connect using Discovery enabled - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - let statefulTxn = contract.createTransaction('CreateAuction'); - - console.log('\n--> Submit Transaction: Propose a new auction'); - await statefulTxn.submit(auctionID,item); - console.log('*** Result: committed'); - - console.log('\n--> Evaluate Transaction: query the auction that was just created'); - let result = await contract.evaluateTransaction('QueryAuction',auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - } -} - -async function main() { - try { - - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined || process.argv[5] === undefined) { - console.log('Usage: node createAuction.js org userID auctionID item'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - const item = process.argv[5]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await createAuction(ccp,wallet,user,auctionID,item); - } - else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await createAuction(ccp,wallet,user,auctionID,item); - } else { - console.log('Usage: node createAuction.js org userID auctionID item'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - } -} - - -main(); diff --git a/auction-simple/application-javascript/endAuction.js b/auction-simple/application-javascript/endAuction.js deleted file mode 100644 index 27ea5983..00000000 --- a/auction-simple/application-javascript/endAuction.js +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function endAuction(ccp,wallet,user,auctionID) { - try { - - const gateway = new Gateway(); - - // Connect using Discovery enabled - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - // Query the auction to get the list of endorsing orgs. - let auctionString = await contract.evaluateTransaction('QueryAuction',auctionID); - let auctionJSON = JSON.parse(auctionString); - - let statefulTxn = contract.createTransaction('EndAuction'); - - if (auctionJSON.organizations.length === 2) { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0],auctionJSON.organizations[1]); - } else { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0]); - } - - console.log('\n--> Submit the transaction to end the auction'); - await statefulTxn.submit(auctionID); - console.log('*** Result: committed'); - - console.log('\n--> Evaluate Transaction: query the updated auction'); - let result = await contract.evaluateTransaction('QueryAuction',auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - process.exit(1); - } -} - -async function main() { - try { - - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined) { - console.log('Usage: node endAuction.js org userID auctionID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await endAuction(ccp,wallet,user,auctionID); - } - else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await endAuction(ccp,wallet,user,auctionID); - } else { - console.log('Usage: node endAuction.js org userID auctionID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - - -main(); diff --git a/auction-simple/application-javascript/enrollAdmin.js b/auction-simple/application-javascript/enrollAdmin.js deleted file mode 100644 index 1c87cad5..00000000 --- a/auction-simple/application-javascript/enrollAdmin.js +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Wallets } = require('fabric-network'); -const FabricCAServices = require('fabric-ca-client'); -const path = require('path'); -const { buildCAClient, enrollAdmin } = require('../../test-application/javascript/CAUtil.js'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); - -const mspOrg1 = 'Org1MSP'; -const mspOrg2 = 'Org2MSP'; - -async function connectToOrg1CA() { - console.log('\n--> Enrolling the Org1 CA admin'); - const ccpOrg1 = buildCCPOrg1(); - const caOrg1Client = buildCAClient(FabricCAServices, ccpOrg1, 'ca.org1.example.com'); - - const walletPathOrg1 = path.join(__dirname, 'wallet/org1'); - const walletOrg1 = await buildWallet(Wallets, walletPathOrg1); - - await enrollAdmin(caOrg1Client, walletOrg1, mspOrg1); - -} - -async function connectToOrg2CA() { - console.log('\n--> Enrolling the Org2 CA admin'); - const ccpOrg2 = buildCCPOrg2(); - const caOrg2Client = buildCAClient(FabricCAServices, ccpOrg2, 'ca.org2.example.com'); - - const walletPathOrg2 = path.join(__dirname, 'wallet/org2'); - const walletOrg2 = await buildWallet(Wallets, walletPathOrg2); - - await enrollAdmin(caOrg2Client, walletOrg2, mspOrg2); - -} -async function main() { - - if (process.argv[2] === undefined) { - console.log('Usage: node enrollAdmin.js Org'); - process.exit(1); - } - - const org = process.argv[2]; - - try { - - if (org === 'Org1' || org === 'org1') { - await connectToOrg1CA(); - } - else if (org === 'Org2' || org === 'org2') { - await connectToOrg2CA(); - } else { - console.log('Usage: node registerUser.js org userID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`Error in enrolling admin: ${error}`); - process.exit(1); - } -} - -main(); diff --git a/auction-simple/application-javascript/package.json b/auction-simple/application-javascript/package.json deleted file mode 100644 index 49bf01e8..00000000 --- a/auction-simple/application-javascript/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "auction", - "version": "1.0.0", - "description": "auction application implemented in JavaScript", - "engines": { - "node": ">=12", - "npm": ">=5" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "scripts": { - "lint": "eslint *.js" - }, - "dependencies": { - "fabric-ca-client": "^2.2.19", - "fabric-network": "^2.2.19" - }, - "devDependencies": { - "eslint": "^7.32.0" - } -} diff --git a/auction-simple/application-javascript/queryAuction.js b/auction-simple/application-javascript/queryAuction.js deleted file mode 100644 index 046267af..00000000 --- a/auction-simple/application-javascript/queryAuction.js +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function queryAuction(ccp,wallet,user,auctionID) { - try { - - const gateway = new Gateway(); - - // Connect using Discovery enabled - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - console.log('\n--> Evaluate Transaction: query the auction'); - let result = await contract.evaluateTransaction('QueryAuction',auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - } -} - -async function main() { - try { - - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined) { - console.log('Usage: node queryAuction.js org userID auctionID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await queryAuction(ccp,wallet,user,auctionID); - } - else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await queryAuction(ccp,wallet,user,auctionID); - } else { - console.log('Usage: node queryAuction.js org userID auctionID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - } -} - - -main(); diff --git a/auction-simple/application-javascript/queryBid.js b/auction-simple/application-javascript/queryBid.js deleted file mode 100644 index 57ce37ba..00000000 --- a/auction-simple/application-javascript/queryBid.js +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function queryBid(ccp,wallet,user,auctionID,bidID) { - try { - - const gateway = new Gateway(); - - // Connect using Discovery enabled - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - console.log('\n--> Evaluate Transaction: read bid from private data store'); - let result = await contract.evaluateTransaction('QueryBid',auctionID,bidID); - console.log('*** Result: Bid: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - } -} - -async function main() { - try { - - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined || process.argv[5] === undefined) { - console.log('Usage: node bid.js org userID auctionID bidID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - const bidID = process.argv[5]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await queryBid(ccp,wallet,user,auctionID,bidID); - } - else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await queryBid(ccp,wallet,user,auctionID,bidID); - } else { - console.log('Usage: node bid.js org userID auctionID bidID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - } -} - - -main(); diff --git a/auction-simple/application-javascript/registerEnrollUser.js b/auction-simple/application-javascript/registerEnrollUser.js deleted file mode 100644 index d6cb9a66..00000000 --- a/auction-simple/application-javascript/registerEnrollUser.js +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Wallets } = require('fabric-network'); -const FabricCAServices = require('fabric-ca-client'); -const path = require('path'); -const { buildCAClient, registerAndEnrollUser } = require('../../test-application/javascript/CAUtil.js'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); - -const mspOrg1 = 'Org1MSP'; -const mspOrg2 = 'Org2MSP'; - -async function connectToOrg1CA(UserID) { - console.log('\n--> Register and enrolling new user'); - const ccpOrg1 = buildCCPOrg1(); - const caOrg1Client = buildCAClient(FabricCAServices, ccpOrg1, 'ca.org1.example.com'); - - const walletPathOrg1 = path.join(__dirname, 'wallet/org1'); - const walletOrg1 = await buildWallet(Wallets, walletPathOrg1); - - await registerAndEnrollUser(caOrg1Client, walletOrg1, mspOrg1, UserID, 'org1.department1'); - -} - -async function connectToOrg2CA(UserID) { - console.log('\n--> Register and enrolling new user'); - const ccpOrg2 = buildCCPOrg2(); - const caOrg2Client = buildCAClient(FabricCAServices, ccpOrg2, 'ca.org2.example.com'); - - const walletPathOrg2 = path.join(__dirname, 'wallet/org2'); - const walletOrg2 = await buildWallet(Wallets, walletPathOrg2); - - await registerAndEnrollUser(caOrg2Client, walletOrg2, mspOrg2, UserID, 'org2.department1'); - -} -async function main() { - - if (process.argv[2] === undefined && process.argv[3] === undefined) { - console.log('Usage: node registerEnrollUser.js org userID'); - process.exit(1); - } - - const org = process.argv[2]; - const userId = process.argv[3]; - - try { - - if (org === 'Org1' || org === 'org1') { - await connectToOrg1CA(userId); - } - else if (org === 'Org2' || org === 'org2') { - await connectToOrg2CA(userId); - } else { - console.log('Usage: node registerEnrollUser.js org userID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`Error in enrolling admin: ${error}`); - process.exit(1); - } -} - -main(); diff --git a/auction-simple/application-javascript/revealBid.js b/auction-simple/application-javascript/revealBid.js deleted file mode 100644 index bb0b1a7f..00000000 --- a/auction-simple/application-javascript/revealBid.js +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - -async function addBid(ccp,wallet,user,auctionID,bidID) { - try { - - const gateway = new Gateway(); - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - console.log('\n--> Evaluate Transaction: read your bid'); - let bidString = await contract.evaluateTransaction('QueryBid',auctionID,bidID); - let bidJSON = JSON.parse(bidString); - - // console.log('\n--> Evaluate Transaction: query the auction you want to join'); - let auctionString = await contract.evaluateTransaction('QueryAuction',auctionID); - // console.log('*** Result: Bid: ' + prettyJSONString(auctionString.toString())); - let auctionJSON = JSON.parse(auctionString); - - let bidData = { objectType: 'bid', price: parseInt(bidJSON.price), org: bidJSON.org, bidder: bidJSON.bidder}; - console.log('*** Result: Bid: ' + JSON.stringify(bidData,null,2)); - - let statefulTxn = contract.createTransaction('RevealBid'); - let tmapData = Buffer.from(JSON.stringify(bidData)); - statefulTxn.setTransient({ - bid: tmapData - }); - - if (auctionJSON.organizations.length === 2) { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0],auctionJSON.organizations[1]); - } else { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0]); - } - - await statefulTxn.submit(auctionID,bidID); - - console.log('\n--> Evaluate Transaction: query the auction to see that our bid was added'); - let result = await contract.evaluateTransaction('QueryAuction',auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - process.exit(1); - } -} - -async function main() { - try { - - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined || process.argv[5] === undefined) { - console.log('Usage: node revealBid.js org userID auctionID bidID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - const bidID = process.argv[5]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await addBid(ccp,wallet,user,auctionID,bidID); - } - else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await addBid(ccp,wallet,user,auctionID,bidID); - } - else { - console.log('Usage: node revealBid.js org userID auctionID bidID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - - -main(); diff --git a/auction-simple/application-javascript/submitBid.js b/auction-simple/application-javascript/submitBid.js deleted file mode 100644 index 6c2e0669..00000000 --- a/auction-simple/application-javascript/submitBid.js +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict'; - -const { Gateway, Wallets } = require('fabric-network'); -const path = require('path'); -const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); - -const myChannel = 'mychannel'; -const myChaincodeName = 'auction'; - - -function prettyJSONString(inputString) { - if (inputString) { - return JSON.stringify(JSON.parse(inputString), null, 2); - } - else { - return inputString; - } -} - -async function submitBid(ccp,wallet,user,auctionID,bidID) { - try { - - const gateway = new Gateway(); - - // Connect using Discovery enabled - await gateway.connect(ccp, - { wallet: wallet, identity: user, discovery: { enabled: true, asLocalhost: true } }); - - const network = await gateway.getNetwork(myChannel); - const contract = network.getContract(myChaincodeName); - - console.log('\n--> Evaluate Transaction: query the auction you want to join'); - let auctionString = await contract.evaluateTransaction('QueryAuction',auctionID); - let auctionJSON = JSON.parse(auctionString); - - let statefulTxn = contract.createTransaction('SubmitBid'); - - if (auctionJSON.organizations.length === 2) { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0],auctionJSON.organizations[1]); - } else { - statefulTxn.setEndorsingOrganizations(auctionJSON.organizations[0]); - } - - console.log('\n--> Submit Transaction: add bid to the auction'); - await statefulTxn.submit(auctionID,bidID); - - console.log('\n--> Evaluate Transaction: query the auction to see that our bid was added'); - let result = await contract.evaluateTransaction('QueryAuction',auctionID); - console.log('*** Result: Auction: ' + prettyJSONString(result.toString())); - - gateway.disconnect(); - } catch (error) { - console.error(`******** FAILED to submit bid: ${error}`); - process.exit(1); - } -} - -async function main() { - try { - - if (process.argv[2] === undefined || process.argv[3] === undefined || - process.argv[4] === undefined || process.argv[5] === undefined) { - console.log('Usage: node submitBid.js org userID auctionID bidID'); - process.exit(1); - } - - const org = process.argv[2]; - const user = process.argv[3]; - const auctionID = process.argv[4]; - const bidID = process.argv[5]; - - if (org === 'Org1' || org === 'org1') { - const ccp = buildCCPOrg1(); - const walletPath = path.join(__dirname, 'wallet/org1'); - const wallet = await buildWallet(Wallets, walletPath); - await submitBid(ccp,wallet,user,auctionID,bidID); - } - else if (org === 'Org2' || org === 'org2') { - const ccp = buildCCPOrg2(); - const walletPath = path.join(__dirname, 'wallet/org2'); - const wallet = await buildWallet(Wallets, walletPath); - await submitBid(ccp,wallet,user,auctionID,bidID); - } - else { - console.log('Usage: node submitBid.js org userID auctionID bidID'); - console.log('Org must be Org1 or Org2'); - } - } catch (error) { - console.error(`******** FAILED to run the application: ${error}`); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - - -main(); diff --git a/auction-simple/chaincode-go/go.mod b/auction-simple/chaincode-go/go.mod deleted file mode 100644 index 3d087a3c..00000000 --- a/auction-simple/chaincode-go/go.mod +++ /dev/null @@ -1,28 +0,0 @@ -module github.com/hyperledger/fabric-samples/auction/chaincode-go - -go 1.22.0 - -require ( - github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 - github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 -) - -require ( - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.36.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/auction-simple/chaincode-go/go.sum b/auction-simple/chaincode-go/go.sum deleted file mode 100644 index fa4d3b24..00000000 --- a/auction-simple/chaincode-go/go.sum +++ /dev/null @@ -1,61 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 h1:IhkHfrl5X/fVnmB6pWeCYCdIJRi9bxj+WTnVN8DtW3c= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0/go.mod h1:PHHaFffjw7p7n9bmCfcm7RqDqYdivNEsJdiNIKZo5Lk= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 h1:rmUoBmciB0GL/miqcbJmJbgp5QTWoJUrZo+CNxrNLF4= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0/go.mod h1:FeWeO/jwGjiME7ak3GufqKIcwkejtzrDG4QxbfKydWs= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/auction-simple/chaincode-go/smart-contract/auction.go b/auction-simple/chaincode-go/smart-contract/auction.go deleted file mode 100644 index f0f5e14d..00000000 --- a/auction-simple/chaincode-go/smart-contract/auction.go +++ /dev/null @@ -1,448 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package auction - -import ( - "bytes" - "crypto/sha256" - "encoding/json" - "errors" - "fmt" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -type SmartContract struct { - contractapi.Contract -} - -// Auction data -type Auction struct { - Type string `json:"objectType"` - ItemSold string `json:"item"` - Seller string `json:"seller"` - Orgs []string `json:"organizations"` - PrivateBids map[string]BidHash `json:"privateBids"` - RevealedBids map[string]FullBid `json:"revealedBids"` - Winner string `json:"winner"` - Price int `json:"price"` - Status string `json:"status"` -} - -// FullBid is the structure of a revealed bid -type FullBid struct { - Type string `json:"objectType"` - Price int `json:"price"` - Org string `json:"org"` - Bidder string `json:"bidder"` -} - -// BidHash is the structure of a private bid -type BidHash struct { - Org string `json:"org"` - Hash string `json:"hash"` -} - -const bidKeyType = "bid" - -// CreateAuction creates on auction on the public channel. The identity that -// submits the transacion becomes the seller of the auction -func (s *SmartContract) CreateAuction(ctx contractapi.TransactionContextInterface, auctionID string, itemsold string) error { - - // get ID of submitting client - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - // get org of submitting client - clientOrgID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - // Create auction - bidders := make(map[string]BidHash) - revealedBids := make(map[string]FullBid) - - auction := Auction{ - Type: "auction", - ItemSold: itemsold, - Price: 0, - Seller: clientID, - Orgs: []string{clientOrgID}, - PrivateBids: bidders, - RevealedBids: revealedBids, - Winner: "", - Status: "open", - } - - auctionJSON, err := json.Marshal(auction) - if err != nil { - return err - } - - // put auction into state - err = ctx.GetStub().PutState(auctionID, auctionJSON) - if err != nil { - return fmt.Errorf("failed to put auction in public data: %v", err) - } - - // set the seller of the auction as an endorser - err = setAssetStateBasedEndorsement(ctx, auctionID, clientOrgID) - if err != nil { - return fmt.Errorf("failed setting state based endorsement for new organization: %v", err) - } - - return nil -} - -// Bid is used to add a user's bid to the auction. The bid is stored in the private -// data collection on the peer of the bidder's organization. The function returns -// the transaction ID so that users can identify and query their bid -func (s *SmartContract) Bid(ctx contractapi.TransactionContextInterface, auctionID string) (string, error) { - - // get bid from transient map - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return "", fmt.Errorf("error getting transient: %v", err) - } - - BidJSON, ok := transientMap["bid"] - if !ok { - return "", errors.New("bid key not found in the transient map") - } - - // get the implicit collection name using the bidder's organization ID - collection, err := getCollectionName(ctx) - if err != nil { - return "", fmt.Errorf("failed to get implicit collection name: %v", err) - } - - // the bidder has to target their peer to store the bid - err = verifyClientOrgMatchesPeerOrg(ctx) - if err != nil { - return "", fmt.Errorf("cannot store bid on this peer, not a member of this org: Error %v", err) - } - - // the transaction ID is used as a unique index for the bid - txID := ctx.GetStub().GetTxID() - - // create a composite key using the transaction ID - bidKey, err := ctx.GetStub().CreateCompositeKey(bidKeyType, []string{auctionID, txID}) - if err != nil { - return "", fmt.Errorf("failed to create composite key: %v", err) - } - - // put the bid into the organization's implicit data collection - err = ctx.GetStub().PutPrivateData(collection, bidKey, BidJSON) - if err != nil { - return "", fmt.Errorf("failed to input price into collection: %v", err) - } - - // return the trannsaction ID so that the uset can identify their bid - return txID, nil -} - -// SubmitBid is used by the bidder to add the hash of that bid stored in private data to the -// auction. Note that this function alters the auction in private state, and needs -// to meet the auction endorsement policy. Transaction ID is used identify the bid -func (s *SmartContract) SubmitBid(ctx contractapi.TransactionContextInterface, auctionID string, txID string) error { - - // get the MSP ID of the bidder's org - clientOrgID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return fmt.Errorf("failed to get client MSP ID: %v", err) - } - - // get the auction from public state - auction, err := s.QueryAuction(ctx, auctionID) - if err != nil { - return fmt.Errorf("failed to get auction from public state %v", err) - } - - // the auction needs to be open for users to add their bid - Status := auction.Status - if Status != "open" { - return errors.New("cannot join closed or ended auction") - } - - // get the inplicit collection name of bidder's org - collection, err := getCollectionName(ctx) - if err != nil { - return fmt.Errorf("failed to get implicit collection name: %v", err) - } - - // use the transaction ID passed as a parameter to create composite bid key - bidKey, err := ctx.GetStub().CreateCompositeKey(bidKeyType, []string{auctionID, txID}) - if err != nil { - return fmt.Errorf("failed to create composite key: %v", err) - } - - // get the hash of the bid stored in private data collection - bidHash, err := ctx.GetStub().GetPrivateDataHash(collection, bidKey) - if err != nil { - return fmt.Errorf("failed to read bid bash from collection: %v", err) - } - if bidHash == nil { - return fmt.Errorf("bid hash does not exist: %s", bidKey) - } - - // store the hash along with the bidder's organization - NewHash := BidHash{ - Org: clientOrgID, - Hash: fmt.Sprintf("%x", bidHash), - } - - auction.PrivateBids[bidKey] = NewHash - - // Add the bidding organization to the list of participating organizations if it is not already - Orgs := auction.Orgs - if !(contains(Orgs, clientOrgID)) { - newOrgs := append(Orgs, clientOrgID) - auction.Orgs = newOrgs - - err = addAssetStateBasedEndorsement(ctx, auctionID, clientOrgID) - if err != nil { - return fmt.Errorf("failed setting state based endorsement for new organization: %v", err) - } - } - - newAuctionJSON, _ := json.Marshal(auction) - - err = ctx.GetStub().PutState(auctionID, newAuctionJSON) - if err != nil { - return fmt.Errorf("failed to update auction: %v", err) - } - - return nil -} - -// RevealBid is used by a bidder to reveal their bid after the auction is closed -func (s *SmartContract) RevealBid(ctx contractapi.TransactionContextInterface, auctionID string, txID string) error { - - // get bid from transient map - transientMap, err := ctx.GetStub().GetTransient() - if err != nil { - return fmt.Errorf("error getting transient: %v", err) - } - - transientBidJSON, ok := transientMap["bid"] - if !ok { - return errors.New("bid key not found in the transient map") - } - - // get implicit collection name of organization ID - collection, err := getCollectionName(ctx) - if err != nil { - return fmt.Errorf("failed to get implicit collection name: %v", err) - } - - // use transaction ID to create composit bid key - bidKey, err := ctx.GetStub().CreateCompositeKey(bidKeyType, []string{auctionID, txID}) - if err != nil { - return fmt.Errorf("failed to create composite key: %v", err) - } - - // get bid hash of bid if private bid on the public ledger - bidHash, err := ctx.GetStub().GetPrivateDataHash(collection, bidKey) - if err != nil { - return fmt.Errorf("failed to read bid bash from collection: %v", err) - } - if bidHash == nil { - return fmt.Errorf("bid hash does not exist: %s", bidKey) - } - - // get auction from public state - auction, err := s.QueryAuction(ctx, auctionID) - if err != nil { - return fmt.Errorf("failed to get auction from public state %v", err) - } - - // Complete a series of three checks before we add the bid to the auction - - // check 1: check that the auction is closed. We cannot reveal a - // bid to an open auction - Status := auction.Status - if Status != "closed" { - return errors.New("cannot reveal bid for open or ended auction") - } - - // check 2: check that hash of revealed bid matches hash of private bid - // on the public ledger. This checks that the bidder is telling the truth - // about the value of their bid - - hash := sha256.New() - hash.Write(transientBidJSON) - calculatedBidJSONHash := hash.Sum(nil) - - // verify that the hash of the passed immutable properties matches the on-chain hash - if !bytes.Equal(calculatedBidJSONHash, bidHash) { - return fmt.Errorf("hash %x for bid JSON %s does not match hash in auction: %x", - calculatedBidJSONHash, - transientBidJSON, - bidHash, - ) - } - - // check 3; check hash of relealed bid matches hash of private bid that was - // added earlier. This ensures that the bid has not changed since it - // was added to the auction - - privateBidHashString := auction.PrivateBids[bidKey].Hash - - onChainBidHashString := fmt.Sprintf("%x", bidHash) - if privateBidHashString != onChainBidHashString { - return fmt.Errorf("hash %s for bid JSON %s does not match hash in auction: %s, bidder must have changed bid", - privateBidHashString, - transientBidJSON, - onChainBidHashString, - ) - } - - // we can add the bid to the auction if all checks have passed - type transientBidInput struct { - Price int `json:"price"` - Org string `json:"org"` - Bidder string `json:"bidder"` - } - - // unmarshal bid input - var bidInput transientBidInput - err = json.Unmarshal(transientBidJSON, &bidInput) - if err != nil { - return fmt.Errorf("failed to unmarshal JSON: %v", err) - } - - // Get ID of submitting client identity - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - // marshal transient parameters and ID and MSPID into bid object - NewBid := FullBid{ - Type: bidKeyType, - Price: bidInput.Price, - Org: bidInput.Org, - Bidder: bidInput.Bidder, - } - - // check 4: make sure that the transaction is being submitted is the bidder - if bidInput.Bidder != clientID { - return fmt.Errorf("permission denied, client id %v is not the owner of the bid", clientID) - } - - auction.RevealedBids[bidKey] = NewBid - - newAuctionJSON, _ := json.Marshal(auction) - - // put auction with bid added back into state - err = ctx.GetStub().PutState(auctionID, newAuctionJSON) - if err != nil { - return fmt.Errorf("failed to update auction: %v", err) - } - - return nil -} - -// CloseAuction can be used by the seller to close the auction. This prevents -// bids from being added to the auction, and allows users to reveal their bid -func (s *SmartContract) CloseAuction(ctx contractapi.TransactionContextInterface, auctionID string) error { - - // get auction from public state - auction, err := s.QueryAuction(ctx, auctionID) - if err != nil { - return fmt.Errorf("failed to get auction from public state %v", err) - } - - // the auction can only be closed by the seller - - // get ID of submitting client - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - Seller := auction.Seller - if Seller != clientID { - return fmt.Errorf("auction can only be closed by seller: %v", err) - } - - Status := auction.Status - if Status != "open" { - return errors.New("cannot close auction that is not open") - } - - auction.Status = string("closed") - - closedAuctionJSON, _ := json.Marshal(auction) - - err = ctx.GetStub().PutState(auctionID, closedAuctionJSON) - if err != nil { - return fmt.Errorf("failed to close auction: %v", err) - } - - return nil -} - -// EndAuction both changes the auction status to closed and calculates the winners -// of the auction -func (s *SmartContract) EndAuction(ctx contractapi.TransactionContextInterface, auctionID string) error { - - // get auction from public state - auction, err := s.QueryAuction(ctx, auctionID) - if err != nil { - return fmt.Errorf("failed to get auction from public state %v", err) - } - - // Check that the auction is being ended by the seller - - // get ID of submitting client - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return fmt.Errorf("failed to get client identity %v", err) - } - - Seller := auction.Seller - if Seller != clientID { - return fmt.Errorf("auction can only be ended by seller: %v", err) - } - - Status := auction.Status - if Status != "closed" { - return errors.New("can only end a closed auction") - } - - // get the list of revealed bids - revealedBidMap := auction.RevealedBids - if len(auction.RevealedBids) == 0 { - return fmt.Errorf("no bids have been revealed, cannot end auction: %v", err) - } - - // determine the highest bid - for _, bid := range revealedBidMap { - if bid.Price > auction.Price { - auction.Winner = bid.Bidder - auction.Price = bid.Price - } - } - - // check if there is a winning bid that has yet to be revealed - err = checkForHigherBid(ctx, auction.Price, auction.RevealedBids, auction.PrivateBids) - if err != nil { - return fmt.Errorf("cannot end auction: %v", err) - } - - auction.Status = "ended" - - endedAuctionJSON, _ := json.Marshal(auction) - - err = ctx.GetStub().PutState(auctionID, endedAuctionJSON) - if err != nil { - return fmt.Errorf("failed to end auction: %v", err) - } - return nil -} diff --git a/auction-simple/chaincode-go/smart-contract/auctionQueries.go b/auction-simple/chaincode-go/smart-contract/auctionQueries.go deleted file mode 100644 index cd99558b..00000000 --- a/auction-simple/chaincode-go/smart-contract/auctionQueries.go +++ /dev/null @@ -1,137 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package auction - -import ( - "encoding/json" - "errors" - "fmt" - - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -// QueryAuction allows all members of the channel to read a public auction -func (s *SmartContract) QueryAuction(ctx contractapi.TransactionContextInterface, auctionID string) (*Auction, error) { - - auctionJSON, err := ctx.GetStub().GetState(auctionID) - if err != nil { - return nil, fmt.Errorf("failed to get auction object %v: %v", auctionID, err) - } - if auctionJSON == nil { - return nil, errors.New("auction does not exist") - } - - var auction *Auction - err = json.Unmarshal(auctionJSON, &auction) - if err != nil { - return nil, err - } - - return auction, nil -} - -// QueryBid allows the submitter of the bid to read their bid from public state -func (s *SmartContract) QueryBid(ctx contractapi.TransactionContextInterface, auctionID string, txID string) (*FullBid, error) { - - err := verifyClientOrgMatchesPeerOrg(ctx) - if err != nil { - return nil, fmt.Errorf("failed to get implicit collection name: %v", err) - } - - clientID, err := s.GetSubmittingClientIdentity(ctx) - if err != nil { - return nil, fmt.Errorf("failed to get client identity %v", err) - } - - collection, err := getCollectionName(ctx) - if err != nil { - return nil, fmt.Errorf("failed to get implicit collection name: %v", err) - } - - bidKey, err := ctx.GetStub().CreateCompositeKey(bidKeyType, []string{auctionID, txID}) - if err != nil { - return nil, fmt.Errorf("failed to create composite key: %v", err) - } - - bidJSON, err := ctx.GetStub().GetPrivateData(collection, bidKey) - if err != nil { - return nil, fmt.Errorf("failed to get bid %v: %v", bidKey, err) - } - if bidJSON == nil { - return nil, fmt.Errorf("bid %v does not exist", bidKey) - } - - var bid *FullBid - err = json.Unmarshal(bidJSON, &bid) - if err != nil { - return nil, err - } - - // check that the client querying the bid is the bid owner - if bid.Bidder != clientID { - return nil, fmt.Errorf("permission denied, client id %v is not the owner of the bid", clientID) - } - - return bid, nil -} - -// checkForHigherBid is an internal function that is used to determine if a winning bid has yet to be revealed -func checkForHigherBid(ctx contractapi.TransactionContextInterface, auctionPrice int, revealedBidders map[string]FullBid, bidders map[string]BidHash) error { - - // Get MSP ID of peer org - peerMSPID, err := shim.GetMSPID() - if err != nil { - return fmt.Errorf("failed getting the peer's MSPID: %v", err) - } - - var error error - error = nil - - for bidKey, privateBid := range bidders { - - if _, bidInAuction := revealedBidders[bidKey]; bidInAuction { - - // bid is already revealed, no action to take - - } else { - - collection := "_implicit_org_" + privateBid.Org - - if privateBid.Org == peerMSPID { - - bidJSON, err := ctx.GetStub().GetPrivateData(collection, bidKey) - if err != nil { - return fmt.Errorf("failed to get bid %v: %v", bidKey, err) - } - if bidJSON == nil { - return fmt.Errorf("bid %v does not exist", bidKey) - } - - var bid *FullBid - err = json.Unmarshal(bidJSON, &bid) - if err != nil { - return err - } - - if bid.Price > auctionPrice { - error = fmt.Errorf("cannot close auction, bidder has a higher price: %v", err) - } - - } else { - - Hash, err := ctx.GetStub().GetPrivateDataHash(collection, bidKey) - if err != nil { - return fmt.Errorf("failed to read bid hash from collection: %v", err) - } - if Hash == nil { - return fmt.Errorf("bid hash does not exist: %s", bidKey) - } - } - } - } - - return error -} diff --git a/auction-simple/chaincode-go/smart-contract/utils.go b/auction-simple/chaincode-go/smart-contract/utils.go deleted file mode 100644 index b663e608..00000000 --- a/auction-simple/chaincode-go/smart-contract/utils.go +++ /dev/null @@ -1,121 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package auction - -import ( - "encoding/base64" - "fmt" - - "github.com/hyperledger/fabric-chaincode-go/v2/pkg/statebased" - "github.com/hyperledger/fabric-chaincode-go/v2/shim" - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -func (s *SmartContract) GetSubmittingClientIdentity(ctx contractapi.TransactionContextInterface) (string, error) { - - b64ID, err := ctx.GetClientIdentity().GetID() - if err != nil { - return "", fmt.Errorf("failed to read clientID: %v", err) - } - decodeID, err := base64.StdEncoding.DecodeString(b64ID) - if err != nil { - return "", fmt.Errorf("failed to base64 decode clientID: %v", err) - } - return string(decodeID), nil -} - -// setAssetStateBasedEndorsement sets the endorsement policy of a new auction -func setAssetStateBasedEndorsement(ctx contractapi.TransactionContextInterface, auctionID string, orgToEndorse string) error { - - endorsementPolicy, err := statebased.NewStateEP(nil) - if err != nil { - return err - } - err = endorsementPolicy.AddOrgs(statebased.RoleTypePeer, orgToEndorse) - if err != nil { - return fmt.Errorf("failed to add org to endorsement policy: %v", err) - } - policy, err := endorsementPolicy.Policy() - if err != nil { - return fmt.Errorf("failed to create endorsement policy bytes from org: %v", err) - } - err = ctx.GetStub().SetStateValidationParameter(auctionID, policy) - if err != nil { - return fmt.Errorf("failed to set validation parameter on auction: %v", err) - } - - return nil -} - -// addAssetStateBasedEndorsement adds a new organization as an endorser of the auction -func addAssetStateBasedEndorsement(ctx contractapi.TransactionContextInterface, auctionID string, orgToEndorse string) error { - - endorsementPolicy, err := ctx.GetStub().GetStateValidationParameter(auctionID) - if err != nil { - return err - } - - newEndorsementPolicy, err := statebased.NewStateEP(endorsementPolicy) - if err != nil { - return err - } - - err = newEndorsementPolicy.AddOrgs(statebased.RoleTypePeer, orgToEndorse) - if err != nil { - return fmt.Errorf("failed to add org to endorsement policy: %v", err) - } - policy, err := newEndorsementPolicy.Policy() - if err != nil { - return fmt.Errorf("failed to create endorsement policy bytes from org: %v", err) - } - err = ctx.GetStub().SetStateValidationParameter(auctionID, policy) - if err != nil { - return fmt.Errorf("failed to set validation parameter on auction: %v", err) - } - - return nil -} - -// getCollectionName is an internal helper function to get collection of submitting client identity. -func getCollectionName(ctx contractapi.TransactionContextInterface) (string, error) { - - // Get the MSP ID of submitting client identity - clientMSPID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return "", fmt.Errorf("failed to get verified MSPID: %v", err) - } - - // Create the collection name - orgCollection := "_implicit_org_" + clientMSPID - - return orgCollection, nil -} - -// verifyClientOrgMatchesPeerOrg is an internal function used to verify that client org id matches peer org id. -func verifyClientOrgMatchesPeerOrg(ctx contractapi.TransactionContextInterface) error { - clientMSPID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return fmt.Errorf("failed getting the client's MSPID: %v", err) - } - peerMSPID, err := shim.GetMSPID() - if err != nil { - return fmt.Errorf("failed getting the peer's MSPID: %v", err) - } - - if clientMSPID != peerMSPID { - return fmt.Errorf("client from org %v is not authorized to read or write private data from an org %v peer", clientMSPID, peerMSPID) - } - - return nil -} - -func contains(sli []string, str string) bool { - for _, a := range sli { - if a == str { - return true - } - } - return false -} diff --git a/auction-simple/chaincode-go/smartContract.go b/auction-simple/chaincode-go/smartContract.go deleted file mode 100644 index c165075d..00000000 --- a/auction-simple/chaincode-go/smartContract.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "log" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" - "github.com/hyperledger/fabric-samples/auction/chaincode-go/smart-contract" -) - -func main() { - auctionSmartContract, err := contractapi.NewChaincode(&auction.SmartContract{}) - if err != nil { - log.Panicf("Error creating auction chaincode: %v", err) - } - - if err := auctionSmartContract.Start(); err != nil { - log.Panicf("Error starting auction chaincode: %v", err) - } -} diff --git a/full-stack-asset-transfer-guide/.gitignore b/full-stack-asset-transfer-guide/.gitignore deleted file mode 100644 index a7148016..00000000 --- a/full-stack-asset-transfer-guide/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -fabric -_cfg -node_modules -*.bin -.idea/ -_* -*tgz -*.tar.gz -~*.pptx - -bin -config/ - -.DS_Store -.idea/ - -rook \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/LICENSE b/full-stack-asset-transfer-guide/LICENSE deleted file mode 100644 index 261eeb9e..00000000 --- a/full-stack-asset-transfer-guide/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/full-stack-asset-transfer-guide/README.md b/full-stack-asset-transfer-guide/README.md deleted file mode 100644 index 2d886005..00000000 --- a/full-stack-asset-transfer-guide/README.md +++ /dev/null @@ -1,108 +0,0 @@ -![Conga](https://avatars.githubusercontent.com/u/49026922?s=200&v=4) - -# Fabric Full Stack Development Workshop - -![Hyperledger](https://img.shields.io/badge/hyperledger-2F3134?style=for-the-badge&logo=hyperledger&logoColor=white) - -Hyperledger Fabric can be used to represent assets of any kind on a permissioned decentralized ledger, from fungible tokens to non-fungible tokens, including monetary products, marbles, pineapples, classic cars, fine art, and anything else you can imagine. -Fabric can be used to track and update anything about these assets, common examples include asset ownership, exchange, provenance, and lifecycle. - -This workshop will demonstrate how a generic asset transfer solution can be modeled and deployed to take advantage of a blockchains qualitites of service. - -The workshop will be split into three sections: -- Smart Contract Development -- Client Application Development -- Cloud Native Fabric Deployment - -![Intro diagram](./docs/images/readme_diagram.png) - -**OBJECTIVES:** - -- Show how an Asset Transfer smart contract can be written to encapsulate business logic - - Show how the smart contract can be developed iteratively to get correct function in a development context -- Show how client applications can be written using the Gateway functionality - - Show how the simplification of the Gateway programming model makes connecting applications more streamlined - - Show how this streamlined approach improves resilience and availability -- Show how the solution can then be deployed to a production-class environment - - Show how a Hyperledger Fabric network can be created and managed in Kubernetes (K8S) using automation - - Show how the Fabric Operator and Console can be installed via Ansible playbooks - - Show how a multi-organization configuration of Fabric can be created - ---- - -**Please ensure you've got the [required tools](./SETUP.md) on your local machine or in a virtual machine -- To check, run `./check.sh`** - ---- - - -## Before you begin.... - -Fabric is a multi-server decentralized system with orderer and peer nodes, so it can be quite complex to configure. Even the simplest smart contract needs a running Fabric Infrastructure and one size does not fit all. - -There are configurations that can run Fabric either as local binaries, in a single docker container, in multiple containers, or in K8S. -This workshop will show some of the approaches that can be used for developing applications and contracts with a minimal Fabric environment (Microfab), and how a production deployment can be achieved. -There are other ways of deploying Fabric produced by the community - these are equally valid and useful. Feel free to try the others, once you understand the basic concepts to find what works best for you. - -At a high-level remember that a solution using Fabric has (a) client application to send in transaction requests (b) Fabric infrastructure to service those requests (c) Smart Contract to action the transactions. -The nature of (b) the fabric infrastructure will change depending on your scenario; start simple and build up. The smart contracts and client application's code will remain the same no matter the way Fabric is provisioned. -There will be minor variations in deployment (eg local docker container vs remote K8S cluster) but fundamentally the process is the same. - -## Running the workshop - -![Windows](https://img.shields.io/badge/Windows-0078D6?style=for-the-badge&logo=windows&logoColor=white) If you're running on Windows, please check the [hints and tips](./docs/tips-for-windows-dev.md) - -- Ensure you've got the tools you may need, either installed locally or in a multipass virtual machine. See the [setup page](./SETUP.md) for details. -- Clone this repository to a convient location -- We suggest that you open 3 or 4 terminal windows - - One for running chaincode in dev mode - - One for running the fabric infrastructure and optionally one for monitoring it - - One for client applications - -- Work through the sections below in order, although you don't necessarily need to complete all the Exercises before moving to the next section. - ---- -## Scenario - -Lets assume the assets you are tracking on the blockchain ledger are trading cards. Each trading card represents a comic book character and has an id, size, favorite color, and owner. -These trading cards can be passed between people, with some cards having more 'value' due to rarity or having notable attributes. - -In token terms, think of these cards as non-fungible tokens. Each card has different attributes and individual cards can't be subdivided. - -We'll create a digital representation of these cards on the blockchain ledger. There are a few important aspects of this solution to consider: - -- Ledger - The blockchain ledger on each peer maintains the current state of each card (asset), as well as the history of transactions that led to the current state, so that there is no doubt about the assets issuance, provenance, attributes, and ownership. -- Asset transfer smart contract - manage changes to asset state such as the transfer of cards between people -- Organizations - Since this is a permissioned blockchain we'll model the participants as organizations that are authorized to run nodes or transact on the Fabric network. Our simple network will consist of an ordering service organization and two transacting organizations. - - Ordering service organization - runs the ordering service to ensure transactions get ordered into blocks fairly, this may be a consortium leader or regulator in the industry. Note that ordering service nodes could also be contributed from multiple organizations, this becomes especially important when running a Byzantine Fault Tolerant (BFT) ordering service. - - Owner Organizations - Each owner organization is authorized to run peers and submit transfer transactions for the cards (assets) that they own. - - -## Smart Contract Development - -- [Introduction](./docs/SmartContractDev/00-Introduction.md) [Español](./docs/SmartContractDev/00-Introduction-ES.md) -- **Exercise**: [Getting Started with a Smart Contract](./docs/SmartContractDev/01-Exercise-Getting-Started.md) [Español](./docs/SmartContractDev/01-Exercise-Getting-Started-ES.md) -- **Exercise**: [Adding a new transaction function](./docs/SmartContractDev/02-Exercise-Adding-tx-function.md) [Español](./docs/SmartContractDev/02-Exercise-Adding-tx-function-ES.md) -- Reference: - - [Detailed Test and Debug](./docs/SmartContractDev/03-Test-And-Debug-Reference.md) [Español](./docs/SmartContractDev/03-Test-And-Debug-Reference-ES.md) - -## Client Application Development - -- [Fabric Gateway](docs/ApplicationDev/01-FabricGateway.md) -- **Exercise:** [Run the client application](docs/ApplicationDev/02-Exercise-RunApplication.md) -- [Application overview](docs/ApplicationDev/03-ApplicationOverview.md) -- **Exercise:** [Implement asset transfer](docs/ApplicationDev/04-Exercise-AssetTransfer.md) -- [Chaincode events](docs/ApplicationDev/05-ChaincodeEvents.md) -- **Exercise:** [Use chaincode events](docs/ApplicationDev/06-Exercise-ChaincodeEvents.md) - -## Cloud Native Fabric - -- [Cloud Ready!](docs/CloudReady/00-setup.md) [中文](docs/CloudReady/00-setup-zh.md) -- **Exercise:** [Deploy a Kubernetes Cluster](docs/CloudReady/10-kube.md) [中文](docs/CloudReady/10-kube-zh.md) -- **Exercise:** [Deploy a Fabric Network](docs/CloudReady/20-fabric.md) [中文](docs/CloudReady/20-fabric-zh.md) -- **Exercise:** [Deploy a Smart Contract](docs/CloudReady/30-chaincode.md)[中文](docs/CloudReady/30-chaincode-zh.md) -- **Exercise:** [Deploy a Client Application](docs/CloudReady/40-bananas.md)[中文](docs/CloudReady/40-bananas-zh.md) - -## Epilogue - -- [Go Bananas](docs/CloudReady/40-bananas.md) -- [Bring it Home](docs/CloudReady/90-teardown.md) diff --git a/full-stack-asset-transfer-guide/SETUP.md b/full-stack-asset-transfer-guide/SETUP.md deleted file mode 100644 index 4f8f0d2d..00000000 --- a/full-stack-asset-transfer-guide/SETUP.md +++ /dev/null @@ -1,138 +0,0 @@ -# Essential Setup - -Remember to clone this repository! - -```shell -git clone https://github.com/hyperledger/fabric-samples.git fabric-samples -cd fabric-samples/full-stack-asset-transfer-guide -export WORKSHOP_PATH=$(pwd) -``` - -> to check the tools you already have `./check.sh` - -## Option 1: Use local environment - -Do you want to configure your local environment with the workshop dependencies? - -- To develop an application and/or contract (first two parts of workshop) follow the *DEV* setup below - -- To deploy a chaincode to kubernetes in a production manner (third part of workshop) follow the *PROD* setup below - -## Option 2: Use a Multipass Ubuntu image - -If you do not want to install dependencies on your local environment, you can use a Multipass Ubuntu image instead. - -Tip - You may need to stop any VPN client for the Multipass networking to work. - -- [Install multipass](https://multipass.run/install) - -- Launch the virtual machine and automatically install the workshop dependencies: - -```shell -multipass launch \ - --name fabric-dev \ - --disk 80G \ - --cpus 8 \ - --mem 8G \ - --cloud-init infrastructure/multipass-cloud-config.yaml -``` - -- Mount the local workshop to your multipass vm: - -```shell -multipass mount $PWD fabric-dev:/home/ubuntu/full-stack-asset-transfer-guide -``` - -- Open a shell on the virtual machine: - -```shell -multipass shell fabric-dev -``` - -Tip - The vm creation log can be seen at /var/log/cloud-init-output.log if you need to troubleshoot anything. - -- You are now inside the virtual machine. cd to the workshop directory: - -```shell -cd full-stack-asset-transfer-guide -``` - -- Install Fabric peer CLI and set environment variables -```shell -curl -sSLO https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh && chmod +x install-fabric.sh -./install-fabric.sh binary -export WORKSHOP_PATH=$(pwd) -export PATH=${WORKSHOP_PATH}/bin:$PATH -export FABRIC_CFG_PATH=${WORKSHOP_PATH}/config -``` - -Note - You'll probably want three terminal windows for running the workshop, go ahead and open the shells now: - -```shell -multipass shell fabric-dev -``` - -- Eventual cleanup - To remove the multipass image when you are done with it after the workshop: -```shell -multipass delete fabric-dev -multipass purge -multipass list -``` - -## DEV - Required Tools - -You will need a set of tools to assist with chaincode and application development. -We'll assume you are developing in Node for this workshop, but you could also develop in Java or Go by installing the respective compilers. - -- [docker engine](https://docs.docker.com/engine/install/) - -- [just](https://github.com/casey/just#installation) to run all the commands here directly - -- [nvm](https://github.com/nvm-sh/nvm#installing-and-updating) to install node and npm -```shell -curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash -``` - -- [node v16 and npm](https://github.com/nvm-sh/nvm#usage) to run node chaincode and applications -```shell -nvm install 16 -``` - -- [typescript](https://www.typescriptlang.org/download) to compile typescript chaincode and applications to node -```shell -npm install -g typescript -``` - -- [weft ](https://www.npmjs.com/package/@hyperledger-labs/weft) Hyperledger-Labs cli to work with identities and chaincode packages -```shell -npm install -g @hyperledger-labs/weft -``` - -- [jq](https://stedolan.github.io/jq/) jq JSON command-line processor -```shell -sudo apt-get update && sudo apt-get install -y jq -``` - -- Fabric peer CLI -```shell -curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary -export WORKSHOP_PATH=$(pwd) -export PATH=${WORKSHOP_PATH}/bin:$PATH -export FABRIC_CFG_PATH=${WORKSHOP_PATH}/config -``` - -## PROD - Required Tools for Kubernetes Deployment - -- [kubectl](https://kubernetes.io/docs/tasks/tools/) -- [jq](https://stedolan.github.io/jq/) -- [just](https://github.com/casey/just#installation) to run all the comamnds here directly -- [kind](https://kind.sigs.k8s.io/) if you want to create a cluster locally, see below for other options -- [k9s](https://k9scli.io) (recommended, but not essential) - -### Beta Ansible Playbooks - -The v2.0.0-beta Ansible Collection for Hyperledger Fabric is required for Kubernetes deployment. This isn't yet being published to DockerHub but is being published to Github Packages. - -For reference check the latest version of [ofs-ansible](https://github.com/IBM-Blockchain/ansible-collection/pkgs/container/ofs-ansibe) - -The Ansible scripts in the workshop are set to use the latest image here by default. diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/.eslintrc.js b/full-stack-asset-transfer-guide/applications/conga-cards/.eslintrc.js deleted file mode 100644 index ad992fae..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/.eslintrc.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - root: true, - parser: '@typescript-eslint/parser', - plugins: [ - '@typescript-eslint', - ], - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'prettier', - ], -}; \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/.gitignore b/full-stack-asset-transfer-guide/applications/conga-cards/.gitignore deleted file mode 100644 index 1276eb3b..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -# Coverage directory used by tools like istanbul -coverage - -# Dependencies -node_modules/ -jspm_packages/ -package-lock.json - -# Compiled TypeScript files -dist - -# Files generated by the application at runtime -checkpoint.json -store.log diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/.npmrc b/full-stack-asset-transfer-guide/applications/conga-cards/.npmrc deleted file mode 100644 index b6f27f13..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/.npmrc +++ /dev/null @@ -1 +0,0 @@ -engine-strict=true diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/README.md b/full-stack-asset-transfer-guide/applications/conga-cards/README.md deleted file mode 100644 index e99b1bcc..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# Conga Cards - -This Gateway Client application will listen for chaincode events, invoking a [#discord webhook](https://discord.com/developers/docs/resources/webhook) -to post a channel message when [Conga Cards](assets/) are created, deleted, and exchanged on a channel. - -> [Conga Comics](https://congacomic.github.io) | Life on the chain, one block at a time by Ed Moffatt & some friends - -This project is based on the [trader-typescript](../trader-typescript) sample Gateway Client application. - - -## Prerequisites - -The client application requires Node.js 16 or later. - -## Set up - -The following steps prepare the client application for execution: - -1. Ensure the [asset-transfer](../../contracts/asset-transfer-typescript/) smart contract is deployed to a running Fabric network. -1. Run `npm install` to download dependencies and compile the application code. - -> **Note:** After making any code changes to the application, be sure to recompile the application code. This can be done by explicitly running `npm install` again, or you can leave `npm run build:watch` running in a terminal window to automatically rebuild the application on any code change. - - -The client application uses environment variables to supply configuration options. You must set the following environment variables when running the application: - -- `ENDPOINT` - endpoint address for the Gateway service to which the client will connect in the form **hostname:port**. Depending on your environment, this can be the address of a specific peer within the user's organization, or an ingress endpoint that dispatches to any available peer in the user's organization. -- `MSP_ID` - member service provider ID for the user's organization. -- `CERTIFICATE` - PEM file containing the user's X.509 certificate. -- `PRIVATE_KEY` - PEM file containing the user's private key. - -The following environment variables are optional and can be set if required by your environment: - -- `CHANNEL_NAME` - Channel to which the chaincode is deployed. (Default: `mychannel`) -- `CHAINCODE_NAME` - Channel to which the chaincode is deployed. (Default: `asset-transfer`) -- `TLS_CERT` - PEM file containing the CA certificate used to authenticate the TLS connection to the Gateway peer. *Only required if using a TLS connection and a private CA.* -- `HOST_ALIAS` - the name of the Gateway peer as it appears in its TLS certificate. *Only required if the endpoint address used by the client does not match the address in the Gateway peer's TLS certificate.* - -- `WEBHOOK_URL` - the [#discord webhook](https://discord.com/developers/docs/resources/webhook) to which the channel - events will be relayed. - - -# Run - -The sample application is run as a command-line application, and is lauched using `npm start [ ...]`. The following commands are available: - -- `npm start create ` to create a new asset. -- `npm start delete ` to delete an existing asset. -- `npm start getAllAssets` to list all assets. -- `npm start read ` to view an existing asset. -- `npm start transfer ` to transfer an asset to a new owner within an organization MSP ID. -- `npm start discord` starts an event loop, relaying channel events to `${WEBHOOK_URL}` - - -## Sample Interaction: - -- Submit some transactions to a ledger: -```shell -npm start create blockbert SeanB orange - -npm start create count-blockula jkneubuhl Org1MSP purple - -npm start transfer count-blockula davidboswell Org1MSP -``` - -- Run the discord event listener: -```shell -export WEBHOOK_URL="https://discord.com/api/webhooks/123456789/xyzzy-abcdef-12345" - -npm start discord -``` - -![Sample Interaction](images/interaction.png) \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/assets/appleplectic.png b/full-stack-asset-transfer-guide/applications/conga-cards/assets/appleplectic.png deleted file mode 100644 index 7a8da445..00000000 Binary files a/full-stack-asset-transfer-guide/applications/conga-cards/assets/appleplectic.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/assets/bananomatopoeia.png b/full-stack-asset-transfer-guide/applications/conga-cards/assets/bananomatopoeia.png deleted file mode 100644 index 40fcba25..00000000 Binary files a/full-stack-asset-transfer-guide/applications/conga-cards/assets/bananomatopoeia.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/assets/block-norris.png b/full-stack-asset-transfer-guide/applications/conga-cards/assets/block-norris.png deleted file mode 100644 index efc2ec84..00000000 Binary files a/full-stack-asset-transfer-guide/applications/conga-cards/assets/block-norris.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/assets/blockbert.png b/full-stack-asset-transfer-guide/applications/conga-cards/assets/blockbert.png deleted file mode 100644 index 43ff9b46..00000000 Binary files a/full-stack-asset-transfer-guide/applications/conga-cards/assets/blockbert.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/assets/count-blockula.png b/full-stack-asset-transfer-guide/applications/conga-cards/assets/count-blockula.png deleted file mode 100644 index e49fb0cc..00000000 Binary files a/full-stack-asset-transfer-guide/applications/conga-cards/assets/count-blockula.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/assets/darth-conga.png b/full-stack-asset-transfer-guide/applications/conga-cards/assets/darth-conga.png deleted file mode 100644 index 7e182204..00000000 Binary files a/full-stack-asset-transfer-guide/applications/conga-cards/assets/darth-conga.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/assets/no-pun-intended.png b/full-stack-asset-transfer-guide/applications/conga-cards/assets/no-pun-intended.png deleted file mode 100644 index 24018022..00000000 Binary files a/full-stack-asset-transfer-guide/applications/conga-cards/assets/no-pun-intended.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/assets/template.png b/full-stack-asset-transfer-guide/applications/conga-cards/assets/template.png deleted file mode 100644 index b04d8126..00000000 Binary files a/full-stack-asset-transfer-guide/applications/conga-cards/assets/template.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/hooks/captain-hook.json b/full-stack-asset-transfer-guide/applications/conga-cards/hooks/captain-hook.json deleted file mode 100644 index ce0a15e0..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/hooks/captain-hook.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "content": "Tail recursion is its own reward.", - "avatar_url": "https://avatars.githubusercontent.com/u/49026922?s=200&v=4", - "username": "Conga-Bot" -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/images/interaction.png b/full-stack-asset-transfer-guide/applications/conga-cards/images/interaction.png deleted file mode 100644 index e7440050..00000000 Binary files a/full-stack-asset-transfer-guide/applications/conga-cards/images/interaction.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/package.json b/full-stack-asset-transfer-guide/applications/conga-cards/package.json deleted file mode 100644 index 8c6d8b2c..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "conga-cards", - "version": "1.0.0", - "description": "Conga Cards client application", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "engines": { - "node": ">=18" - }, - "scripts": { - "build": "tsc", - "build:watch": "tsc -w", - "lint": "eslint ./src", - "prepare": "npm run build", - "pretest": "npm run lint", - "start": "node ./dist/app", - "test": "" - }, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "@grpc/grpc-js": "^1.12.2", - "@hyperledger/fabric-gateway": "^1.7.0", - "axios": "^1.7.7", - "source-map-support": "^0.5.21" - }, - "devDependencies": { - "@tsconfig/node18": "^18.2.2", - "@types/node": "^18.18.6", - "@types/source-map-support": "^0.5.6", - "@typescript-eslint/eslint-plugin": "^6.9.0", - "@typescript-eslint/parser": "^6.9.0", - "eslint": "^8.52.0", - "typescript": "~5.2.2" - } -} diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/app.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/app.ts deleted file mode 100644 index acbdf3a9..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/app.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as sourceMapSupport from 'source-map-support'; -sourceMapSupport.install(); - -import { Command, commands } from './commands'; -import { newGatewayConnection, newGrpcConnection } from './connect'; -import { ExpectedError } from './expectedError'; - -async function main(): Promise { - const commandName = process.argv[2]; - const args = process.argv.slice(3); - - const command = commands[commandName]; - if (!command) { - printUsage(); - throw new Error(`Unknown command: ${commandName}`); - } - - await runCommand(command, args); -} - -async function runCommand(command: Command, args: string[]): Promise { - const client = await newGrpcConnection(); - try { - const gateway = await newGatewayConnection(client); - try { - await command(gateway, args); - } finally { - gateway.close(); - } - } finally { - client.close(); - } -} - -function printUsage(): void { - console.log('Arguments: [ ...]'); - console.log('Available commands:'); - console.log(`\t${Object.keys(commands).sort().join('\n\t')}`); -} - -main().catch(error => { - if (error instanceof ExpectedError) { - console.log(error); - } else { - console.error('\nUnexpected application error:', error); - process.exitCode = 1; - } -}); diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/create.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/create.ts deleted file mode 100644 index 3d823351..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/create.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { AssetTransfer } from '../contract'; -import { assertAllDefined } from '../utils'; - -export default async function main(gateway: Gateway, args: string[]): Promise { - const [assetId, owner, color] = assertAllDefined([args[0], args[1], args[2]], 'Arguments: '); - - const network = gateway.getNetwork(CHANNEL_NAME); - const contract = network.getContract(CHAINCODE_NAME); - - const smartContract = new AssetTransfer(contract); - await smartContract.createAsset({ - ID: assetId, - Owner: owner, - Color: color, - Size: 1, - AppraisedValue: 1, - }); -} diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/delete.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/delete.ts deleted file mode 100644 index 1026a006..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/delete.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { AssetTransfer } from '../contract'; -import { assertDefined } from '../utils'; - -export default async function main(gateway: Gateway, args: string[]): Promise { - const assetId = assertDefined(args[0], 'Arguments: '); - - const network = gateway.getNetwork(CHANNEL_NAME); - const contract = network.getContract(CHAINCODE_NAME); - - const smartContract = new AssetTransfer(contract); - await smartContract.deleteAsset(assetId); -} diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/discord.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/discord.ts deleted file mode 100644 index 6e06688f..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/discord.ts +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ -import { ChaincodeEvent, checkpointers, Gateway } from '@hyperledger/fabric-gateway'; -import * as path from 'path'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { Asset } from '../contract'; -import { assertDefined } from '../utils'; -import { TextDecoder } from 'util'; - -const axios = require('axios'); -const utf8Decoder = new TextDecoder(); - -const checkpointFile = path.resolve(process.env.CHECKPOINT_FILE ?? 'checkpoint.json'); - -const startBlock = BigInt(0); - -// Webhook / bot display names for create -const createUsername = 'King Conga'; -const createAvatar = 'https://avatars.githubusercontent.com/u/49026922?s=200&v=4'; - -const transferUsername = createUsername; -const transferAvatar = createAvatar; - -const deleteUsername = createUsername; -const deleteAvatar = createAvatar; - -export default async function main(gateway: Gateway): Promise { - const webhookURL = assertDefined(process.env['WEBHOOK_URL'], () => { return 'WEBHOOK_URL is not defined in the env' }); - const network = gateway.getNetwork(CHANNEL_NAME); - const checkpointer = await checkpointers.file(checkpointFile); - - console.log(`Connecting to #discord webhook ${webhookURL}`); - console.log(`Starting event discording from block ${checkpointer.getBlockNumber() ?? startBlock}`); - console.log('Last processed transaction ID within block:', checkpointer.getTransactionId()); - - const events = await network.getChaincodeEvents(CHAINCODE_NAME, { - checkpoint: checkpointer, - startBlock, // Used only if there is no checkpoint block number - }); - - try { - for await (const event of events) { - await discord(webhookURL, event); - - await checkpointer.checkpointChaincodeEvent(event) - - // Slow down the event iterator to avoid rate limitations imposed by discord. - // This could be improved to catch the "try again" error from discord and resubmit the event before - // checkpointing the iterator. - await new Promise(resolve => setTimeout(resolve, 1000)); - } - } finally { - events.close(); - } -} - -// Relay a quick message to the discord webhook to indicate the transaction has been processed. -async function discord(webhookURL: string, event: ChaincodeEvent): Promise { - - const asset = parseJson(event.payload); - console.log(`\n<-- Chaincode event received: ${event.eventName}: `, asset); - - // const message = boringLogMessage(event, asset); - const message = splashyShoutMessage(event, asset); - - deliverMessage(webhookURL, message); -} - -// Send an event to a discord webhook. -async function deliverMessage(webhookURL: string, message: any): Promise { - console.log('--> Sending to discord webhook: ' + webhookURL); - console.log(JSON.stringify(message)); - - try { - await axios.post(webhookURL, message); - - } catch (error) { - console.log(error); - } -} - -function boringLogMessage(event: ChaincodeEvent, asset: Asset): any { - const owner = ownerNickname(asset); - const text = format(event, asset, owner); - - return { - username: 'Ledger Troll', - // avatar_url: avatarURL, - content: text, - } -} - -function splashyShoutMessage(event: ChaincodeEvent, asset: Asset): any { - - const owner:any = JSON.parse(asset.Owner); - - if (event.eventName == 'CreateAsset') { - return { - username: createUsername, - avatar_url: createAvatar, - content: `${bold(owner.user)} has caught a wild ${bold(asset.ID)}!` + getRandomEmoji(), - embeds: [ - { - title: `${owner.org}`, - image: { - // an actual conga comic (sometimes png and sometimes jpg) - // url: `https://congacomic.github.io/assets/img/blockheight-${offset}.png` - url: `https://github.com/hyperledgendary/full-stack-asset-transfer-guide/blob/main/applications/conga-cards/assets/${asset.ID}.png?raw=true` - } - } - ], - }; - } - - if (event.eventName == 'TransferAsset') { - return { - username: transferUsername, - avatar_url: transferAvatar, - content: `${bold(owner.user)} is now the owner of ${bold(asset.ID)}: ✈️ ${snippet(JSON.stringify(asset, null, 2))}`, - }; - } - - if (event.eventName == 'DeletaAsset') { - return { - username: deleteUsername, - avatar_url: deleteAvatar, - content: `${bold(asset.ID)} ran away from ${bold(owner.user)}! 😮`, - }; - } - - return {}; -} - -function format(event: ChaincodeEvent, asset: Asset, owner: string): string { - return `${quote(event.transactionId)} ${italic(event.eventName)}(${bold(asset.ID)}, ${owner})`; -} - -function parseJson(jsonBytes: Uint8Array): Asset { - const json = utf8Decoder.decode(jsonBytes); - return JSON.parse(json); -} - -function quote(s: string): string { - return `\`${s}\`` -} - -function italic(s: string): string { - return `_${s}_`; -} - -function bold(s: string) { - return `**${s}**`; -} - -function snippet(s: string) { - return "```" + s + "```"; -} - -function ownerNickname(asset: Asset): string { - const owner:any = JSON.parse(asset.Owner); - - return `${owner.org}, ${owner.user}`; -} - -// https://github.com/discord/discord-example-app/blob/main/utils.js#L43 -// Simple method that returns a random emoji from list -function getRandomEmoji(): string { - const emojiList = ['😭','😄','😌','🤓','😎','😤','🤖','😶‍🌫', '🌏','📸','💿','👋','🌊','✨']; - return emojiList[Math.floor(Math.random() * emojiList.length)]; -} - - diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/getAllAssets.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/getAllAssets.ts deleted file mode 100644 index 9b095dc4..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/getAllAssets.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { AssetTransfer } from '../contract'; - -export default async function main(gateway: Gateway): Promise { - const network = gateway.getNetwork(CHANNEL_NAME); - const contract = network.getContract(CHAINCODE_NAME); - - const smartContract = new AssetTransfer(contract); - const assets = await smartContract.getAllAssets(); - - const assetsJson = JSON.stringify(assets, undefined, 2); - assetsJson.split('\n').forEach(line => console.log(line)); // Write line-by-line to avoid truncation -} diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/index.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/index.ts deleted file mode 100644 index aee38680..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import create from './create'; -import deleteCommand from './delete'; -import discord from './discord'; -import getAllAssets from './getAllAssets'; -import read from './read'; -import transfer from './transfer'; - -export type Command = (gateway: Gateway, args: string[]) => Promise; - -export const commands: Record = { - create, - delete: deleteCommand, - discord, - getAllAssets, - read, - transfer, -}; diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/read.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/read.ts deleted file mode 100644 index a101fb07..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/read.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { AssetTransfer } from '../contract'; -import { assertDefined } from '../utils'; - -export default async function main(gateway: Gateway, args: string[]): Promise { - const assetId = assertDefined(args[0], 'Arguments: '); - - const network = gateway.getNetwork(CHANNEL_NAME); - const contract = network.getContract(CHAINCODE_NAME); - - const smartContract = new AssetTransfer(contract); - const asset = await smartContract.readAsset(assetId); - - const assetsJson = JSON.stringify(asset, undefined, 2); - console.log(assetsJson); -} diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/transfer.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/transfer.ts deleted file mode 100644 index bdfd532e..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/commands/transfer.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { AssetTransfer } from '../contract'; -import { assertAllDefined } from '../utils'; - -export default async function main(gateway: Gateway, args: string[]): Promise { - const [assetId, newOwner, newOwnerOrg] = assertAllDefined([args[0], args[1], args[2]], 'Arguments: '); - - const network = gateway.getNetwork(CHANNEL_NAME); - const contract = network.getContract(CHAINCODE_NAME); - - const smartContract = new AssetTransfer(contract); - await smartContract.transferAsset(assetId, newOwner, newOwnerOrg); -} diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/config.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/config.ts deleted file mode 100644 index e6b45f7f..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/config.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { resolve } from 'path'; -import { assertDefined } from './utils'; - -export const GATEWAY_ENDPOINT = assertEnv('ENDPOINT'); -export const MSP_ID = assertEnv('MSP_ID'); -export const CLIENT_CERT_PATH = resolve(assertEnv('CERTIFICATE')); -export const PRIVATE_KEY_PATH = resolve(assertEnv('PRIVATE_KEY')); -export const TLS_CERT_PATH = resolvePathIfPresent(process.env.TLS_CERT); -export const CHANNEL_NAME = process.env.CHANNEL_NAME ?? 'mychannel'; -export const CHAINCODE_NAME = process.env.CHAINCODE_NAME ?? 'asset-transfer'; - -// Gateway peer SSL host name override. -export const HOST_ALIAS = process.env.HOST_ALIAS; - -function assertEnv(envName: string): string { - return assertDefined(process.env[envName], () => { - console.error('The following environment variables must be set:' + - '\n ENDPOINT - Endpoint address of the gateway service' + - '\n MSP_ID - User\'s organization Member Services Provider ID' + - '\n CERTIFICATE - User\'s certificate file' + - '\n PRIVATE_KEY - User\'s private key file' + - '\n' + - '\nThe following environment variables are optional:' + - '\n CHANNEL_NAME - Channel to which the chaincode is deployed' + - '\n CHAINCODE_NAME - Channel to which the chaincode is deployed' + - '\n TLS_CERT - TLS CA root certificate (only if using TLS and private CA)' + - '\n HOST_ALIAS - TLS hostname override (only if TLS cert does not match endpoint)' + - '\n'); - return `Environment variable ${envName} not set`; - }); -} - -function resolvePathIfPresent(path: string | undefined): string | undefined { - if (path == undefined) { - return undefined; - } - - return resolve(path); -} diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/connect.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/connect.ts deleted file mode 100644 index d34147a5..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/connect.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as grpc from '@grpc/grpc-js'; -import { connect, Gateway, hash, Identity, Signer, signers } from '@hyperledger/fabric-gateway'; -import * as crypto from 'crypto'; -import * as fs from 'fs'; -import * as path from 'path'; -import { CLIENT_CERT_PATH, GATEWAY_ENDPOINT, HOST_ALIAS, MSP_ID, PRIVATE_KEY_PATH, TLS_CERT_PATH } from './config'; - -export async function newGrpcConnection(): Promise { - if (TLS_CERT_PATH) { - const tlsRootCert = await fs.promises.readFile(TLS_CERT_PATH); - const tlsCredentials = grpc.credentials.createSsl(tlsRootCert); - return new grpc.Client(GATEWAY_ENDPOINT, tlsCredentials, newGrpcClientOptions()); - } - - return new grpc.Client(GATEWAY_ENDPOINT, grpc.ChannelCredentials.createInsecure()); -} - -function newGrpcClientOptions(): grpc.ClientOptions { - const result: grpc.ClientOptions = {}; - if (HOST_ALIAS) { - result['grpc.ssl_target_name_override'] = HOST_ALIAS; // Only required if server TLS cert does not match the endpoint address we use - } - return result; -} - -export async function newGatewayConnection(client: grpc.Client): Promise { - return connect({ - client, - identity: await newIdentity(), - signer: await newSigner(), - hash: hash.sha256, - // Default timeouts for different gRPC calls - evaluateOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - endorseOptions: () => { - return { deadline: Date.now() + 15000 }; // 15 seconds - }, - submitOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - commitStatusOptions: () => { - return { deadline: Date.now() + 60000 }; // 1 minute - }, - }); -} - -async function newIdentity(): Promise { - const certPath = path.resolve(CLIENT_CERT_PATH); - const credentials = await fs.promises.readFile(certPath); - - return { mspId: MSP_ID, credentials }; -} - -async function newSigner(): Promise { - const keyPath = path.resolve(PRIVATE_KEY_PATH); - const privateKeyPem = await fs.promises.readFile(keyPath); - const privateKey = crypto.createPrivateKey(privateKeyPem); - - return signers.newPrivateKeySigner(privateKey); -} diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/contract.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/contract.ts deleted file mode 100644 index 3dcb92b3..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/contract.ts +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { CommitError, Contract, StatusCode } from '@hyperledger/fabric-gateway'; -import { TextDecoder } from 'util'; - -const RETRIES = 2; - -const utf8Decoder = new TextDecoder(); - -export interface Asset { - ID: string; - Color: string; - Size: number; - Owner: string; - AppraisedValue: number; -} - -export type AssetCreate = Omit & Partial; -export type AssetUpdate = Pick & Partial>; - -/** - * AssetTransfer presents the smart contract in a form appropriate to the business application. Internally it uses the - * Fabric Gateway client API to invoke transaction functions, and deals with the translation between the business - * application and API representation of parameters and return values. - */ -export class AssetTransfer { - readonly #contract: Contract; - - constructor(contract: Contract) { - this.#contract = contract; - } - - async createAsset(asset: AssetCreate): Promise { - await this.#contract.submit('CreateAsset', { - arguments: [JSON.stringify(asset)], - }); - } - - async getAllAssets(): Promise { - const result = await this.#contract.evaluate('GetAllAssets'); - if (result.length === 0) { - return []; - } - - return JSON.parse(utf8Decoder.decode(result)) as Asset[]; - } - - async readAsset(id: string): Promise { - const result = await this.#contract.evaluate('ReadAsset', { - arguments: [id], - }); - return JSON.parse(utf8Decoder.decode(result)) as Asset; - } - - async updateAsset(asset: AssetUpdate): Promise { - await submitWithRetry(() => this.#contract.submit('UpdateAsset', { - arguments: [JSON.stringify(asset)], - })); - } - - async deleteAsset(id: string): Promise { - await submitWithRetry(() => this.#contract.submit('DeleteAsset', { - arguments: [id], - })); - } - - async assetExists(id: string): Promise { - const result = await this.#contract.evaluate('AssetExists', { - arguments: [id], - }); - return utf8Decoder.decode(result).toLowerCase() === 'true'; - } - - async transferAsset(id: string, newOwner: string, newOwnerOrg: string): Promise { - await submitWithRetry(() => this.#contract.submit('TransferAsset', { - arguments: [id, newOwner, newOwnerOrg], - })); - } -} - -async function submitWithRetry(submit: () => Promise): Promise { - let lastError: unknown | undefined; - - for (let retryCount = 0; retryCount < RETRIES; retryCount++) { - try { - return await submit(); - } catch (err: unknown) { - lastError = err; - if (err instanceof CommitError) { - // Transaction failed validation and did not update the ledger. Handle specific transaction validation codes. - if (err.code === StatusCode.MVCC_READ_CONFLICT) { - continue; // Retry - } - } - break; // Failure -- don't retry - } - } - - throw lastError; -} diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/expectedError.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/expectedError.ts deleted file mode 100644 index 3b1466b4..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/expectedError.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ - -export class ExpectedError extends Error { - constructor(message?: string) { - super(message); - this.name = ExpectedError.name; - } -} diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/src/utils.ts b/full-stack-asset-transfer-guide/applications/conga-cards/src/utils.ts deleted file mode 100644 index e9b1e594..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/src/utils.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright contributors to the Hyperledgendary Full Stack Asset Transfer Guide project - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { inspect, TextDecoder } from 'util'; - -const utf8Decoder = new TextDecoder(); - -/** - * Pick a random element from an array. - * @param values Candidate elements. - */ -export function randomElement(values: T[]): T { - return values[randomInt(values.length)]; -} - -/** - * Generate a random integer in the range 0 to max - 1. - * @param max Maximum value (exclusive). - */ -export function randomInt(max: number): number { - return Math.floor(Math.random() * max); -} - -/** - * Pick a random element from an array, excluding the current value. - * @param values Candidate elements. - * @param currentValue Value to avoid. - */ -export function differentElement(values: T[], currentValue: T): T { - const candidateValues = values.filter(value => value !== currentValue); - return randomElement(candidateValues); -} - -/** - * Wait for all promises to complete, then throw an Error only if any of the promises were rejected. - * @param promises Promises to be awaited. - */ -export async function allFulfilled(promises: Promise[]): Promise { - const results = await Promise.allSettled(promises); - const failures = results - .map(result => result.status === 'rejected' && result.reason as unknown) - .filter(reason => !!reason) - .map(reason => inspect(reason)); - - if (failures.length > 0) { - const failMessages = '- ' + failures.join('\n- '); - throw new Error(`${failures.length} failures:\n${failMessages}\n`); - } -} - -export type PrintView = { - [K in keyof T]: T[K] extends Uint8Array ? string : T[K]; -}; - -export function printable(event: T): PrintView { - return Object.fromEntries( - Object.entries(event).map(([k, v]) => [k, v instanceof Uint8Array ? utf8Decoder.decode(v) : v]) - ) as PrintView; -} - -export function assertAllDefined(values: (T | undefined)[], message: string | (() => string)): T[] { - values.forEach(value => assertDefined(value, message)); - return values as T[]; -} - -export function assertDefined(value: T | undefined, message: string | (() => string)): T { - if (value == undefined) { - throw new Error(typeof message === 'string' ? message : message()); - } - - return value; -} diff --git a/full-stack-asset-transfer-guide/applications/conga-cards/tsconfig.json b/full-stack-asset-transfer-guide/applications/conga-cards/tsconfig.json deleted file mode 100644 index 891d7c74..00000000 --- a/full-stack-asset-transfer-guide/applications/conga-cards/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@tsconfig/node18/tsconfig.json", - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "outDir": "dist", - "rootDir": "src", - "noUnusedLocals": false, - "noImplicitReturns": true - }, - "include": [ - "src/" - ], - "exclude": [ - "src/**/*.spec.ts" - ] -} diff --git a/full-stack-asset-transfer-guide/applications/frontend/.browserslistrc b/full-stack-asset-transfer-guide/applications/frontend/.browserslistrc deleted file mode 100644 index 4f9ac269..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/.browserslistrc +++ /dev/null @@ -1,16 +0,0 @@ -# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. -# For additional information regarding the format and rule options, please see: -# https://github.com/browserslist/browserslist#queries - -# For the full list of supported browsers by the Angular framework, please see: -# https://angular.io/guide/browser-support - -# You can see what browsers were selected by your queries by running: -# npx browserslist - -last 1 Chrome version -last 1 Firefox version -last 2 Edge major versions -last 2 Safari major versions -last 2 iOS major versions -Firefox ESR diff --git a/full-stack-asset-transfer-guide/applications/frontend/.editorconfig b/full-stack-asset-transfer-guide/applications/frontend/.editorconfig deleted file mode 100644 index 59d9a3a3..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/.editorconfig +++ /dev/null @@ -1,16 +0,0 @@ -# Editor configuration, see https://editorconfig.org -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 2 -insert_final_newline = true -trim_trailing_whitespace = true - -[*.ts] -quote_type = single - -[*.md] -max_line_length = off -trim_trailing_whitespace = false diff --git a/full-stack-asset-transfer-guide/applications/frontend/.gitignore b/full-stack-asset-transfer-guide/applications/frontend/.gitignore deleted file mode 100644 index 0711527e..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. - -# Compiled output -/dist -/tmp -/out-tsc -/bazel-out - -# Node -/node_modules -npm-debug.log -yarn-error.log - -# IDEs and editors -.idea/ -.project -.classpath -.c9/ -*.launch -.settings/ -*.sublime-workspace - -# Visual Studio Code -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -.history/* - -# Miscellaneous -/.angular/cache -.sass-cache/ -/connect.lock -/coverage -/libpeerconnection.log -testem.log -/typings - -# System files -.DS_Store -Thumbs.db diff --git a/full-stack-asset-transfer-guide/applications/frontend/Dockerfile b/full-stack-asset-transfer-guide/applications/frontend/Dockerfile deleted file mode 100644 index b3d16aab..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -# FROM node:14-alpine3.14 AS build -# WORKDIR /app -# COPY package.json /app -# RUN npm install -# CMD npm run build - -# COPY . /app -# CMD [ "npm","run","prod" ] - -FROM nginx:alpine -COPY /dist/frontend /usr/share/nginx/html \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/frontend/README.md b/full-stack-asset-transfer-guide/applications/frontend/README.md deleted file mode 100644 index 5d96edcf..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/README.md +++ /dev/null @@ -1,18 +0,0 @@ -local build - -npm install -npm start - - -k8s deployment -Step-1 Prodction build -ng build -Step-2 Build docker image & tag -docker build -t localhost:5000/frontend . -Step-3 Push image to local registary -docker push localhost:5000/frontend -Step-4 deploy to k8s -kubectl apply -f deployment.yaml -n test-network - -Step-5 Navigate to frontend using below url -https://frontend.localho.st/ \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/frontend/angular.json b/full-stack-asset-transfer-guide/applications/frontend/angular.json deleted file mode 100644 index 63df0214..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/angular.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", - "version": 1, - "newProjectRoot": "projects", - "projects": { - "frontend": { - "projectType": "application", - "schematics": { - "@schematics/angular:component": { - "style": "scss" - } - }, - "root": "", - "sourceRoot": "src", - "prefix": "app", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "options": { - "outputPath": "dist/frontend", - "index": "src/index.html", - "main": "src/main.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "src/favicon.ico", - "src/assets" - ], - "styles": [ - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", - "src/styles.scss" - ], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.prod.ts" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "browserTarget": "frontend:build:production" - }, - "development": { - "browserTarget": "frontend:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "frontend:build" - } - }, - "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "main": "src/test.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.spec.json", - "karmaConfig": "karma.conf.js", - "inlineStyleLanguage": "scss", - "assets": [ - "src/favicon.ico", - "src/assets" - ], - "styles": [ - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", - "src/styles.scss" - ], - "scripts": [] - } - } - } - } - }, - "cli": { - "analytics": "2231f71d-331b-4f3d-8391-0f5998405c1e" - } -} diff --git a/full-stack-asset-transfer-guide/applications/frontend/karma.conf.js b/full-stack-asset-transfer-guide/applications/frontend/karma.conf.js deleted file mode 100644 index 36356397..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/karma.conf.js +++ /dev/null @@ -1,44 +0,0 @@ -// Karma configuration file, see link for more information -// https://karma-runner.github.io/1.0/config/configuration-file.html - -module.exports = function (config) { - config.set({ - basePath: '', - frameworks: ['jasmine', '@angular-devkit/build-angular'], - plugins: [ - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), - require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') - ], - client: { - jasmine: { - // you can add configuration options for Jasmine here - // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html - // for example, you can disable the random execution with `random: false` - // or set a specific seed with `seed: 4321` - }, - clearContext: false // leave Jasmine Spec Runner output visible in browser - }, - jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces - }, - coverageReporter: { - dir: require('path').join(__dirname, './coverage/frontend'), - subdir: '.', - reporters: [ - { type: 'html' }, - { type: 'text-summary' } - ] - }, - reporters: ['progress', 'kjhtml'], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: true, - browsers: ['Chrome'], - singleRun: false, - restartOnFileChange: true - }); -}; diff --git a/full-stack-asset-transfer-guide/applications/frontend/package.json b/full-stack-asset-transfer-guide/applications/frontend/package.json deleted file mode 100644 index 29120e1f..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "frontend", - "version": "0.0.0", - "scripts": { - "ng": "ng", - "start": "ng serve", - "build": "ng build", - "watch": "ng build --watch --configuration development", - "test": "ng test" - }, - "private": true, - "dependencies": { - "@angular/animations": "^14.1.0", - "@angular/cdk": "^14.2.0", - "@angular/common": "^14.1.0", - "@angular/compiler": "^14.1.0", - "@angular/core": "^14.1.0", - "@angular/forms": "^14.1.0", - "@angular/material": "^14.2.0", - "@angular/platform-browser": "^14.1.0", - "@angular/platform-browser-dynamic": "^14.1.0", - "@angular/router": "^14.1.0", - "rxjs": "~7.5.0", - "tslib": "^2.3.0", - "zone.js": "~0.11.4" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^14.1.1", - "@angular/cli": "~14.1.1", - "@angular/compiler-cli": "^14.1.0", - "@types/jasmine": "~4.0.0", - "jasmine-core": "~4.2.0", - "karma": "~6.4.0", - "karma-chrome-launcher": "~3.1.0", - "karma-coverage": "~2.2.0", - "karma-jasmine": "~5.1.0", - "karma-jasmine-html-reporter": "~2.0.0", - "typescript": "~4.7.2" - } -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/frontend/screenshots/Create.png b/full-stack-asset-transfer-guide/applications/frontend/screenshots/Create.png deleted file mode 100644 index 2603c4c8..00000000 Binary files a/full-stack-asset-transfer-guide/applications/frontend/screenshots/Create.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/applications/frontend/screenshots/list.png b/full-stack-asset-transfer-guide/applications/frontend/screenshots/list.png deleted file mode 100644 index 807721ee..00000000 Binary files a/full-stack-asset-transfer-guide/applications/frontend/screenshots/list.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/app/app-routing.module.ts b/full-stack-asset-transfer-guide/applications/frontend/src/app/app-routing.module.ts deleted file mode 100644 index 02972627..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/app/app-routing.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; - -const routes: Routes = []; - -@NgModule({ - imports: [RouterModule.forRoot(routes)], - exports: [RouterModule] -}) -export class AppRoutingModule { } diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/app/app.component.html b/full-stack-asset-transfer-guide/applications/frontend/src/app/app.component.html deleted file mode 100644 index 252123ea..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/app/app.component.html +++ /dev/null @@ -1,66 +0,0 @@ -

-
-
- Assets - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
No. {{ (i+1) + (paginator.pageIndex * - paginator.pageSize) }} Id {{element.ID}} Color {{element.Color}} Owner {{element.Owner}} Appraised Value {{element.AppraisedValue}} Size {{element.Size}} Trasnfer - arrow_forward - Edit - edit - Delete - delete -
- - -
-
\ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/app/app.component.scss b/full-stack-asset-transfer-guide/applications/frontend/src/app/app.component.scss deleted file mode 100644 index acd75952..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/app/app.component.scss +++ /dev/null @@ -1,6 +0,0 @@ -.layout{ - margin: 40px 10%; -} -.search{ - float: right; -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/app/app.component.spec.ts b/full-stack-asset-transfer-guide/applications/frontend/src/app/app.component.spec.ts deleted file mode 100644 index 74b5b3eb..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/app/app.component.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { AppComponent } from './app.component'; - -describe('AppComponent', () => { - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ - RouterTestingModule - ], - declarations: [ - AppComponent - ], - }).compileComponents(); - }); - - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); - - it(`should have as title 'frontend'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('frontend'); - }); - - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('.content span')?.textContent).toContain('frontend app is running!'); - }); -}); diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/app/app.component.ts b/full-stack-asset-transfer-guide/applications/frontend/src/app/app.component.ts deleted file mode 100644 index c26dc0c1..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/app/app.component.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Component, OnInit, ViewChild } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import { MatSort } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; -import { AssetDialogComponent } from './asset-dialog/asset-dialog.component'; -import { URLS } from './urls'; - -@Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'] -}) -export class AppComponent implements OnInit { - - @ViewChild(MatSort, { static: false }) sort!: MatSort ; - @ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator; - dataSource = new MatTableDataSource(); - httpOptions; - title = 'frontend'; - assets = []; - displayedColumns: String[] = ["position", "id",'owner','color','appraisedValue',"size" ,'transfer','edit','delete']; - constructor(private _http: HttpClient, private dialog: MatDialog,private snackBar:MatSnackBar) { - this.httpOptions = { - headers: new HttpHeaders({ - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*' - - }) - } - this._http.get(URLS.LIST,this.httpOptions).subscribe(data => { - this.dataSource.data = data; - }) - } - ngOnInit() { - - } - editRow(asset:any,index:number){ - const dialogRef = this.dialog.open(AssetDialogComponent, { - width: '500px', height: '100vh',position:{right:'0'},data:asset - - }); - dialogRef.afterClosed().subscribe(result => { - if (result) { - this.dataSource.data[index]=(result) - this.dataSource._updateChangeSubscription(); - } - }); - } - delete(asset:any,index:number){ - this._http.post(URLS.DELETE,JSON.stringify({"id":asset.ID}),this.httpOptions).subscribe((data:any) => { - console.log(data); - this.dataSource.data.splice(index,1) - this.dataSource._updateChangeSubscription(); - this.snackBar.open(asset.ID+ ' deleted', '', {duration:1000 - }); - }) - } - addNewAsset(){ - const dialogRef = this.dialog.open(AssetDialogComponent, { - width: '500px', height: '100vh',position:{right:'0'}, - - }); - dialogRef.afterClosed().subscribe(result => { - if (result) { - this.dataSource.data.push(result) - this.dataSource._updateChangeSubscription(); - } - }); - } - applyFilter(event: Event) { - const filterValue = (event.target as HTMLInputElement).value; - this.dataSource.filter = filterValue.trim().toLowerCase(); - } - ngAfterViewInit() { - console.log('after ininti'); - this.dataSource.sort = this.sort; - this.dataSource.paginator = this.paginator; - } -} diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/app/app.module.ts b/full-stack-asset-transfer-guide/applications/frontend/src/app/app.module.ts deleted file mode 100644 index eb0ad4b7..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/app/app.module.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; - -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; -import { HttpClientModule } from '@angular/common/http'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { MatTableModule } from '@angular/material/table'; -import { MatInputModule } from '@angular/material/input'; -import { MatButtonModule } from '@angular/material/button'; -import { MatPaginatorModule } from '@angular/material/paginator'; -import { AssetDialogComponent } from './asset-dialog/asset-dialog.component'; -import { MatDialogModule } from '@angular/material/dialog'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatSnackBarModule } from '@angular/material/snack-bar'; -import { MatIconModule } from '@angular/material/icon'; -import { MatToolbarModule } from '@angular/material/toolbar'; - -@NgModule({ - declarations: [ - AppComponent, - AssetDialogComponent - ], - imports: [ - BrowserModule, - AppRoutingModule, HttpClientModule, BrowserAnimationsModule, MatTableModule,MatInputModule,MatButtonModule,MatPaginatorModule, - MatDialogModule,FormsModule, ReactiveFormsModule,MatSnackBarModule,MatIconModule,MatToolbarModule - ], - providers: [], - bootstrap: [AppComponent] -}) -export class AppModule { } diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/app/asset-dialog/asset-dialog.component.html b/full-stack-asset-transfer-guide/applications/frontend/src/app/asset-dialog/asset-dialog.component.html deleted file mode 100644 index 87977d9d..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/app/asset-dialog/asset-dialog.component.html +++ /dev/null @@ -1,51 +0,0 @@ - - highlight_off - -
-
Asset create/edit
-
-
-
-
- - Color - - - You must include color -
-
- - Owner - - - You must include owner -
-
- - Size - - - You must include size -
-
- - Appraised Value - - - You must include appraisedValue -
-
- - -
-
- - -
-
-
\ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/app/asset-dialog/asset-dialog.component.scss b/full-stack-asset-transfer-guide/applications/frontend/src/app/asset-dialog/asset-dialog.component.scss deleted file mode 100644 index f0845f1d..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/app/asset-dialog/asset-dialog.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.mat-form-field{ - width: 100% !important; -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/app/asset-dialog/asset-dialog.component.spec.ts b/full-stack-asset-transfer-guide/applications/frontend/src/app/asset-dialog/asset-dialog.component.spec.ts deleted file mode 100644 index 88866e94..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/app/asset-dialog/asset-dialog.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { AssetDialogComponent } from './asset-dialog.component'; - -describe('AssetDialogComponent', () => { - let component: AssetDialogComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ AssetDialogComponent ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(AssetDialogComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/app/asset-dialog/asset-dialog.component.ts b/full-stack-asset-transfer-guide/applications/frontend/src/app/asset-dialog/asset-dialog.component.ts deleted file mode 100644 index 1480bcc8..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/app/asset-dialog/asset-dialog.component.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Component, Inject, OnInit } from '@angular/core'; -import { FormGroup, FormControl } from '@angular/forms'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; -import { Data } from '@angular/router'; -import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { URLS } from '../urls'; - -@Component({ - selector: 'app-asset-dialog', - templateUrl: './asset-dialog.component.html', - styleUrls: ['./asset-dialog.component.scss'] -}) -export class AssetDialogComponent implements OnInit { - stores = []; - isEdit: Boolean = false; - aseet= { "Color": "", "AppraisedValue": "", "ID": "", "Size": "", "Owner": "" }; - buttonText = "Save"; - form = new FormGroup({ - Color: new FormControl(''), - AppraisedValue: new FormControl(''), - Owner: new FormControl(''), - Size: new FormControl('') - }); - httpOptions: any; - data:any; - constructor(public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public dialogdata: Data, private snackBar: MatSnackBar, private _http: HttpClient) { - console.log(dialogdata); - this.data=dialogdata; - if (dialogdata) { - var data = dialogdata; - this.aseet.AppraisedValue = data['AppraisedValue']; - this.aseet.Color = data['Color']; - this.aseet.Size = data['Size']; - this.aseet.ID = data['Id']; - var owner = JSON.parse(data['Owner']) - this.aseet.Owner = owner.user; - } - - } - ngOnInit() { - - } - - onSubmit() { - console.log(this.form.value); - this.httpOptions = { - headers: new HttpHeaders({ - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*' - - }) - } - if (this.data) { - var request = { "Color": this.form.value.Color, "AppraisedValue": this.form.value.AppraisedValue, "ID": this.data.ID, "Size": this.form.value.Size, "Owner": { "org": "Org1MSP", "user": this.form.value.Owner } }; - this._http.post(URLS.UPDATE, JSON.stringify(request), this.httpOptions).subscribe((data: any) => { - console.log(data); - var response = { "Color": this.form.value.Color, "AppraisedValue": this.form.value.AppraisedValue, "ID": this.data.ID, "Size": this.form.value.Size, "Owner": JSON.stringify({ "org": "Org1MSP", "user": this.form.value.Owner }) }; - this.dialogRef.close(response) - }) - }else{ - this._http.post(URLS.CREATE, JSON.stringify(this.form.value), this.httpOptions).subscribe((data: any) => { - console.log(data); - var response = { "Color": this.form.value.Color, "AppraisedValue": this.form.value.AppraisedValue, "ID": data.AssetId, "Size": this.form.value.Size, "Owner": JSON.stringify({ "org": "Org1MSP", "user": this.form.value.Owner }) }; - this.dialogRef.close(response) - }) - } - - } - close() { - this.dialogRef.close(); - } -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/app/urls.ts b/full-stack-asset-transfer-guide/applications/frontend/src/app/urls.ts deleted file mode 100644 index 5e553a3f..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/app/urls.ts +++ /dev/null @@ -1,8 +0,0 @@ -export class URLS { - // private static IP = "http://localhost:8080/"; - private static IP = "https://restapi.localho.st/"; - public static LIST = URLS.IP + "list"; - public static CREATE = URLS.IP + "create"; - public static UPDATE = URLS.IP + "update"; - public static DELETE = URLS.IP + "delete"; -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/assets/.gitkeep b/full-stack-asset-transfer-guide/applications/frontend/src/assets/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/environments/environment.prod.ts b/full-stack-asset-transfer-guide/applications/frontend/src/environments/environment.prod.ts deleted file mode 100644 index 3612073b..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/environments/environment.prod.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const environment = { - production: true -}; diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/environments/environment.ts b/full-stack-asset-transfer-guide/applications/frontend/src/environments/environment.ts deleted file mode 100644 index f56ff470..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/environments/environment.ts +++ /dev/null @@ -1,16 +0,0 @@ -// This file can be replaced during build by using the `fileReplacements` array. -// `ng build` replaces `environment.ts` with `environment.prod.ts`. -// The list of file replacements can be found in `angular.json`. - -export const environment = { - production: false -}; - -/* - * For easier debugging in development mode, you can import the following file - * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. - * - * This import should be commented out in production mode because it will have a negative impact - * on performance if an error is thrown. - */ -// import 'zone.js/plugins/zone-error'; // Included with Angular CLI. diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/favicon.ico b/full-stack-asset-transfer-guide/applications/frontend/src/favicon.ico deleted file mode 100644 index 997406ad..00000000 Binary files a/full-stack-asset-transfer-guide/applications/frontend/src/favicon.ico and /dev/null differ diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/index.html b/full-stack-asset-transfer-guide/applications/frontend/src/index.html deleted file mode 100644 index 41bf45ce..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - Frontend - - - - - - - - - - - - - - diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/main.ts b/full-stack-asset-transfer-guide/applications/frontend/src/main.ts deleted file mode 100644 index c7b673cf..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/main.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; - -import { AppModule } from './app/app.module'; -import { environment } from './environments/environment'; - -if (environment.production) { - enableProdMode(); -} - -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.error(err)); diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/polyfills.ts b/full-stack-asset-transfer-guide/applications/frontend/src/polyfills.ts deleted file mode 100644 index 429bb9ef..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/polyfills.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes recent versions of Safari, Chrome (including - * Opera), Edge on the desktop, and iOS and Chrome on mobile. - * - * Learn more in https://angular.io/guide/browser-support - */ - -/*************************************************************************************************** - * BROWSER POLYFILLS - */ - -/** - * By default, zone.js will patch all possible macroTask and DomEvents - * user can disable parts of macroTask/DomEvents patch by setting following flags - * because those flags need to be set before `zone.js` being loaded, and webpack - * will put import in the top of bundle, so user need to create a separate file - * in this directory (for example: zone-flags.ts), and put the following flags - * into that file, and then add the following code before importing zone.js. - * import './zone-flags'; - * - * The flags allowed in zone-flags.ts are listed here. - * - * The following flags will work for all browsers. - * - * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - * - * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js - * with the following flag, it will bypass `zone.js` patch for IE/Edge - * - * (window as any).__Zone_enable_cross_context_check = true; - * - */ - -/*************************************************************************************************** - * Zone JS is required by default for Angular itself. - */ -import 'zone.js'; // Included with Angular CLI. - - -/*************************************************************************************************** - * APPLICATION IMPORTS - */ diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/styles.scss b/full-stack-asset-transfer-guide/applications/frontend/src/styles.scss deleted file mode 100644 index 7e7239a2..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/styles.scss +++ /dev/null @@ -1,4 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ - -html, body { height: 100%; } -body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } diff --git a/full-stack-asset-transfer-guide/applications/frontend/src/test.ts b/full-stack-asset-transfer-guide/applications/frontend/src/test.ts deleted file mode 100644 index c04c8760..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/src/test.ts +++ /dev/null @@ -1,26 +0,0 @@ -// This file is required by karma.conf.js and loads recursively all the .spec and framework files - -import 'zone.js/testing'; -import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; - -declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { - (id: string): T; - keys(): string[]; - }; -}; - -// First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting(), -); - -// Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); -// And load the modules. -context.keys().forEach(context); diff --git a/full-stack-asset-transfer-guide/applications/frontend/tsconfig.app.json b/full-stack-asset-transfer-guide/applications/frontend/tsconfig.app.json deleted file mode 100644 index 82d91dc4..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/tsconfig.app.json +++ /dev/null @@ -1,15 +0,0 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./out-tsc/app", - "types": [] - }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] -} diff --git a/full-stack-asset-transfer-guide/applications/frontend/tsconfig.json b/full-stack-asset-transfer-guide/applications/frontend/tsconfig.json deleted file mode 100644 index ff06eae1..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ -{ - "compileOnSave": false, - "compilerOptions": { - "baseUrl": "./", - "outDir": "./dist/out-tsc", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "sourceMap": true, - "declaration": false, - "downlevelIteration": true, - "experimentalDecorators": true, - "moduleResolution": "node", - "importHelpers": true, - "target": "es2020", - "module": "es2020", - "lib": [ - "es2020", - "dom" - ] - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/full-stack-asset-transfer-guide/applications/frontend/tsconfig.spec.json b/full-stack-asset-transfer-guide/applications/frontend/tsconfig.spec.json deleted file mode 100644 index 092345b0..00000000 --- a/full-stack-asset-transfer-guide/applications/frontend/tsconfig.spec.json +++ /dev/null @@ -1,18 +0,0 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./out-tsc/spec", - "types": [ - "jasmine" - ] - }, - "files": [ - "src/test.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/full-stack-asset-transfer-guide/applications/ping-chaincode/.gitignore b/full-stack-asset-transfer-guide/applications/ping-chaincode/.gitignore deleted file mode 100644 index 76add878..00000000 --- a/full-stack-asset-transfer-guide/applications/ping-chaincode/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -dist \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/ping-chaincode/app.env b/full-stack-asset-transfer-guide/applications/ping-chaincode/app.env deleted file mode 100644 index 0bbde31a..00000000 --- a/full-stack-asset-transfer-guide/applications/ping-chaincode/app.env +++ /dev/null @@ -1,7 +0,0 @@ -CHANNEL_NAME=mychannel -CHAINCODE_NAME=asset-transfer -CONN_PROFILE_FILE=/home/matthew/github.com/hyperledgendary/full-stack-asset-transfer-guide/_cfg/Org1_gateway.json -ID_FILE=asset-transfer_appid.json -ID_DIR=/home/matthew/github.com/hyperledgendary/full-stack-asset-transfer-guide/_cfg/ -TLS_ENABLED=true -MSPID=Org1MSP diff --git a/full-stack-asset-transfer-guide/applications/ping-chaincode/package.json b/full-stack-asset-transfer-guide/applications/ping-chaincode/package.json deleted file mode 100644 index a9ee2571..00000000 --- a/full-stack-asset-transfer-guide/applications/ping-chaincode/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "asset-transfer-basic", - "version": "1.0.0", - "description": "Asset Transfer Basic Application implemented in typeScript using fabric-gateway", - "main": "dist/app.js", - "engines": { - "node": ">=18" - }, - "scripts": { - "build": "tsc", - "build:watch": "tsc -w", - "lint": "eslint . --ext .ts", - "prepare": "npm run build", - "pretest": "npm run lint", - "start": "node dist/app.js" - }, - "engineStrict": true, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "@grpc/grpc-js": "^1.12.2", - "@hyperledger/fabric-gateway": "^1.7.0", - "dotenv": "^16.4.5", - "env-var": "^7.5.0", - "js-yaml": "^4.1.0" - }, - "devDependencies": { - "@tsconfig/node18": "^18.2.2", - "@types/js-yaml": "^4.0.5", - "@types/node": "^18.18.6", - "@typescript-eslint/eslint-plugin": "^6.9.0", - "@typescript-eslint/parser": "^6.9.0", - "eslint": "^8.52.0", - "typescript": "~5.2.2" - } -} diff --git a/full-stack-asset-transfer-guide/applications/ping-chaincode/src/app.ts b/full-stack-asset-transfer-guide/applications/ping-chaincode/src/app.ts deleted file mode 100644 index 2c8916fe..00000000 --- a/full-stack-asset-transfer-guide/applications/ping-chaincode/src/app.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { connect, Contract, hash } from '@hyperledger/fabric-gateway'; -import * as path from 'path'; -import { TextDecoder } from 'util'; -import { ConnectionHelper } from './fabric-connection-profile'; -import JSONIDAdapter from './jsonid-adapter'; - -import { dump } from 'js-yaml'; - -import { config } from 'dotenv'; -import * as env from 'env-var'; -config({path:'app.env'}); - -const channelName = env.get('CHANNEL_NAME').default('mychannel').asString(); -const chaincodeName = env.get('CHAINCODE_NAME').default('conga-nft-contract').asString(); - -const connectionProfile = env.get('CONN_PROFILE_FILE').required().asString(); -const identityFile = env.get('ID_FILE').required().asString() -const identityDir = env.get('ID_DIR').required().asString() -const mspID = env.get('MSPID').required().asString() -const tls = env.get('TLS_ENABLED').default("false").asBool(); - -const utf8Decoder = new TextDecoder(); - - -async function main(): Promise { - - const cp = await ConnectionHelper.loadProfile(connectionProfile); - - - // The gRPC client connection should be shared by all Gateway connections to this endpoint. - const client = await ConnectionHelper.newGrpcConnection(cp,tls); - console.log("Created GRPC Connection") - - const jsonAdapter: JSONIDAdapter = new JSONIDAdapter(path.resolve(identityDir),mspID); - const identity = await jsonAdapter.getIdentity(identityFile); - const signer = await jsonAdapter.getSigner(identityFile); - - console.log("Loaded Identity") - const gateway = connect({ - client, - identity, - signer, - hash: hash.sha256, - // Default timeouts for different gRPC calls - evaluateOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - endorseOptions: () => { - return { deadline: Date.now() + 15000 }; // 15 seconds - }, - submitOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - commitStatusOptions: () => { - return { deadline: Date.now() + 60000 }; // 1 minute - }, - }); - - try { - // Get a network instance representing the channel where the smart contract is deployed. - const network = gateway.getNetwork(channelName); - - // Get the smart contract from the network. - const contract = network.getContract(chaincodeName); - - // Return all the current assets on the ledger. - await ping(contract); - - } finally { - gateway.close(); - client.close(); - } -} - -main().catch(error => { - console.error('******** FAILED to run the application:', error); - process.exitCode = 1; -}); - -/** - * Evaluate a transaction to query ledger state. - */ -async function ping(contract: Contract): Promise { - console.log('\n--> Evaluate Transaction: Get Contract Metdata from : org.hyperledger.fabric:GetMetadata'); - - const resultBytes = await contract.evaluateTransaction('org.hyperledger.fabric:GetMetadata'); - - const resultJson = utf8Decoder.decode(resultBytes); - const result = JSON.parse(resultJson); - console.log('*** Result:'); - console.log(dump(result)); -} diff --git a/full-stack-asset-transfer-guide/applications/ping-chaincode/src/fabric-connection-profile.ts b/full-stack-asset-transfer-guide/applications/ping-chaincode/src/fabric-connection-profile.ts deleted file mode 100644 index cd4f9364..00000000 --- a/full-stack-asset-transfer-guide/applications/ping-chaincode/src/fabric-connection-profile.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as fs from 'fs'; -import * as path from 'path'; - -import * as grpc from '@grpc/grpc-js'; -import yaml from 'js-yaml'; - -const JSON_EXT = /json/gi; -const YAML_EXT = /ya?ml/gi; - -export interface ConnectionProfile { - display_name: string; - id: string; - name: string; - type: string; - version: string; - // - certificateAuthorities: any; - client: any; - oprganizations: any; - peers: { [key: string]: Peer }; -} - -export interface Peer { - grpcOptions: grpcOptions; - url: string; - tlsCACerts: any -} - -export interface grpcOptions { - 'ssl-Target-Name-Override'?: string; - hostnameOverride?: string; - 'grpc.ssl_target_name_override'?: string; - 'grpc.default_authority'?: string; -} - -export class ConnectionHelper { - /** - * Loads the profile at the given filename. - * - * File can either by yaml or json, error is thrown is the file does - * not exist at the location given. - * - * @param profilename filename of the gateway connection profile - * @return Gateway profile as an object - */ - static loadProfile(profilename: string): ConnectionProfile { - const ccpPath = path.resolve(profilename); - if (!fs.existsSync(ccpPath)) { - throw new Error(`Profile file ${ccpPath} does not exist`); - } - - const type = path.extname(ccpPath); - - if (JSON_EXT.exec(type)) { - return JSON.parse(fs.readFileSync(ccpPath, 'utf8')); - } else if (YAML_EXT.exec(type)) { - return yaml.load(fs.readFileSync(ccpPath, 'utf8')) as ConnectionProfile; - } else { - throw new Error(`Extension of ${ccpPath} not recognised`); - } - } - - - static async newGrpcConnection(cp: ConnectionProfile, tls: boolean): Promise { - const peerEndpointURL = new URL(cp.peers[Object.keys(cp.peers)[0]].url); - const peerEndpoint = `${peerEndpointURL.hostname}:${peerEndpointURL.port}`; - - if (tls){ - const tlsRootCert = cp.peers[Object.keys(cp.peers)[0]].tlsCACerts.pem; - const tlsCredentials = grpc.credentials.createSsl(Buffer.from(tlsRootCert)); - - return new grpc.Client(peerEndpoint, tlsCredentials); - - } else { - console.log(peerEndpoint); - return new grpc.Client(peerEndpoint, grpc.ChannelCredentials.createInsecure()); - - } - } - -} diff --git a/full-stack-asset-transfer-guide/applications/ping-chaincode/src/jsonid-adapter.ts b/full-stack-asset-transfer-guide/applications/ping-chaincode/src/jsonid-adapter.ts deleted file mode 100644 index 9ffa9f91..00000000 --- a/full-stack-asset-transfer-guide/applications/ping-chaincode/src/jsonid-adapter.ts +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Identity, Signer, signers } from '@hyperledger/fabric-gateway'; -import * as crypto from 'crypto'; -import { promises as fs } from 'fs'; -import * as path from 'path'; - -/** Internal interface used to describe all the possible components - * of the identity - */ -interface JSONID { - name: string; - cert: string; - ca: string; - hsm: boolean; - private_key?: string; - privateKey?: string; - mspId: string; -} - -/** - * This class can be used to map identities in a variety of JSON formats to the Identity and Signers required - * for the gateway. For example if you have an application wallet, or have exported IDs from SaaS - * - * ``` - * const jsonAdapter: JSONIDAdapter = new JSONIDAdapter(path.resolve(__dirname,'..','wallet')) - * - * const gateway = connect({ - * client, - * identity: await jsonAdapter.getIdentity("appuser"), - * signer: await jsonAdapter.getSigner("appuser"), - * }); - * ``` - * - * Though they are JSON files, typically they files will have the .id extension. Therefore - * if no extension is provided `.id` is added - */ -export default class JSONIDAdapter { - private idFilesDir: string; - private mspId = ''; - - /** - * @param idFilesDir Directory to load the files from - * @param mspId optional MSPID to apply to all identities returned if they are missing it - */ - public constructor(idFilesDir: string, mspId?: string) { - this.idFilesDir = path.resolve(idFilesDir); - - if (mspId) { - this.mspId = mspId; - } - } - - private async readIDFile(idFile: string): Promise { - let idJsonFile = path.resolve(path.join(this.idFilesDir, idFile)); - - // check if there's no extension probably means it's a waller id file - if (path.extname(idJsonFile) === '') { - idJsonFile = `${idJsonFile}.id`; - } - - let id: JSONID; - const json = JSON.parse(await fs.readFile(idJsonFile, 'utf-8')); - - // look for the nested credentials element - const credentials = json['credentials']; - - if (credentials) { - // v2 SDK Wallet format - id = { - name: idFile, - cert: credentials['certificate'], - ca: '', - hsm: false, - private_key: credentials['privateKey'], - mspId: json.mspId, - }; - } else { - // IBP exported ID style format - id = { - name: json.name, - cert: Buffer.from(json.cert, 'base64').toString(), - ca: Buffer.from(json.ca, 'base64').toString(), - hsm: json.js, - private_key: Buffer.from(json.private_key, 'base64').toString(), - mspId: this.mspId, - }; - } - return id; - } - - /** - * - * @param idFile the name of the identity to load (if no extension is provided `.id` is added) - * @returns Identity to use with the GatewayBuilder - */ - public async getIdentity(idFile: string): Promise { - const id = await this.readIDFile(idFile); - - const identity: Identity = { - credentials: Buffer.from(id.cert), - mspId: id.mspId, - }; - - return identity; - } - - /** - * - * @param idFile the name of the identity to load (if no extension is provided `.id` is added) - * @returns Signer to use with the GatewayBuilder - */ - public async getSigner(idFile: string): Promise { - const id = await this.readIDFile(idFile); - let pk; - if (id.private_key) { - pk = id.private_key; - } else if ('privateKey' in id) { - pk = id['privateKey']; - } else { - throw new Error('Unable to parse the identity json file'); - } - const privateKey = crypto.createPrivateKey(pk as string); - return signers.newPrivateKeySigner(privateKey); - } -} diff --git a/full-stack-asset-transfer-guide/applications/ping-chaincode/tsconfig.json b/full-stack-asset-transfer-guide/applications/ping-chaincode/tsconfig.json deleted file mode 100644 index d088f396..00000000 --- a/full-stack-asset-transfer-guide/applications/ping-chaincode/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "extends":"@tsconfig/node18/tsconfig.json", - "compilerOptions": { - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "outDir": "dist", - "declaration": true, - "sourceMap": true, - "noImplicitAny": true - }, - "include": [ - "./src/**/*" - ], - "exclude": [ - "./src/**/*.spec.ts" - ] -} diff --git a/full-stack-asset-transfer-guide/applications/rest-api/.gitignore b/full-stack-asset-transfer-guide/applications/rest-api/.gitignore deleted file mode 100644 index 04c01ba7..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -dist/ \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/rest-api/Dockerfile b/full-stack-asset-transfer-guide/applications/rest-api/Dockerfile deleted file mode 100644 index 07e5896e..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM node:14-alpine3.14 AS build -WORKDIR /app -COPY package.json /app -RUN npm install -COPY . /app -CMD [ "npm","run","prod" ] \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/rest-api/LICENSE b/full-stack-asset-transfer-guide/applications/rest-api/LICENSE deleted file mode 100644 index 898e232d..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/LICENSE +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright contributors to the Hyperledger Full Stack Asset Transfer project -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/rest-api/README.md b/full-stack-asset-transfer-guide/applications/rest-api/README.md deleted file mode 100644 index 5dcdf7fa..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/README.md +++ /dev/null @@ -1,37 +0,0 @@ -Make sure all the certificates are generated as per the documentation in the below link -https://github.com/hyperledgendary/full-stack-asset-transfer-guide/blob/main/docs/CloudReady/40-bananas.md - - -#Local development - -npm install -npm run prod - -Import the postman collections and test the apis - - -#Kubernetes development - -Step-1 Build docker image & Tag - -docker build -t localhost:5000/rest-api . - -Step-2 Push docker image to local registary - -docker push localhost:5000/rest-api - -Step-3 Create secrets for the certicates - - kubectl create secret generic client-secret --from-file=keyPath=/home/ramdisk/my-full-stack/infrastructure/sample-network/temp/enrollments/org1/users/org1user/msp/keystore/key.pem --from-file=certPath=/home/ramdisk/my-full-stack/infrastructure/sample-network/temp/enrollments/org1/users/org1user/msp/signcerts/cert.pem --from-file=tlsCertPath=/home/ramdisk/my-full-stack/infrastructure/sample-network/temp/channel-msp/peerOrganizations/org1/msp/tlscacerts/tlsca-signcert.pem -n test-network - -please replace the path of /home/ramdisk/my-full-stack/infrastructure/sample-network/temp with your system path - -Step-4 Deploy the pods to k8s - -kubectl apply -f deployment.yaml -n test-network - -Step-5 Testing API's - -Import the apis into postman and test the apis - -create & list apis are tested.reminaing apis need be implemented diff --git a/full-stack-asset-transfer-guide/applications/rest-api/asset-transfer.postman_collection.json b/full-stack-asset-transfer-guide/applications/rest-api/asset-transfer.postman_collection.json deleted file mode 100644 index 40f6b142..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/asset-transfer.postman_collection.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "info": { - "_postman_id": "56cf175c-ca6b-453a-b950-3d057e19d391", - "name": "asset-transfer", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", - "_exporter_id": "101085" - }, - "item": [ - { - "name": "http://localhost:8081/pokemons", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:8081/pokemons", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8081", - "path": [ - "pokemons" - ] - } - }, - "response": [] - }, - { - "name": "http://localhost:8081/get", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:8081/list", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8081", - "path": [ - "list" - ] - } - }, - "response": [] - }, - { - "name": "http://localhost:8081/get/1", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:8081/get/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8081", - "path": [ - "get", - "1" - ] - } - }, - "response": [] - }, - { - "name": "http://localhost:8081/create", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"appraisedValue\":2,\n \"color\": \"color\",\n \"owner\": \"Ramesh\",\n \"size\": 1\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:8081/create", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8081", - "path": [ - "create" - ] - } - }, - "response": [] - }, - { - "name": "Create", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"appraisedValue\":2,\n \"color\": \"color\",\n \"owner\": \"Ramesh\",\n \"size\": 1\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://restapi.localho.st/create", - "protocol": "http", - "host": [ - "restapi", - "localho", - "st" - ], - "path": [ - "create" - ] - } - }, - "response": [] - }, - { - "name": "List", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://restapi.localho.st/list", - "protocol": "http", - "host": [ - "restapi", - "localho", - "st" - ], - "path": [ - "list" - ] - } - }, - "response": [] - } - ] -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/rest-api/deployment.yaml b/full-stack-asset-transfer-guide/applications/rest-api/deployment.yaml deleted file mode 100644 index d18d9a0c..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/deployment.yaml +++ /dev/null @@ -1,81 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: rest-api - labels: - app: rest-api -spec: - replicas: 1 - selector: - matchLabels: - app: rest-api - template: - metadata: - labels: - app: rest-api - spec: - volumes: - - name: secret-volume - secret: - secretName: client-secret - containers: - - name: rest-api - image: localhost:5000/rest-api:latest - ports: - - containerPort: 8080 - env: - - name: rest-certs - valueFrom: - secretKeyRef: - name: rest-certs - key: key.pem - volumeMounts: - - name: secret-volume - readOnly: true - mountPath: "/etc/secret-volume" ---- -kind: Service -apiVersion: v1 -metadata: - name: rest-api -spec: - selector: - app: rest-api - ports: - - protocol: TCP - port: 80 - targetPort: 8080 - - - # kubectl create secret generic client-secret --from-file=keyPath=/home/ramdisk/my-full-stack/infrastructure/sample-network/temp/enrollments/org1/users/org1user/msp/keystore/key.pem --from-file=certPath=/home/ramdisk/my-full-stack/infrastructure/sample-network/temp/enrollments/org1/users/org1user/msp/signcerts/cert.pem --from-file=tlsCertPath=/home/ramdisk/my-full-stack/infrastructure/sample-network/temp/channel-msp/peerOrganizations/org1/msp/tlscacerts/tlsca-signcert.pem -n test-network ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: rest-api - annotations: - nginx.ingress.kubernetes.io/proxy-connect-timeout: 60s - # nginx.ingress.kubernetes.io/ssl-passthrough: "true" - # labels: - # app: rest-api - # app.kubernetes.io/instance: fabricpeer - # app.kubernetes.io/managed-by: fabric-operator - # app.kubernetes.io/name: fabric - # creator: fabric - # orgname: Org1MSP -spec: - ingressClassName: nginx - rules: - - host: restapi.localho.st - http: - paths: - - backend: - service: - name: rest-api - port: - number: 80 - path: / - pathType: ImplementationSpecific - tls: - - hosts: - - restapi.localho.st \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/rest-api/package.json b/full-stack-asset-transfer-guide/applications/rest-api/package.json deleted file mode 100644 index 487127ab..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "asset-transfer-restapi", - "version": "1.0.0", - "description": "", - "main": "index.js", - "engines": { - "node": ">=18" - }, - "scripts": { - "build": "tsc", - "dev": "ts-node ./src/server.ts", - "start": "nodemon ./dist/server.js", - "prod": "npm run build && npm run start", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "devDependencies": { - "@tsconfig/node18": "^18.2.2", - "@types/body-parser": "^1.17.0", - "@types/express": "^4.16.0", - "@types/node": "^18.18.6", - "@typescript-eslint/eslint-plugin": "^6.9.0", - "@typescript-eslint/parser": "^6.9.0", - "eslint": "^8.52.0", - "nodemon": "^1.18.3", - "ts-node": "^7.0.0", - "typescript": "~5.2.2" - }, - "dependencies": { - "@grpc/grpc-js": "^1.12.2", - "@hyperledger/fabric-gateway": "^1.7.0", - "body-parser": "^1.20.3", - "cors": "^2.8.5", - "express": "^4.21.0" - } -} diff --git a/full-stack-asset-transfer-guide/applications/rest-api/renovate.json b/full-stack-asset-transfer-guide/applications/rest-api/renovate.json deleted file mode 100644 index f45d8f11..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/renovate.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": [ - "config:base" - ] -} diff --git a/full-stack-asset-transfer-guide/applications/rest-api/src/app.ts b/full-stack-asset-transfer-guide/applications/rest-api/src/app.ts deleted file mode 100644 index 30b61561..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/src/app.ts +++ /dev/null @@ -1,27 +0,0 @@ -import * as express from 'express'; -import * as bodyParser from 'body-parser'; -import { Connection } from './connection'; -import { AssetRouter } from './assets.router'; -var cors = require('cors'); - -class App { - public app: express.Application; - public routes: AssetRouter = new AssetRouter(); - constructor() { - new Connection().init(); - this.app = express(); - this.app.use(cors()); - this.config(); - this.routes.routes(this.app); - } - - private config(): void { - // support application/json type post data - this.app.use(bodyParser.json()); - //support application/x-www-form-urlencoded post data - this.app.use(bodyParser.urlencoded({ - extended: false - })); - } -} -export default new App().app; \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/rest-api/src/assets.router.ts b/full-stack-asset-transfer-guide/applications/rest-api/src/assets.router.ts deleted file mode 100644 index bc9ad912..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/src/assets.router.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Request, Response } from "express"; -const utf8Decoder = new TextDecoder(); -import { Connection } from "./connection"; -export class AssetRouter { - public routes(app): void { - app.route('/list') - .get(async (req: Request, res: Response) => { - const resultBytes = Connection.contract.evaluateTransaction('GetAllAssets'); - const resultJson = utf8Decoder.decode(await resultBytes); - const result = JSON.parse(resultJson); - res.status(200).send(result); - }) - app.route('/create') - .post((req: Request, res: Response) => { - console.log(req.body) - var Id = Date.now(); - var json = JSON.stringify({ - ID: Id + "", - Owner: req.body.Owner, - Color: req.body.Color, - Size: req.body.Size, - AppraisedValue: req.body.AppraisedValue, - }) - Connection.contract.submitTransaction('CreateAsset', json); - var response = ({ "AssetId": Id }) - res.status(200).send(response); - }) - app.route('/update') - .post((req: Request, res: Response) => { - console.log(req.body) - var Id = Date.now(); - var json = JSON.stringify({ - ID: req.body.ID, - Owner: req.body.Owner, - Color: req.body.Color, - Size: req.body.Size, - AppraisedValue: req.body.AppraisedValue, - }) - var response; - try { - Connection.contract.submitTransaction('UpdateAsset', json); - response = ({ "status": 0, "message": "Update success" }) - } catch (error) { - response = ({ "status": -1, "message": "Something went wrong" }) - } - res.status(200).send(response); - }) - app.route('/delete') - .post((req: Request, res: Response) => { - console.log(req.body) - var response; - try { - Connection.contract.submitTransaction('DeleteAsset', req.body.id); - response = ({ "status": 0, "message": "Delete success" }) - } catch (error) { - response = ({ "status": -1, "message": "Something went wrong" }) - } - res.status(200).send(response); - }) - app.route('/transfer') - .post(async (req: Request, res: Response) => { - console.log(req.body) - - console.log('\n--> Async Submit Transaction: TransferAsset, updates existing asset owner'); - - const commit = Connection.contract.submitAsync('TransferAsset', { - arguments: [req.body.assetId, 'Saptha'], - }); - const oldOwner = utf8Decoder.decode((await commit).getResult()); - - console.log(`*** Successfully submitted transaction to transfer ownership from ${oldOwner} to Saptha`); - console.log('*** Waiting for transaction commit'); - - const status = await (await commit).getStatus(); - if (!status.successful) { - throw new Error(`Transaction ${status.transactionId} failed to commit with status code ${status.code}`); - } - console.log('*** Transaction committed successfully'); - res.status(200).send(status); - }) - app.route('/updateNonExistentAsset') - .post(async (req: Request, res: Response) => { - try { - await Connection.contract.submitTransaction( - 'UpdateAsset', - 'asset70', - 'blue', - '5', - 'Tomoko', - '300', - ); - console.log('******** FAILED to return an error'); - } catch (error) { - console.log('*** Successfully caught the error: \n', error); - } - res.status(200).send("Success"); - }) - app.route('/get/:id') - .get(async (req: Request, res: Response) => { - let id = req.params.id; - console.log('\n--> Evaluate Transaction: ReadAsset, function returns asset attributes'); - const resultBytes = Connection.contract.evaluateTransaction('ReadAsset', id); - const resultJson = utf8Decoder.decode(await resultBytes); - const result = JSON.parse(resultJson); - console.log('*** Result:', result); - res.status(200).send(result); - }) - } - -} diff --git a/full-stack-asset-transfer-guide/applications/rest-api/src/connection.ts b/full-stack-asset-transfer-guide/applications/rest-api/src/connection.ts deleted file mode 100644 index 44f2c008..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/src/connection.ts +++ /dev/null @@ -1,102 +0,0 @@ -import * as grpc from '@grpc/grpc-js'; -import { connect, Contract, hash, Identity, Signer, signers } from '@hyperledger/fabric-gateway'; -import * as crypto from 'crypto'; -import * as path from 'path'; - -import { promises as fs } from 'fs'; -const channelName = envOrDefault('CHANNEL_NAME', 'mychannel'); -const chaincodeName = envOrDefault('CHAINCODE_NAME', 'asset-transfer'); -const mspId = envOrDefault('MSP_ID', 'Org1MSP'); -//Local development and testing uncomment below code -// const WORKSHOP_CRYPTO =envOrDefault('CRYPTO_PATH', path.resolve(__dirname, '..','..', '..', 'infrastructure', 'sample-network', 'temp')); -// const keyPath = WORKSHOP_CRYPTO + "/enrollments/org1/users/org1user/msp/keystore/key.pem"; -// const certPath = WORKSHOP_CRYPTO + "/enrollments/org1/users/org1user/msp/signcerts/cert.pem" -// const tlsCertPath = WORKSHOP_CRYPTO + "/channel-msp/peerOrganizations/org1/msp/tlscacerts/tlsca-signcert.pem"; - -// //kubenetes certificates file path -const WORKSHOP_CRYPTO = "/etc/secret-volume/" -const keyPath = WORKSHOP_CRYPTO + "keyPath"; -const certPath = WORKSHOP_CRYPTO + "certPath" -const tlsCertPath = WORKSHOP_CRYPTO + "tlsCertPath"; -console.log("keyPath " + keyPath); -console.log("certPath " + certPath); -console.log("tlsCertPath " + tlsCertPath); -const peerEndpoint = "test-network-org1-peer1-peer.localho.st:443"; -const peerHostAlias = "test-network-org1-peer1-peer.localho.st"; -export class Connection { - public static contract: Contract; - public init() { - initFabric(); - } -} -async function initFabric(): Promise { - // The gRPC client connection should be shared by all Gateway connections to this endpoint. - const client = await newGrpcConnection(); - - const gateway = connect({ - client, - identity: await newIdentity(), - signer: await newSigner(), - hash: hash.sha256, - // Default timeouts for different gRPC calls - evaluateOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - endorseOptions: () => { - return { deadline: Date.now() + 15000 }; // 15 seconds - }, - submitOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - commitStatusOptions: () => { - return { deadline: Date.now() + 60000 }; // 1 minute - }, - }); - - try { - // Get a network instance representing the channel where the smart contract is deployed. - const network = gateway.getNetwork(channelName); - - // Get the smart contract from the network. - const contract = network.getContract(chaincodeName); - Connection.contract = contract; - - // Initialize a set of asset data on the ledger using the chaincode 'InitLedger' function. - // await initLedger(contract); - - - } catch (e: any) { - console.log('sample log'); - console.log(e.message); - } finally { - console.log('error log '); - // gateway.close(); - // client.close(); - } -} -async function newGrpcConnection(): Promise { - const tlsRootCert = await fs.readFile(tlsCertPath); - const tlsCredentials = grpc.credentials.createSsl(tlsRootCert); - return new grpc.Client(peerEndpoint, tlsCredentials, { - 'grpc.ssl_target_name_override': peerHostAlias, - }); -} - -async function newIdentity(): Promise { - const credentials = await fs.readFile(certPath); - return { mspId, credentials }; -} - -async function newSigner(): Promise { - //const files = await fs.readdir(keyDirectoryPath); - // path.resolve(keyDirectoryPath, files[0]); - const privateKeyPem = await fs.readFile(keyPath); - const privateKey = crypto.createPrivateKey(privateKeyPem); - return signers.newPrivateKeySigner(privateKey); -} -/** - * envOrDefault() will return the value of an environment variable, or a default value if the variable is undefined. - */ -function envOrDefault(key: string, defaultValue: string): string { - return process.env[key] || defaultValue; -} diff --git a/full-stack-asset-transfer-guide/applications/rest-api/src/server.ts b/full-stack-asset-transfer-guide/applications/rest-api/src/server.ts deleted file mode 100644 index 3d0c4b19..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/src/server.ts +++ /dev/null @@ -1,6 +0,0 @@ -import app from "./app"; -const PORT = process.env.PORT || 8080; - -app.listen(PORT, () => { - console.log('listening on port ' + PORT); -}) diff --git a/full-stack-asset-transfer-guide/applications/rest-api/tsconfig.json b/full-stack-asset-transfer-guide/applications/rest-api/tsconfig.json deleted file mode 100644 index bab355bb..00000000 --- a/full-stack-asset-transfer-guide/applications/rest-api/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "@tsconfig/node18/tsconfig.json", - "compilerOptions": { - "outDir": "dist", //change the output directory - "resolveJsonModule": true //to import out json database - }, - "include": [ - "src/**/*.ts" //which kind of files to compile - ], - "exclude": [ - "node_modules" //which files or directories to ignore - ] -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/.gitignore b/full-stack-asset-transfer-guide/applications/trader-typescript/.gitignore deleted file mode 100644 index 1276eb3b..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - -# Coverage directory used by tools like istanbul -coverage - -# Dependencies -node_modules/ -jspm_packages/ -package-lock.json - -# Compiled TypeScript files -dist - -# Files generated by the application at runtime -checkpoint.json -store.log diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/.npmrc b/full-stack-asset-transfer-guide/applications/trader-typescript/.npmrc deleted file mode 100644 index b6f27f13..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/.npmrc +++ /dev/null @@ -1 +0,0 @@ -engine-strict=true diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/README.md b/full-stack-asset-transfer-guide/applications/trader-typescript/README.md deleted file mode 100644 index ab584847..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Trader sample client application - -This is a simple client application for the [asset-transfer](../../contracts/asset-transfer-typescript/) smart contract, built using the [Fabric Gateway client API](https://hyperledger.github.io/fabric-gateway/) for Fabric v2.4+. - -## Prerequisites - -The client application requires Node.js 16 or later. - -## Set up - -The following steps prepare the client application for execution: - -1. Ensure the [asset-transfer](../../contracts/asset-transfer-typescript/) smart contract is deployed to a running Fabric network. -1. Run `npm install` to download dependencies and compile the application code. - -> **Note:** After making any code changes to the application, be sure to recompile the application code. This can be done by explicitly running `npm install` again, or you can leave `npm run build:watch` running in a terminal window to automatically rebuild the application on any code change. - - -The client application uses environment variables to supply configuration options. You must set the following environment variables when running the application: - -- `ENDPOINT` - endpoint address for the Gateway service to which the client will connect in the form **hostname:port**. Depending on your environment, this can be the address of a specific peer within the user's organization, or an ingress endpoint that dispatches to any available peer in the user's organization. -- `MSP_ID` - member service provider ID for the user's organization. -- `CERTIFICATE` - PEM file containing the user's X.509 certificate. -- `PRIVATE_KEY` - PEM file containing the user's private key. - -The following environment variables are optional and can be set if required by your environment: - -- `CHANNEL_NAME` - Channel to which the chaincode is deployed. (Default: `mychannel`) -- `CHAINCODE_NAME` - Channel to which the chaincode is deployed. (Default: `asset-transfer`) -- `TLS_CERT` - PEM file containing the CA certificate used to authenticate the TLS connection to the Gateway peer. *Only required if using a TLS connection and a private CA.* -- `HOST_ALIAS` - the name of the Gateway peer as it appears in its TLS certificate. *Only required if the endpoint address used by the client does not match the address in the Gateway peer's TLS certificate.* - -# Run - -The sample application is run as a command-line application, and is lauched using `npm start [ ...]`. The following commands are available: - -- `npm start create ` to create a new asset. -- `npm start delete ` to delete an existing asset. -- `npm start getAllAssets` to list all assets. -- `npm start listen` to listen for chaincode events emitted by transaction functions. Interrupt the listener using Control-C. -- `npm start read ` to view an existing asset. -- `npm start transact` to create some random assets and perform some random operations on those assets. -- `npm start transfer ` to transfer an asset to a new owner within an organization MSP ID. diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/eslint.config.mjs b/full-stack-asset-transfer-guide/applications/trader-typescript/eslint.config.mjs deleted file mode 100644 index 9ef6b243..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/eslint.config.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import js from '@eslint/js'; -import tseslint from 'typescript-eslint'; - -export default tseslint.config(js.configs.recommended, ...tseslint.configs.strictTypeChecked, { - languageOptions: { - ecmaVersion: 2023, - sourceType: 'module', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: import.meta.dirname, - }, - }, -}); diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/package.json b/full-stack-asset-transfer-guide/applications/trader-typescript/package.json deleted file mode 100644 index 25351959..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "trader", - "version": "1.0.0", - "description": "Asset transfer client application", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "engines": { - "node": ">=18" - }, - "scripts": { - "build": "tsc", - "build:watch": "tsc -w", - "lint": "eslint src", - "prepare": "npm run build", - "pretest": "npm run lint", - "start": "node ./dist/app", - "test": "" - }, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "@grpc/grpc-js": "^1.12.2", - "@hyperledger/fabric-gateway": "^1.7.0" - }, - "devDependencies": { - "@eslint/js": "^9.3.0", - "@tsconfig/node18": "^18.2.4", - "@types/node": "^18.19.33", - "eslint": "^8.57.0", - "typescript": "~5.4.5", - "typescript-eslint": "^7.11.0" - } -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/app.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/app.ts deleted file mode 100644 index 3d25d14d..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/app.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Command, commands } from './commands'; -import { newGatewayConnection, newGrpcConnection } from './connect'; -import { ExpectedError } from './expectedError'; - -async function main(): Promise { - const commandName = process.argv[2]; - const args = process.argv.slice(3); - - const command = commandName && commands[commandName]; - if (!command) { - printUsage(); - throw new Error(`Unknown command: ${String(commandName)}`); - } - - await runCommand(command, args); -} - -async function runCommand(command: Command, args: string[]): Promise { - const client = await newGrpcConnection(); - try { - const gateway = await newGatewayConnection(client); - try { - await command(gateway, args); - } finally { - gateway.close(); - } - } finally { - client.close(); - } -} - -function printUsage(): void { - console.log('Arguments: [ ...]'); - console.log('Available commands:'); - console.log(`\t${Object.keys(commands).sort().join('\n\t')}`); -} - -main().catch((error: unknown) => { - if (error instanceof ExpectedError) { - console.log(error); - } else { - console.error('\nUnexpected application error:', error); - process.exitCode = 1; - } -}); diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/create.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/create.ts deleted file mode 100644 index 423a7968..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/create.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { AssetTransfer } from '../contract'; -import { assertDefined } from '../utils'; - -const usage = 'Arguments: '; - -export default async function main(gateway: Gateway, args: string[]): Promise { - const assetId = assertDefined(args[0], usage); - const owner = assertDefined(args[1], usage); - const color = assertDefined(args[2], usage); - - const network = gateway.getNetwork(CHANNEL_NAME); - const contract = network.getContract(CHAINCODE_NAME); - - const smartContract = new AssetTransfer(contract); - await smartContract.createAsset({ - ID: assetId, - Owner: owner, - Color: color, - Size: 1, - AppraisedValue: 1, - }); -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/delete.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/delete.ts deleted file mode 100644 index 4cd5df34..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/delete.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { AssetTransfer } from '../contract'; -import { assertDefined } from '../utils'; - -export default async function main(gateway: Gateway, args: string[]): Promise { - const assetId = assertDefined(args[0], 'Arguments: '); - - const network = gateway.getNetwork(CHANNEL_NAME); - const contract = network.getContract(CHAINCODE_NAME); - - const smartContract = new AssetTransfer(contract); - await smartContract.deleteAsset(assetId); -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/getAllAssets.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/getAllAssets.ts deleted file mode 100644 index c849363c..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/getAllAssets.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { AssetTransfer } from '../contract'; - -export default async function main(gateway: Gateway): Promise { - const network = gateway.getNetwork(CHANNEL_NAME); - const contract = network.getContract(CHAINCODE_NAME); - - const smartContract = new AssetTransfer(contract); - const assets = await smartContract.getAllAssets(); - - const assetsJson = JSON.stringify(assets, undefined, 2); - // Write line-by-line to avoid truncation - assetsJson.split('\n').forEach((line) => { - console.log(line); - }); -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/index.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/index.ts deleted file mode 100644 index 1293ff64..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import create from './create'; -import deleteCommand from './delete'; -import getAllAssets from './getAllAssets'; -import listen from './listen'; -import read from './read'; -import transact from './transact'; -import transfer from './transfer'; - -export type Command = (gateway: Gateway, args: string[]) => Promise; - -export const commands: Record = { - create, - delete: deleteCommand, - getAllAssets, - listen, - read, - transact, - transfer, -}; diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/listen.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/listen.ts deleted file mode 100644 index 488bef99..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/listen.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { ChaincodeEvent, checkpointers, Gateway } from '@hyperledger/fabric-gateway'; -import * as path from 'path'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { ExpectedError } from '../expectedError'; -import { printable } from '../utils'; - -const checkpointFile = path.resolve(process.env.CHECKPOINT_FILE ?? 'checkpoint.json'); -const simulatedFailureCount = getSimulatedFailureCount(); - -const startBlock = BigInt(0); - -export default async function main(gateway: Gateway): Promise { - const network = gateway.getNetwork(CHANNEL_NAME); - const checkpointer = await checkpointers.file(checkpointFile); - - console.log('Starting event listening from block', checkpointer.getBlockNumber() ?? startBlock); - console.log('Last processed transaction ID within block:', checkpointer.getTransactionId()); - if (simulatedFailureCount > 0) { - console.log('Simulating a write failure every', simulatedFailureCount, 'transactions'); - } - - const events = await network.getChaincodeEvents(CHAINCODE_NAME, { - startBlock, // Used only if there is no checkpoint block number - }); - - try { - for await (const event of events) { - onEvent(event); - } - } finally { - events.close(); - } -} - -function onEvent(event: ChaincodeEvent): void { - simulateFailureIfRequired(); - - console.log(printable(event)); -} - -function getSimulatedFailureCount(): number { - const value = process.env.SIMULATED_FAILURE_COUNT ?? '0'; - const count = Math.floor(Number(value)); - if (isNaN(count) || count < 0) { - throw new Error(`Invalid SIMULATED_FAILURE_COUNT value: ${String(value)}`); - } - - return count; -} - -let eventCount = 0; // Used only to simulate failures - -function simulateFailureIfRequired(): void { - if (simulatedFailureCount > 0 && eventCount++ >= simulatedFailureCount) { - eventCount = 0; - throw new ExpectedError('Simulated write failure'); - } -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/read.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/read.ts deleted file mode 100644 index 57ac9280..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/read.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { AssetTransfer } from '../contract'; -import { assertDefined } from '../utils'; - -export default async function main(gateway: Gateway, args: string[]): Promise { - const assetId = assertDefined(args[0], 'Arguments: '); - - const network = gateway.getNetwork(CHANNEL_NAME); - const contract = network.getContract(CHAINCODE_NAME); - - const smartContract = new AssetTransfer(contract); - const asset = await smartContract.readAsset(assetId); - - const assetsJson = JSON.stringify(asset, undefined, 2); - console.log(assetsJson); -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/transact.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/transact.ts deleted file mode 100644 index 591c26d7..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/transact.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import * as crypto from 'crypto'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { AssetCreate, AssetTransfer } from '../contract'; -import { allFulfilled, differentElement, randomElement, randomInt } from '../utils'; - -export default async function main(gateway: Gateway): Promise { - const network = gateway.getNetwork(CHANNEL_NAME); - const contract = network.getContract(CHAINCODE_NAME); - - const smartContract = new AssetTransfer(contract); - const app = new TransactApp(smartContract); - await app.run(); -} - -const colors = ['red', 'green', 'blue']; -const maxInitialValue = 1000; -const maxInitialSize = 10; - -class TransactApp { - readonly #smartContract: AssetTransfer; - #batchSize = 6; - - constructor(smartContract: AssetTransfer) { - this.#smartContract = smartContract; - } - - async run(): Promise { - const promises = Array.from({ length: this.#batchSize }, () => this.#transact()); - await allFulfilled(promises); - } - - async #transact(): Promise { - const asset = this.#newAsset(); - - await this.#smartContract.createAsset(asset); - console.log(`Created asset ${asset.ID}`); - - // Update randomly 1 in 2 assets to a new owner. - if (randomInt(2) === 0) { - const oldColor = asset.Color; - asset.Color = differentElement(colors, oldColor); - await this.#smartContract.updateAsset(asset); - console.log(`Updated color of asset ${asset.ID} from ${oldColor} to ${asset.Color}`); - } - - // Delete randomly 1 in 4 created assets. - if (randomInt(4) === 0) { - await this.#smartContract.deleteAsset(asset.ID); - console.log(`Deleted asset ${asset.ID}`); - } - } - - #newAsset(): AssetCreate { - return { - ID: crypto.randomUUID().replaceAll('-', '').substring(0, 8), - Color: randomElement(colors), - Size: randomInt(maxInitialSize) + 1, - AppraisedValue: randomInt(maxInitialValue) + 1, - }; - } - - setbatchSize(batchSize: number): void { - this.#batchSize = batchSize; - } -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/transfer.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/transfer.ts deleted file mode 100644 index 71039ee5..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/commands/transfer.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { Gateway } from '@hyperledger/fabric-gateway'; -import { CHAINCODE_NAME, CHANNEL_NAME } from '../config'; -import { AssetTransfer } from '../contract'; -import { assertDefined } from '../utils'; - -const usage = 'Arguments: '; - -export default async function main(gateway: Gateway, args: string[]): Promise { - const assetId = assertDefined(args[0], usage); - const newOwner = assertDefined(args[1], usage); - const newOwnerOrg = assertDefined(args[2], usage); - - const network = gateway.getNetwork(CHANNEL_NAME); - const contract = network.getContract(CHAINCODE_NAME); - - const smartContract = new AssetTransfer(contract); - await smartContract.transferAsset(assetId, newOwner, newOwnerOrg); -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/config.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/config.ts deleted file mode 100644 index 352f37c9..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/config.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { resolve } from 'path'; -import { assertDefined } from './utils'; - -export const GATEWAY_ENDPOINT = assertEnv('ENDPOINT'); -export const MSP_ID = assertEnv('MSP_ID'); -export const CLIENT_CERT_PATH = resolve(assertEnv('CERTIFICATE')); -export const PRIVATE_KEY_PATH = resolve(assertEnv('PRIVATE_KEY')); -export const TLS_CERT_PATH = resolvePathIfPresent(process.env.TLS_CERT); -export const CHANNEL_NAME = process.env.CHANNEL_NAME ?? 'mychannel'; -export const CHAINCODE_NAME = process.env.CHAINCODE_NAME ?? 'asset-transfer'; - -// Gateway peer SSL host name override. -export const HOST_ALIAS = process.env.HOST_ALIAS; - -function assertEnv(envName: string): string { - return assertDefined(process.env[envName], () => { - console.error('The following environment variables must be set:' + - '\n ENDPOINT - Endpoint address of the gateway service' + - '\n MSP_ID - User\'s organization Member Services Provider ID' + - '\n CERTIFICATE - User\'s certificate file' + - '\n PRIVATE_KEY - User\'s private key file' + - '\n' + - '\nThe following environment variables are optional:' + - '\n CHANNEL_NAME - Channel to which the chaincode is deployed' + - '\n CHAINCODE_NAME - Channel to which the chaincode is deployed' + - '\n TLS_CERT - TLS CA root certificate (only if using TLS and private CA)' + - '\n HOST_ALIAS - TLS hostname override (only if TLS cert does not match endpoint)' + - '\n'); - return `Environment variable ${envName} not set`; - }); -} - -function resolvePathIfPresent(path: string | undefined): string | undefined { - if (path == undefined) { - return undefined; - } - - return resolve(path); -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/connect.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/connect.ts deleted file mode 100644 index 6aac3d2d..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/connect.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as grpc from '@grpc/grpc-js'; -import { connect, Gateway, hash, Identity, Signer, signers } from '@hyperledger/fabric-gateway'; -import * as crypto from 'crypto'; -import * as fs from 'fs'; -import * as path from 'path'; -import { CLIENT_CERT_PATH, GATEWAY_ENDPOINT, HOST_ALIAS, MSP_ID, PRIVATE_KEY_PATH, TLS_CERT_PATH } from './config'; - -export async function newGrpcConnection(): Promise { - if (TLS_CERT_PATH) { - const tlsRootCert = await fs.promises.readFile(TLS_CERT_PATH); - const tlsCredentials = grpc.credentials.createSsl(tlsRootCert); - return new grpc.Client(GATEWAY_ENDPOINT, tlsCredentials, newGrpcClientOptions()); - } - - return new grpc.Client(GATEWAY_ENDPOINT, grpc.ChannelCredentials.createInsecure()); -} - -function newGrpcClientOptions(): grpc.ClientOptions { - const result: grpc.ClientOptions = {}; - if (HOST_ALIAS) { - result['grpc.ssl_target_name_override'] = HOST_ALIAS; // Only required if server TLS cert does not match the endpoint address we use - } - return result; -} - -export async function newGatewayConnection(client: grpc.Client): Promise { - return connect({ - client, - identity: await newIdentity(), - signer: await newSigner(), - hash: hash.sha256, - // Default timeouts for different gRPC calls - evaluateOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - endorseOptions: () => { - return { deadline: Date.now() + 15000 }; // 15 seconds - }, - submitOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - commitStatusOptions: () => { - return { deadline: Date.now() + 60000 }; // 1 minute - }, - }); -} - -async function newIdentity(): Promise { - const certPath = path.resolve(CLIENT_CERT_PATH); - const credentials = await fs.promises.readFile(certPath); - - return { mspId: MSP_ID, credentials }; -} - -async function newSigner(): Promise { - const keyPath = path.resolve(PRIVATE_KEY_PATH); - const privateKeyPem = await fs.promises.readFile(keyPath); - const privateKey = crypto.createPrivateKey(privateKeyPem); - - return signers.newPrivateKeySigner(privateKey); -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/contract.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/contract.ts deleted file mode 100644 index 48c64ba1..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/contract.ts +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { CommitError, Contract, StatusCode } from '@hyperledger/fabric-gateway'; -import { TextDecoder } from 'util'; - -const RETRIES = 2; - -const utf8Decoder = new TextDecoder(); - -export interface Asset { - ID: string; - Color: string; - Size: number; - Owner: string; - AppraisedValue: number; -} - -export type AssetCreate = Omit & Partial; -export type AssetUpdate = Pick & Partial>; - -/** - * AssetTransfer presents the smart contract in a form appropriate to the business application. Internally it uses the - * Fabric Gateway client API to invoke transaction functions, and deals with the translation between the business - * application and API representation of parameters and return values. - */ -export class AssetTransfer { - readonly #contract: Contract; - - constructor(contract: Contract) { - this.#contract = contract; - } - - async createAsset(asset: AssetCreate): Promise { - await this.#contract.submit('CreateAsset', { - arguments: [JSON.stringify(asset)], - }); - } - - async getAllAssets(): Promise { - const result = await this.#contract.evaluate('GetAllAssets'); - if (result.length === 0) { - return []; - } - - return JSON.parse(utf8Decoder.decode(result)) as Asset[]; - } - - async readAsset(id: string): Promise { - const result = await this.#contract.evaluate('ReadAsset', { - arguments: [id], - }); - return JSON.parse(utf8Decoder.decode(result)) as Asset; - } - - async updateAsset(asset: AssetUpdate): Promise { - await submitWithRetry(() => this.#contract.submit('UpdateAsset', { - arguments: [JSON.stringify(asset)], - })); - } - - async deleteAsset(id: string): Promise { - await submitWithRetry(() => this.#contract.submit('DeleteAsset', { - arguments: [id], - })); - } - - async assetExists(id: string): Promise { - const result = await this.#contract.evaluate('AssetExists', { - arguments: [id], - }); - return utf8Decoder.decode(result).toLowerCase() === 'true'; - } - - async transferAsset(id: string, newOwner: string, newOwnerOrg: string): Promise { - console.log(`transferring asset '${id}' to ${newOwner}, ${newOwnerOrg}`); - // TODO: implement the transferAsset() function. - // TODO: submit a 'TransferAsset' transaction, requiring [id, newOwner, newOwnerOrg] arguments. - return Promise.reject(new Error('TODO: implement the contract.ts transferAsset() function.')); - } -} - -async function submitWithRetry(submit: () => Promise): Promise { - let lastError: unknown; - - for (let retryCount = 0; retryCount < RETRIES; retryCount++) { - try { - return await submit(); - } catch (err: unknown) { - lastError = err; - if (err instanceof CommitError) { - // Transaction failed validation and did not update the ledger. Handle specific transaction validation codes. - if (err.code === StatusCode.MVCC_READ_CONFLICT) { - continue; // Retry - } - } - break; // Failure -- don't retry - } - } - - throw lastError; -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/expectedError.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/expectedError.ts deleted file mode 100644 index 296d87be..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/expectedError.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -export class ExpectedError extends Error { - constructor(message?: string) { - super(message); - this.name = ExpectedError.name; - } -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/src/utils.ts b/full-stack-asset-transfer-guide/applications/trader-typescript/src/utils.ts deleted file mode 100644 index b0d3b133..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/src/utils.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -import { inspect, TextDecoder } from 'util'; - -const utf8Decoder = new TextDecoder(); - -/** - * Pick a random element from an array. - * @param values Candidate elements. - */ -export function randomElement(values: T[]): T { - const result = values[randomInt(values.length)]; - return assertDefined(result, `Missing element in {String(values)}`); -} - -/** - * Generate a random integer in the range 0 to max - 1. - * @param max Maximum value (exclusive). - */ -export function randomInt(max: number): number { - return Math.floor(Math.random() * max); -} - -/** - * Pick a random element from an array, excluding the current value. - * @param values Candidate elements. - * @param currentValue Value to avoid. - */ -export function differentElement(values: T[], currentValue: T): T { - const candidateValues = values.filter(value => value !== currentValue); - return randomElement(candidateValues); -} - -/** - * Wait for all promises to complete, then throw an Error only if any of the promises were rejected. - * @param promises Promises to be awaited. - */ -export async function allFulfilled(promises: Promise[]): Promise { - const results = await Promise.allSettled(promises); - const failures = results - .map(result => result.status === 'rejected' && result.reason as unknown) - .filter(reason => !!reason) - .map(reason => inspect(reason)); - - if (failures.length > 0) { - const failMessages = '- ' + failures.join('\n- '); - throw new Error(`${String(failures.length)} failures:\n${failMessages}\n`); - } -} - -export type PrintView = { - [K in keyof T]: T[K] extends Uint8Array ? string : T[K]; -}; - -export function printable(event: T): PrintView { - return Object.fromEntries( - Object.entries(event).map(([k, v]) => [k, v instanceof Uint8Array ? utf8Decoder.decode(v) : v]) - ) as PrintView; -} - -export function assertDefined(value: T | undefined, message: string | (() => string)): T { - if (value == undefined) { - throw new Error(typeof message === 'string' ? message : message()); - } - - return value; -} diff --git a/full-stack-asset-transfer-guide/applications/trader-typescript/tsconfig.json b/full-stack-asset-transfer-guide/applications/trader-typescript/tsconfig.json deleted file mode 100644 index 4c20df24..00000000 --- a/full-stack-asset-transfer-guide/applications/trader-typescript/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "@tsconfig/node18/tsconfig.json", - "compilerOptions": { - "outDir": "dist", - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "noUnusedLocals": true, - "noImplicitReturns": true, - "noUncheckedIndexedAccess": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["./src/**/*"], - "exclude": ["./src/**/*.spec.ts"] -} diff --git a/full-stack-asset-transfer-guide/check.sh b/full-stack-asset-transfer-guide/check.sh deleted file mode 100755 index c3ec4641..00000000 --- a/full-stack-asset-transfer-guide/check.sh +++ /dev/null @@ -1,167 +0,0 @@ -#!/usr/bin/env bash - -SUCCESS="✅" -WARN="⚠️ " -EXIT=0 - -if ! command -v docker &> /tmp/cmdpath -then - echo "${WARN} Please install Docker; suggested install commands:" - EXIT=1 -else - echo -e "${SUCCESS} Docker found:\t$(cat /tmp/cmdpath)" -fi - -KUBECTL_VERSION=v1.28.2 # $(curl -L -s https://dl.k8s.io/release/stable.txt) -if ! command -v kubectl &> /tmp/cmdpath -then - echo "${WARN} Please install kubectl if you want to use k8s; suggested install commands:" - - if [ $(uname -s) = Darwin ]; then - if [ $(uname -m) = arm64 ]; then - echo "curl -LO https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/darwin/arm64/kubectl" - echo "chmod +x ./kubectl" - echo "sudo mv ./kubectl /usr/local/bin/kubectl" - echo "sudo chown root: /usr/local/bin/kubectl" - else - echo "curl -LO https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/darwin/amd64/kubectl" - echo "chmod +x ./kubectl" - echo "sudo mv ./kubectl /usr/local/bin/kubectl" - echo "sudo chown root: /usr/local/bin/kubectl" - fi - else - echo "curl -LO https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl" - echo "sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl" - fi - EXIT=1 -else - echo -e "${SUCCESS} kubectl found:\t$(cat /tmp/cmdpath)" - - KUBECTL_CLIENT_VERSION=$(kubectl version --client --output=yaml | grep gitVersion | cut -c 15-) - KUBECTL_CLIENT_MINOR_VERSION=$(kubectl version --client --output=yaml | grep minor | cut -c 11-12) - if [ "${KUBECTL_CLIENT_MINOR_VERSION}" -lt "24" ]; then - echo -e "${WARN} Found kubectl client version ${KUBECTL_CLIENT_VERSION}, which may be out of date. Please ensure client version >= ${KUBECTL_VERSION}" - EXIT=1 - fi -fi - -# Install kind -KIND_VERSION=0.20.0 -if ! command -v kind &> /tmp/cmdpath -then - echo "${WARN} Please install kind; suggested install commands:" - echo - if [ $(uname -s) = Darwin ]; then - if [ $(uname -m) = arm64 ]; then - echo "sudo curl --fail --silent --show-error -L https://kind.sigs.k8s.io/dl/v${KIND_VERSION}/kind-darwin-arm64 -o /usr/local/bin/kind" - else - echo "sudo curl --fail --silent --show-error -L https://kind.sigs.k8s.io/dl/v${KIND_VERSION}/kind-darwin-amd64 -o /usr/local/bin/kind" - fi - else - echo "sudo curl --fail --silent --show-error -L https://kind.sigs.k8s.io/dl/v${KIND_VERSION}/kind-linux-amd64 -o /usr/local/bin/kind" - fi - echo "sudo chmod 755 /usr/local/bin/kind" - echo - EXIT=1 -else - echo -e "${SUCCESS} kind found:\t\t$(cat /tmp/cmdpath)" -fi - -# Install k9s -K9S_VERSION=0.25.3 -if ! command -v k9s &> /tmp/cmdpath -then - echo "${WARN} Please install k9s; suggested install commands:" - echo - if [ $(uname -s) = Darwin ]; then - if [ $(uname -m) = arm64 ]; then - echo "curl --fail --silent --show-error -L https://github.com/derailed/k9s/releases/download/v${K9S_VERSION}/k9s_Darwin_arm64.tar.gz -o /tmp/k9s_Darwin_arm64.tar.gz" - echo "tar -zxf /tmp/k9s_Darwin_arm64.tar.gz -C /usr/local/bin k9s" - else - echo "curl --fail --silent --show-error -L https://github.com/derailed/k9s/releases/download/v${K9S_VERSION}/k9s_Darwin_x86_64.tar.gz -o /tmp/k9s_Darwin_x86_64.tar.gz" - echo "tar -zxf /tmp/k9s_Darwin_x86_64.tar.gz -C /usr/local/bin k9s" - fi - else - echo "curl --fail --silent --show-error -L https://github.com/derailed/k9s/releases/download/v${K9S_VERSION}/k9s_Linux_x86_64.tar.gz -o /tmp/k9s_Linux_x86_64.tar.gz" - echo "tar -zxf /tmp/k9s_Linux_x86_64.tar.gz -C /usr/local/bin k9s" - fi - echo "sudo chown root /usr/local/bin/k9s" - echo "sudo chmod 755 /usr/local/bin/k9s" - echo - EXIT=1 -else - echo -e "${SUCCESS} k9s found:\t\t$(cat /tmp/cmdpath)" -fi - -# Install just -JUST_VERSION=1.2.0 -if ! command -v just &> /tmp/cmdpath -then - echo "${WARN} Please install just; suggested install commands:" - echo "curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --tag ${JUST_VERSION} --to /usr/local/bin" - EXIT=1 -else - echo -e "${SUCCESS} Just found:\t\t$(cat /tmp/cmdpath)" -fi - -# Install weft -if ! command -v weft &> /tmp/cmdpath -then - echo "${WARN} Please install weft; suggested install commands:" - echo "npm install -g @hyperledger-labs/weft" - EXIT=1 -else - echo -e "${SUCCESS} weft found:\t\t$(cat /tmp/cmdpath)" -fi - -# Install jq -if ! command -v jq &> /tmp/cmdpath -then - echo "${WARN} Please install jq; suggested install commands:" - echo "sudo apt-update && sudo apt-install -y jq" - EXIT=1 -else - echo -e "${SUCCESS} jq found:\t\t$(cat /tmp/cmdpath)" -fi - - -if ! command -v peer &> /tmp/cmdpath -then - echo "${WARN} Please install the peer; suggested install commands:" - echo "curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary" - echo 'export WORKSHOP_PATH=$(pwd)' - echo 'export PATH=${WORKSHOP_PATH}/bin:$PATH' - echo 'export FABRIC_CFG_PATH=${WORKSHOP_PATH}/config' - EXIT=1 -else - echo -e "${SUCCESS} peer found:\t\t$(cat /tmp/cmdpath)" - - # double-check that the peer binary is compiled for the correct arch. This can occur when installing fabric - # binaries into a multipass VM, then running the Linux binaries from a Mac or windows Host OS via the volume share. - peer version &> /dev/null - rc=$? - if [ $rc -ne 0 ]; then - echo -e "${WARN} Could not execute peer. Was it compiled for the correct architecture?" - peer version - fi -fi - -# tests if varname is defined in the env AND it's an existing directory -function must_declare() { - local varname=$1 - - if [[ ! -d ${!varname} ]]; then - echo "${WARN} ${varname} must be set to a directory" - EXIT=1 - - else - echo -e "${SUCCESS} ${varname}:\t${!varname}" - fi -} - -must_declare "FABRIC_CFG_PATH" -must_declare "WORKSHOP_PATH" - -rm /tmp/cmdpath &> /dev/null - -exit $EXIT diff --git a/full-stack-asset-transfer-guide/checks/check-chaincode.sh b/full-stack-asset-transfer-guide/checks/check-chaincode.sh deleted file mode 100755 index 3a6cf115..00000000 --- a/full-stack-asset-transfer-guide/checks/check-chaincode.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -set -eou pipefail - -# All checks run in the workshop root folder -cd "$(dirname "$0")"/.. - -. checks/utils.sh - -EXIT=0 - -function chaincode_ready() { - peer chaincode query -n asset-transfer -C mychannel -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' -} - -must_declare WORKSHOP_CRYPTO - -must_declare CORE_PEER_LOCALMSPID -must_declare CORE_PEER_ADDRESS -must_declare CORE_PEER_TLS_ENABLED -must_declare CORE_PEER_MSPCONFIGPATH -must_declare CORE_PEER_TLS_ROOTCERT_FILE -must_declare CORE_PEER_CLIENT_CONNTIMEOUT -must_declare CORE_PEER_DELIVERYCLIENT_CONNTIMEOUT -must_declare ORDERER_ENDPOINT -must_declare ORDERER_TLS_CERT - -check chaincode_ready "asset-transfer chaincode is running" - -exit $EXIT diff --git a/full-stack-asset-transfer-guide/checks/check-kube.sh b/full-stack-asset-transfer-guide/checks/check-kube.sh deleted file mode 100755 index 82fb354b..00000000 --- a/full-stack-asset-transfer-guide/checks/check-kube.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -set -eo pipefail - -# All checks run in the workshop root folder -cd "$(dirname "$0")"/.. - -. checks/utils.sh - -EXIT=0 - - -function cluster_info() { - kubectl cluster-info &>/dev/null -} - -function nginx() { - kubectl -n ingress-nginx get all &>/dev/null - kubectl -n ingress-nginx get deployment.apps/ingress-nginx-controller &>/dev/null - curl http://${WORKSHOP_INGRESS_DOMAIN} &>/dev/null - curl --insecure https://${WORKSHOP_INGRESS_DOMAIN}:443 &>/dev/null -} - -function container_registry() { - curl --fail http://${WORKSHOP_INGRESS_DOMAIN}:5000/v2/_catalog &>/dev/null -} - - -must_declare WORKSHOP_INGRESS_DOMAIN -must_declare WORKSHOP_NAMESPACE - -check cluster_info "k8s API controller is running" -check nginx "Nginx ingress is running at https://${WORKSHOP_INGRESS_DOMAIN}" - -if [ x"${WORKSHOP_CLUSTER_RUNTIME}" == x"kind" ]; then - check container_registry "Container registry is running at ${WORKSHOP_INGRESS_DOMAIN}:5000" -fi - -exit $EXIT - diff --git a/full-stack-asset-transfer-guide/checks/check-network.sh b/full-stack-asset-transfer-guide/checks/check-network.sh deleted file mode 100755 index 157d15b5..00000000 --- a/full-stack-asset-transfer-guide/checks/check-network.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash - -set -eou pipefail - -# All checks run in the workshop root folder -cd "$(dirname "$0")"/.. - -. checks/utils.sh - -EXIT=0 - -function operator_crds() { - kubectl get customresourcedefinition.apiextensions.k8s.io/ibpcas.ibp.com - kubectl get customresourcedefinition.apiextensions.k8s.io/ibpconsoles.ibp.com - kubectl get customresourcedefinition.apiextensions.k8s.io/ibporderers.ibp.com - kubectl get customresourcedefinition.apiextensions.k8s.io/ibppeers.ibp.com -} - -function fabric_resources() { - # Did it apply the CRDs? - kubectl -n ${WORKSHOP_NAMESPACE} get ibpca org0-ca - kubectl -n ${WORKSHOP_NAMESPACE} get ibpca org1-ca - kubectl -n ${WORKSHOP_NAMESPACE} get ibpca org2-ca - kubectl -n ${WORKSHOP_NAMESPACE} get ibppeer org1-peer1 - kubectl -n ${WORKSHOP_NAMESPACE} get ibppeer org1-peer2 - kubectl -n ${WORKSHOP_NAMESPACE} get ibppeer org2-peer1 - kubectl -n ${WORKSHOP_NAMESPACE} get ibppeer org2-peer2 - kubectl -n ${WORKSHOP_NAMESPACE} get ibporderer org0-orderersnode1 - kubectl -n ${WORKSHOP_NAMESPACE} get ibporderer org0-orderersnode2 - kubectl -n ${WORKSHOP_NAMESPACE} get ibporderer org0-orderersnode3 -} - -function fabric_deployment() { - kubectl -n ${WORKSHOP_NAMESPACE} get deployment fabric-operator - kubectl -n ${WORKSHOP_NAMESPACE} get deployment org0-ca - kubectl -n ${WORKSHOP_NAMESPACE} get deployment org0-orderersnode1 - kubectl -n ${WORKSHOP_NAMESPACE} get deployment org0-orderersnode2 - kubectl -n ${WORKSHOP_NAMESPACE} get deployment org0-orderersnode3 - kubectl -n ${WORKSHOP_NAMESPACE} get deployment org1-ca - kubectl -n ${WORKSHOP_NAMESPACE} get deployment org1-peer1 - kubectl -n ${WORKSHOP_NAMESPACE} get deployment org1-peer2 - kubectl -n ${WORKSHOP_NAMESPACE} get deployment org2-ca - kubectl -n ${WORKSHOP_NAMESPACE} get deployment org2-peer1 - kubectl -n ${WORKSHOP_NAMESPACE} get deployment org2-peer2 -} - -function cas_ready() { - WORKSHOP_CRYPTO=$WORKSHOP_PATH/infrastructure/sample-network/temp - - # Hit the CAs using the TLS certs, etc. - curl --fail -s --cacert $WORKSHOP_CRYPTO/cas/org0-ca/tls-cert.pem https://$WORKSHOP_NAMESPACE-org0-ca-ca.$WORKSHOP_INGRESS_DOMAIN/cainfo | jq -c - curl --fail -s --cacert $WORKSHOP_CRYPTO/cas/org1-ca/tls-cert.pem https://$WORKSHOP_NAMESPACE-org1-ca-ca.$WORKSHOP_INGRESS_DOMAIN/cainfo | jq -c - curl --fail -s --cacert $WORKSHOP_CRYPTO/cas/org2-ca/tls-cert.pem https://$WORKSHOP_NAMESPACE-org2-ca-ca.$WORKSHOP_INGRESS_DOMAIN/cainfo | jq -c -} - -function channel_msp() { - WORKSHOP_CRYPTO=$WORKSHOP_PATH/infrastructure/sample-network/temp - - find $WORKSHOP_CRYPTO/channel-msp -} - -must_declare WORKSHOP_PATH -must_declare FABRIC_CFG_PATH - -check operator_crds "fabric-operator CRDs have been installed" -check fabric_resources "Network Peers, Orderers, and CAs have been created" -check fabric_deployment "Service deployments are ready" -check cas_ready "Certificate Authorities are running" -check channel_msp "Channel has been created" - -exit $EXIT - diff --git a/full-stack-asset-transfer-guide/checks/utils.sh b/full-stack-asset-transfer-guide/checks/utils.sh deleted file mode 100644 index 9c4a14ef..00000000 --- a/full-stack-asset-transfer-guide/checks/utils.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -# -# Copyright IBM Corp All Rights Reserved -# -# SPDX-License-Identifier: Apache-2.0 -# - -SUCCESS="✅" -WARN="⚠️ " - -# tests if varname is defined in the env AND it's an existing directory -function must_declare() { - local varname=$1 - - if [[ ${!varname+x} ]] - then - printf "%s %-40s%s\n" $SUCCESS $varname ${!varname} - else - printf "%s %-40s\n" ${WARN} $varname - EXIT=1 - fi -} - - -function check() { - local name=$1 - local message=$2 - - printf "🤔 %s" $name - - if $name &>/dev/null ; then - printf "\r%s %-40s" $SUCCESS $name - else - printf "\r%s %-40s" $WARN $name - EXIT=1 - fi - - echo $message -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/.gitignore b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/.gitignore deleted file mode 100644 index 9d9c13e9..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# - - -# Coverage directory used by tools like istanbul -coverage - -# Dependency directories -node_modules/ -jspm_packages/ -package-lock.json - -# Compiled TypeScript files -dist - -# Files created during workshop run -metadata.json diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/.npmrc b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/.npmrc deleted file mode 100644 index b6f27f13..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/.npmrc +++ /dev/null @@ -1 +0,0 @@ -engine-strict=true diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/Dockerfile b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/Dockerfile deleted file mode 100644 index 184bc27a..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/Dockerfile +++ /dev/null @@ -1,69 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# -FROM node:18 AS builder - -WORKDIR /usr/src/app - -# Copy node.js source and build, changing owner as well -COPY --chown=node:node . /usr/src/app -ENV npm_config_cache=/usr/src/app -RUN npm install -RUN npm run build && npm shrinkwrap - - -FROM node:18.16 as prod-builder -WORKDIR /usr/src/app -COPY --chown=node:node --from=builder /usr/src/app/dist ./dist -COPY --chown=node:node --from=builder /usr/src/app/package.json ./ -COPY --chown=node:node --from=builder /usr/src/app/npm-shrinkwrap.json ./ -RUN npm ci --omit=dev && npm cache clean --force - -# ------------------------------------------------------------------------------ -# Builds the Chaincode as a Service docker version -FROM node:18.16 AS ccaas -WORKDIR /usr/src/app - -ARG TARGETARCH -ARG TARGETOS - -COPY --chown=node:node --from=prod-builder /usr/src/app . -COPY --chown=node:node docker/docker-entrypoint.sh /usr/src/app/docker-entrypoint.sh - -ARG CC_SERVER_PORT -ENV PORT $CC_SERVER_PORT -EXPOSE $CC_SERVER_PORT - -ENV TINI_VERSION=v0.19.0 -ENV PLATFORM=${TARGETARCH} -ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${PLATFORM} /tini -RUN chmod +x /tini - -ENV NODE_ENV=production -USER node -ENTRYPOINT [ "/tini", "--", "/usr/src/app/docker-entrypoint.sh" ] - - - -# ------------------------------------------------------------------------------ -# Builds the chaincode for the k8s builder -FROM node:18.16 AS k8s -WORKDIR /usr/src/app - -ARG TARGETARCH -ARG TARGETOS - -COPY --chown=node:node --from=prod-builder /usr/src/app . -COPY --chown=node:node docker/docker-entrypoint.sh /usr/src/app/docker-entrypoint.sh - -RUN printenv - -ENV TINI_VERSION=v0.19.0 -ENV PLATFORM=${TARGETARCH} -ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${PLATFORM} /tini -RUN chmod +x /tini - -ENV NODE_ENV=production -USER node -ENTRYPOINT [ "/tini", "--", "/usr/src/app/docker-entrypoint.sh" ] - diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/asset-transfer-chaincode-vars.yml b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/asset-transfer-chaincode-vars.yml deleted file mode 100644 index 0838df68..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/asset-transfer-chaincode-vars.yml +++ /dev/null @@ -1,11 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -smart_contract_name: "asset-transfer" -smart_contract_version: "1.0.0" -smart_contract_sequence: 1 -smart_contract_package: "asset-transfer.tgz" -# smart_contract_constructor: "initLedger" -smart_contract_endorsement_policy: "" -smart_contract_collections_file: "" diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/docker/docker-entrypoint.sh b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/docker/docker-entrypoint.sh deleted file mode 100755 index 4aaac8c5..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/docker/docker-entrypoint.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -# -# SPDX-License-Identifier: Apache-2.0 -# -set -euo pipefail -: ${CORE_PEER_TLS_ENABLED:="false"} -: ${DEBUG:="false"} - -if [ "${DEBUG,,}" = "true" ]; then - npm run start:server-debug - -elif [[ ! -v CHAINCODE_SERVER_ADDRESS ]]; then - npm start -- --peer.address $CORE_PEER_ADDRESS - -elif [ "${CORE_PEER_TLS_ENABLED,,}" = "true" ]; then - npm run start:server - -else - npm run start:server-nontls -fi - diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/eslint.config.mjs b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/eslint.config.mjs deleted file mode 100644 index 9ef6b243..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/eslint.config.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import js from '@eslint/js'; -import tseslint from 'typescript-eslint'; - -export default tseslint.config(js.configs.recommended, ...tseslint.configs.strictTypeChecked, { - languageOptions: { - ecmaVersion: 2023, - sourceType: 'module', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: import.meta.dirname, - }, - }, -}); diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/npm-shrinkwrap.json b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/npm-shrinkwrap.json deleted file mode 100644 index acd6b6b3..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/npm-shrinkwrap.json +++ /dev/null @@ -1,2274 +0,0 @@ -{ - "name": "asset-transfer", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "asset-transfer", - "version": "1.0.0", - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "~2.5", - "fabric-shim": "~2.5", - "json-stringify-deterministic": "^1.0.7", - "sort-keys-recursive": "^2.1.7" - }, - "devDependencies": { - "@eslint/js": "^9.3.0", - "@tsconfig/node18": "^18.2.4", - "@types/node": "^18.19.33", - "eslint": "^8.57.0", - "typescript": "~5.4.5", - "typescript-eslint": "^7.11.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.5.0.tgz", - "integrity": "sha512-A7+AOT2ICkodvtsWnxZP4Xxk3NbZ3VMHd8oihydLRGrJgqqdEz1qSeEgXYyT/Cu8h1TWWsQRejIx48mtjZ5y1w==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@fidm/asn1": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@fidm/asn1/-/asn1-1.0.4.tgz", - "integrity": "sha512-esd1jyNvRb2HVaQGq2Gg8Z0kbQPXzV9Tq5Z14KNIov6KfFD6PTaRIO8UpcsYiTNzOqJpmyzWgVTrUwFV3UF4TQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@fidm/x509": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@fidm/x509/-/x509-1.2.1.tgz", - "integrity": "sha512-nwc2iesjyc9hkuzcrMCBXQRn653XuAUKorfWM8PZyJawiy1QzLj4vahwzaI25+pfpwOLvMzbJ0uKpWLDNmo16w==", - "dependencies": { - "@fidm/asn1": "^1.0.4", - "tweetnacl": "^1.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.10.9", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.9.tgz", - "integrity": "sha512-5tcgUctCG0qoNyfChZifz2tJqbRbXVO9J7X6duFcOjY3HUNCxg5D0ZCK7EP9vIcZ0zRpLU9bWkyCqVCLZ46IbQ==", - "dependencies": { - "@grpc/proto-loader": "^0.7.13", - "@js-sdsl/ordered-map": "^4.4.2" - }, - "engines": { - "node": ">=12.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@hyperledger/fabric-protos": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@hyperledger/fabric-protos/-/fabric-protos-0.2.1.tgz", - "integrity": "sha512-qjm0vIQIfCall804tWDeA8p/mUfu14sl5Sj+PbOn2yDKJq+7ThoIhNsLAqf+BCxUfqsoqQq6AojhqQeTFyOOqg==", - "dependencies": { - "@grpc/grpc-js": "^1.9.0", - "google-protobuf": "^3.21.0" - }, - "engines": { - "node": ">=14.15.0" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@tsconfig/node18": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node18/-/node18-18.2.4.tgz", - "integrity": "sha512-5xxU8vVs9/FNcvm3gE07fPbn9tl6tqGGWA9tSlwsUEkBxtRnTsNmwrV8gasZ9F/EobaSv9+nu8AxUKccw77JpQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.19.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.34.tgz", - "integrity": "sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/triple-beam": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/class-transformer": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", - "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==" - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fabric-contract-api": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-contract-api/-/fabric-contract-api-2.5.6.tgz", - "integrity": "sha512-AosGb8tA+Jgt+pqMEgYNB3/J/P5QuWOC7yhXbhDmAAwUzn4Sc7pdWDICH1YyrFGZNFxMGQmqJmLVWUX8BKHy0w==", - "dependencies": { - "class-transformer": "^0.4.0", - "fabric-shim-api": "2.5.6", - "fast-safe-stringify": "^2.1.1", - "get-params": "^0.1.2", - "reflect-metadata": "^0.1.13", - "winston": "^3.7.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fabric-shim": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-shim/-/fabric-shim-2.5.6.tgz", - "integrity": "sha512-4Y8WNFhYuQ9QYSEgPXWdlXnrXjwOlM10sQQzE4kJ7cDh8a4LX0rn44FxtxTCB18lnzrSLMZ8/8Cr5m0c9NeXWA==", - "dependencies": { - "@fidm/x509": "^1.2.1", - "@grpc/grpc-js": "~1.10.9", - "@hyperledger/fabric-protos": "~0.2.1", - "@types/node": "^16.11.1", - "ajv": "^6.12.2", - "fabric-contract-api": "2.5.6", - "fabric-shim-api": "2.5.6", - "fast-safe-stringify": "^2.1.1", - "long": "^5.2.3", - "reflect-metadata": "^0.1.13", - "winston": "^3.7.2", - "yargs": "^17.4.0", - "yargs-parser": "^21.0.1" - }, - "bin": { - "fabric-chaincode-node": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fabric-shim-api": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/fabric-shim-api/-/fabric-shim-api-2.5.6.tgz", - "integrity": "sha512-1L0nO7CJ31/gEOWKWHEeCqgB5HkqPVfRbpcS7L9eTscT7tffjg2OkZISvC+a7RiqihL0iyrXNBgBg5MwlSSN9g==", - "engines": { - "eslint": "^6.6.0", - "node": ">=18" - } - }, - "node_modules/fabric-shim/node_modules/@types/node": { - "version": "16.18.98", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.98.tgz", - "integrity": "sha512-fpiC20NvLpTLAzo3oVBKIqBGR6Fx/8oAK/SSf7G+fydnXMY1x4x9RZ6sBXhqKlCU21g2QapUsbLlhv3+a7wS+Q==" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-params": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/get-params/-/get-params-0.1.2.tgz", - "integrity": "sha512-41eOxtlGgHQRbFyA8KTH+w+32Em3cRdfBud7j67ulzmIfmaHX9doq47s0fa4P5o9H64BZX9nrYI6sJvk46Op+Q==" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/google-protobuf": { - "version": "3.21.2", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz", - "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json-stringify-deterministic": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/json-stringify-deterministic/-/json-stringify-deterministic-1.0.12.tgz", - "integrity": "sha512-q3PN0lbUdv0pmurkBNdJH3pfFvOTL/Zp0lquqpvcjfKzt6Y0j49EPHAmVHCAS4Ceq/Y+PejWTzyiVpoY71+D6g==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/logform": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", - "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", - "dependencies": { - "@colors/colors": "1.6.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/protobufjs": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.2.tgz", - "integrity": "sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/reflect-metadata": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", - "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==" - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/sort-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-4.2.0.tgz", - "integrity": "sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==", - "dependencies": { - "is-plain-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sort-keys-recursive": { - "version": "2.1.10", - "resolved": "https://registry.npmjs.org/sort-keys-recursive/-/sort-keys-recursive-2.1.10.tgz", - "integrity": "sha512-yRLJbEER/PjU7hSRwXvP+NyXiORufu8rbSbp+3wFRuJZXoi/AhuKczbjuipqn7Le0SsTXK4VUeri2+Ni6WS8Hg==", - "dependencies": { - "kind-of": "~6.0.2", - "sort-keys": "~4.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "engines": { - "node": "*" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/triple-beam": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", - "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.13.0.tgz", - "integrity": "sha512-upO0AXxyBwJ4BbiC6CRgAJKtGYha2zw4m1g7TIVPSonwYEuf7vCicw3syjS1OxdDMTz96sZIXl3Jx3vWJLLKFw==", - "dev": true, - "dependencies": { - "@typescript-eslint/eslint-plugin": "7.13.0", - "@typescript-eslint/parser": "7.13.0", - "@typescript-eslint/utils": "7.13.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.0.tgz", - "integrity": "sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.13.0", - "@typescript-eslint/type-utils": "7.13.0", - "@typescript-eslint/utils": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.0.tgz", - "integrity": "sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "7.13.0", - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/typescript-estree": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz", - "integrity": "sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.0.tgz", - "integrity": "sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "7.13.0", - "@typescript-eslint/utils": "7.13.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz", - "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz", - "integrity": "sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.0.tgz", - "integrity": "sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.13.0", - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/typescript-estree": "7.13.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz", - "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/typescript-eslint/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/winston": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.0.tgz", - "integrity": "sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==", - "dependencies": { - "@colors/colors": "^1.6.0", - "@dabh/diagnostics": "^2.0.2", - "async": "^3.2.3", - "is-stream": "^2.0.0", - "logform": "^2.4.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "safe-stable-stringify": "^2.3.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/winston-transport": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", - "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", - "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/package.json b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/package.json deleted file mode 100644 index 3565c360..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "asset-transfer", - "version": "1.0.0", - "description": "Asset Transfer contract implemented in TypeScript", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "engines": { - "node": ">=18" - }, - "scripts": { - "lint": "eslint src", - "pretest": "npm run lint", - "test": "", - "start": "set -x && fabric-chaincode-node start", - "build": "tsc", - "build:watch": "tsc -w", - "prepublishOnly": "npm run build", - "metadata": "set -x && fabric-chaincode-node metadata generate --file metadata.json", - "docker": "docker build -f ./Dockerfile -t asset-transfer-basic .", - "package:caas": "npm run build && weft chaincode package caas --path . --label asset-transfer --address ${CHAINCODE_SERVER_ADDRESS} --archive asset-transfer-caas.tgz --quiet", - "package:k8s": "npm run build && weft chaincode package caas --path . --label asset-transfer --address ${CHAINCODE_SERVER_ADDRESS} --archive asset-transfer-caas.tgz --quiet", - "start:server-nontls": "set -x && fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID", - "start:server-debug": "set -x && NODE_OPTIONS='--inspect=0.0.0.0:9229' fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID", - "start:server": "set -x && fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID --chaincode-tls-key-file=/hyperledger/privatekey.pem --chaincode-tls-client-cacert-file=/hyperledger/rootcert.pem --chaincode-tls-cert-file=/hyperledger/cert.pem" - }, - "author": "Hyperledger", - "license": "Apache-2.0", - "dependencies": { - "fabric-contract-api": "~2.5", - "fabric-shim": "~2.5", - "json-stringify-deterministic": "^1.0.7", - "sort-keys-recursive": "^2.1.7" - }, - "devDependencies": { - "@types/node": "^18.19.33", - "@eslint/js": "^9.3.0", - "@tsconfig/node18": "^18.2.4", - "eslint": "^8.57.0", - "typescript": "~5.4.5", - "typescript-eslint": "^7.11.0" - }, - "nyc": { - "extension": [ - ".ts", - ".tsx" - ], - "exclude": [ - "coverage/**", - "dist/**" - ], - "reporter": [ - "text-summary", - "html" - ], - "all": true, - "check-coverage": true, - "statements": 100, - "branches": 100, - "functions": 100, - "lines": 100 - } -} diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/src/asset.ts b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/src/asset.ts deleted file mode 100644 index 53538a43..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/src/asset.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - SPDX-License-Identifier: Apache-2.0 -*/ - -import { Object as DataType, Property } from 'fabric-contract-api'; - -@DataType() -export class Asset { - @Property('ID', 'string') - ID = ''; - - @Property('Color', 'string') - Color = ''; - - @Property('Owner', 'string') - Owner = ''; - - @Property('AppraisedValue', 'number') - AppraisedValue = 0; - - @Property('Size', 'number') - Size = 0; - - static newInstance(state: Partial = {}): Asset { - return { - ID: assertHasValue(state.ID, 'Missing ID'), - Color: state.Color ?? '', - Size: state.Size ?? 0, - Owner: assertHasValue(state.Owner, 'Missing Owner'), - AppraisedValue: state.AppraisedValue ?? 0, - }; - } -} - -function assertHasValue(value: T | undefined | null, message: string): T { - if (value == undefined || (typeof value === 'string' && value.length === 0)) { - throw new Error(message); - } - - return value; -} diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/src/assetTransfer.ts b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/src/assetTransfer.ts deleted file mode 100644 index b3bd1b2e..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/src/assetTransfer.ts +++ /dev/null @@ -1,225 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -import { X509Certificate } from 'crypto'; -import { Context, Contract, Info, Param, Returns, Transaction } from 'fabric-contract-api'; -import { KeyEndorsementPolicy } from 'fabric-shim'; -import stringify from 'json-stringify-deterministic'; // Deterministic JSON.stringify() -import sortKeysRecursive from 'sort-keys-recursive'; -import { TextDecoder } from 'util'; -import { Asset } from './asset'; - -const utf8Decoder = new TextDecoder(); - -@Info({title: 'AssetTransfer', description: 'Smart contract for trading assets'}) -export class AssetTransferContract extends Contract { - /** - * CreateAsset issues a new asset to the world state with given details. - */ - @Transaction() - @Param('assetObj', 'Asset', 'Part formed JSON of Asset') - async CreateAsset(ctx: Context, state: Asset): Promise { - state.Owner = toJSON(clientIdentifier(ctx, state.Owner)); - const asset = Asset.newInstance(state); - - const exists = await this.AssetExists(ctx, asset.ID); - if (exists) { - throw new Error(`The asset ${asset.ID} already exists`); - } - - const assetBytes = marshal(asset); - await ctx.stub.putState(asset.ID, assetBytes); - - await setEndorsingOrgs(ctx, asset.ID, ctx.clientIdentity.getMSPID()); - - ctx.stub.setEvent('CreateAsset', assetBytes); - } - - /** - * ReadAsset returns an existing asset stored in the world state. - */ - @Transaction(false) - @Returns('Asset') - async ReadAsset(ctx: Context, id: string): Promise { - const existingAssetBytes = await this.#readAsset(ctx, id); - const existingAsset = Asset.newInstance(unmarshal(existingAssetBytes)); - - return existingAsset; - } - - async #readAsset(ctx: Context, id: string): Promise { - const assetBytes = await ctx.stub.getState(id); // get the asset from chaincode state - if (assetBytes.length === 0) { - throw new Error(`Sorry, asset ${id} has not been created`); - } - - return assetBytes; - } - - /** - * UpdateAsset updates an existing asset in the world state with provided partial asset data, which must include - * the asset ID. - */ - @Transaction() - @Param('assetObj', 'Asset', 'Part formed JSON of Asset') - async UpdateAsset(ctx: Context, assetUpdate: Asset): Promise { - if (!assetUpdate.ID) { - throw new Error('No asset ID specified'); - } - - const existingAssetBytes = await this.#readAsset(ctx, assetUpdate.ID); - const existingAsset = Asset.newInstance(unmarshal(existingAssetBytes)); - - if (!hasWritePermission(ctx, existingAsset)) { - throw new Error('Only owner can update assets'); - } - - const updatedState = Object.assign({}, existingAsset, assetUpdate, { - Owner: existingAsset.Owner, // Must transfer to change owner - }); - const updatedAsset = Asset.newInstance(updatedState); - - // overwriting original asset with new asset - const updatedAssetBytes = marshal(updatedAsset); - await ctx.stub.putState(updatedAsset.ID, updatedAssetBytes); - - await setEndorsingOrgs(ctx, updatedAsset.ID, ctx.clientIdentity.getMSPID()); - - ctx.stub.setEvent('UpdateAsset', updatedAssetBytes); - } - - /** - * DeleteAsset deletes an asset from the world state. - */ - @Transaction() - async DeleteAsset(ctx: Context, id: string): Promise { - const assetBytes = await this.#readAsset(ctx, id); // Throws if asset does not exist - const asset = Asset.newInstance(unmarshal(assetBytes)); - - if (!hasWritePermission(ctx, asset)) { - throw new Error('Only owner can delete assets'); - } - - await ctx.stub.deleteState(id); - - ctx.stub.setEvent('DeletaAsset', assetBytes); - } - - /** - * AssetExists returns true when asset with the specified ID exists in world state; otherwise false. - */ - @Transaction(false) - @Returns('boolean') - async AssetExists(ctx: Context, id: string): Promise { - const assetJson = await ctx.stub.getState(id); - return assetJson.length > 0; - } - - /** - * TransferAsset updates the owner field of asset with the specified ID in the world state. - */ - @Transaction() - async TransferAsset(ctx: Context, id: string, newOwner: string, newOwnerOrg: string): Promise { - const assetString = await this.#readAsset(ctx, id); - const asset = Asset.newInstance(unmarshal(assetString)); - - if (!hasWritePermission(ctx, asset)) { - throw new Error('Only owner can transfer assets'); - } - - asset.Owner = toJSON(ownerIdentifier(newOwner, newOwnerOrg)); - - const assetBytes = marshal(asset); - await ctx.stub.putState(id, assetBytes); - - await setEndorsingOrgs(ctx, id, newOwnerOrg); // Subsequent updates must be endorsed by the new owning org - - ctx.stub.setEvent('TransferAsset', assetBytes); - } - - /** - * GetAllAssets returns a list of all assets found in the world state. - */ - @Transaction(false) - @Returns('string') - async GetAllAssets(ctx: Context): Promise { - // range query with empty string for startKey and endKey does an open-ended query of all assets in the chaincode namespace. - const iterator = await ctx.stub.getStateByRange('', ''); - - const assets: Asset[] = []; - for (let result = await iterator.next(); !result.done; result = await iterator.next()) { - const assetBytes = result.value.value; - try { - const asset = Asset.newInstance(unmarshal(assetBytes)); - assets.push(asset); - } catch (err) { - console.log(err); - } - } - - return marshal(assets).toString(); - } -} - -function unmarshal(bytes: Uint8Array | string): object { - const json = typeof bytes === 'string' ? bytes : utf8Decoder.decode(bytes); - const parsed: unknown = JSON.parse(json); - if (parsed === null || typeof parsed !== 'object') { - throw new Error(`Invalid JSON type (${typeof parsed}): ${json}`); - } - - return parsed; -} - -function marshal(o: object): Buffer { - return Buffer.from(toJSON(o)); -} - -function toJSON(o: object): string { - // Insert data in alphabetic order using 'json-stringify-deterministic' and 'sort-keys-recursive' - return stringify(sortKeysRecursive(o)); -} - -interface OwnerIdentifier { - org: string; - user: string; -} - -function hasWritePermission(ctx: Context, asset: Asset): boolean { - const clientId = clientIdentifier(ctx); - const ownerId = unmarshal(asset.Owner) as OwnerIdentifier; - return clientId.org === ownerId.org; -} - -function clientIdentifier(ctx: Context, user?: string): OwnerIdentifier { - return { - org: ctx.clientIdentity.getMSPID(), - user: user ?? clientCommonName(ctx), - }; -} - -function clientCommonName(ctx: Context): string { - const clientCert = new X509Certificate(ctx.clientIdentity.getIDBytes()); - const matches = clientCert.subject.match(/^CN=(.*)$/m); // [0] Matching string; [1] capture group - if (matches?.length !== 2) { - throw new Error(`Unable to identify client identity common name: ${clientCert.subject}`); - } - - return matches[1]; -} - -function ownerIdentifier(user: string, org: string): OwnerIdentifier { - return { org, user }; -} - -async function setEndorsingOrgs(ctx: Context, ledgerKey: string, ...orgs: string[]): Promise { - const policy = newMemberPolicy(...orgs); - await ctx.stub.setStateValidationParameter(ledgerKey, policy.getPolicy()); -} - -function newMemberPolicy(...orgs: string[]): KeyEndorsementPolicy { - const policy = new KeyEndorsementPolicy(); - policy.addOrgs('MEMBER', ...orgs); - return policy; -} diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/src/index.ts b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/src/index.ts deleted file mode 100644 index 06f92f05..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/src/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -import { AssetTransferContract } from './assetTransfer'; - -export { AssetTransferContract } from './assetTransfer'; - -export const contracts: any[] = [AssetTransferContract]; // eslint-disable-line @typescript-eslint/no-explicit-any diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/src/untyped.d.ts b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/src/untyped.d.ts deleted file mode 100644 index 4c2910bb..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/src/untyped.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -declare module 'json-stringify-deterministic' { - interface Options { - space?: string; - cycles?: boolean; - replacer?: (k, v) => v; - stringify?: typeof JSON.stringify; - } - - export default function stringify(o: unknown, options?: Options): string; -} diff --git a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/tsconfig.json b/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/tsconfig.json deleted file mode 100644 index 031d7de7..00000000 --- a/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@tsconfig/node18/tsconfig.json", - "compilerOptions": { - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "outDir": "dist", - "strict": true, - "noUnusedLocals": true, - "noImplicitReturns": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["src/"] -} diff --git a/full-stack-asset-transfer-guide/docs/ApplicationDev/01-FabricGateway.md b/full-stack-asset-transfer-guide/docs/ApplicationDev/01-FabricGateway.md deleted file mode 100644 index 8ad2273e..00000000 --- a/full-stack-asset-transfer-guide/docs/ApplicationDev/01-FabricGateway.md +++ /dev/null @@ -1,76 +0,0 @@ -# Fabric Gateway - -From Fabric v2.4 onwards, the [Fabric Gateway client API](https://hyperledger.github.io/fabric-gateway/) is the recommended API for building client applications. There are implementations in Go, Node (TypeScript / JavaScript) and Java, each providing identical capability and behavior. The client API makes use of a Fabric Gateway service embedded within Fabric v2.4+ peers. This topic describes the Fabric Gateway model and considerations for production deployment. - -The concepts described here map directly to methods provided by the client API, and will help you to understand the client API behavior. Provided you have a clear understanding of the Fabric transaction flow, you can treat this topic as reference material. - -## Background - -To understand how Fabric Gateway works, it is necessary to understand the Fabric transaction submit (and evaluate) flow. This section provides a brief recap of the Fabric transaction flow from the perspective of the client. - -### Transaction submit flow - -Submit represents a ledger update. In the following diagram, solid orange lines represent interactions between the client and network nodes, while dashed green lines represent interactions between network nodes. - -![Transaction submit flow](../images/ApplicationDev/transaction-submit-flow.png) - -1. **Endorse:** client sends transaction proposal to peers for endorsement. - - The peer executes the smart contract's transaction function against its *current* ledger state to produce a read/write set and a return value for the transaction. - - Successful endorsments must be gathered from sufficient organizations to meet the endorsement requirements, which may need to consider chaincode and state-based endorsement policies, chaincode-to-chaincode calls, and private data collections accessed by the transaction function; otherwise the transaction will fail *validation* later in the flow. -1. **Submit:** client sends endorsed transaction to an orderer to be committed into a block. -1. Orderers distribute committed blocks to all network peers, which validate the transactions against their *current* ledger state. - - Valid transactions have their read/write sets applied to update the ledger. - - Invalid transactions are marked with an appropriate validation code and do not update the ledger. - - A common reason for validation failure is MVCC_READ_CONFLICT, which means that the ledger keys accessed by the transaction were modified between endorsement and validation. This is recoverable by running the submit flow again. -1. **Commit:** client retrieves commit status for submitted transactions from peers and reports success or failure for the transaction submit depending on the transaction validation code. - -### Transaction evaluate flow - -Evaluate represents a query and is essentially just the *endorse* step of the transaction submit flow. - -1. **Evaluate:** client sends a transaction proposal to a suitable peer for endorsement and obtains a return value. - - The return value is based on the endorsing peer's *current* ledger state. - - Endorsement policies do not need to be satisfied since the transaction is not submitted to update the ledger. - - Access to private data collections needs to be considered when selecting peers. - -## Legacy client SDKs - -The following diagram demonstrates how the transaction submit flow is executed for a client using one of the legacy SDKs. Solid orange lines represent interactions between the client and network nodes, which must cross the firewall at the boundary of the network deployment. Dashed green lines represent interactions between network nodes. - -Notice that the client potentially needs to interact directly with any or all of the network nodes. - -![Legacy SDK model](../images/ApplicationDev/legacy-sdk-model.png) - -In order for the client application to operate effectively, it must make use of the discovery service provided by network peers. This requires additional network interactions beyond the ones shown in the transaction submit flow to: - -- Identify available network nodes. -- Obtain an endorsement plan based on client-supplied endorsement requirements. - -## Fabric Gateway client API - -The following diagram demonstrates for the transaction subsmit flow is executed for a client using the Fabric Gateway client API. Solid orange lines represent interactions between the client and a Gateway peer, which must cross the firewall at the boundary of the network deployment. Dashed green lines represent interactions between network nodes. - -Notice that the client only needs to interact directly with the Gateway peer. The Gateway peer operates as a client driving the transaction submit flow from within the network deployment on behalf of the client application. - -![Fabric Gateway model](../images/ApplicationDev/fabric-gateway-model.png) - - Since the Gateway is itself a peer, it has direct access to its ledger and service discovery information. This allows the client to avoid using the discovery service and to transact using only a single Gateway endpoint address. The Gateway peer is generally able to determine an appropriate endorsement plan automatically, avoiding the need for the client to have knowledge of endorsement requirements. - - For reference, a more detailed description of the Fabric Gateway service and its behavior can be found in the [Fabric documentation](https://hyperledger-fabric.readthedocs.io/en/release-2.4/gateway.html). - -## Production deployment of Fabric Gateway - -For security, client applications should connect only to Gateway peers within their own organization or, if the client's organization does not host their own peers, to Gateway peers of a trusted organization. - -The following diagram demonstrates recommended practice for enabling access to an organization cluster through a single endpoint address while maintaining high availability. This use of a load balancer or ingress controller as a proxy in front of a set of internal endpoints is commonly used when deploying Web or Application servers, so this pattern is well established. The gRPC communication between client and Gateway actually uses HTTP/2 as its transport. - -![Fabric Gateway deployment](../images/ApplicationDev/fabric-gateway-deployment.png) - -An alternative (or complementary) approach that can be employed is to assign multiple records for a single Gateway DNS name. This allows clients to select from a set of Gateway peer IP addresses associated with a single Gateway endpoint. - -Note that peers must include the externally visible endpoint address in their TLS certificates for clients to successfully complete a TLS handshake. - -For reference, more information is available in the gRPC documentation: - -- [gRPC load balancing](https://grpc.io/blog/grpc-load-balancing/). -- [gRPC name resolution](https://grpc.github.io/grpc/core/md_doc_naming.html). diff --git a/full-stack-asset-transfer-guide/docs/ApplicationDev/02-Exercise-RunApplication.md b/full-stack-asset-transfer-guide/docs/ApplicationDev/02-Exercise-RunApplication.md deleted file mode 100644 index 2f148803..00000000 --- a/full-stack-asset-transfer-guide/docs/ApplicationDev/02-Exercise-RunApplication.md +++ /dev/null @@ -1,43 +0,0 @@ -# Exercise: Run the client application - -> **Note:** This exercise requires the Fabric network and chaincode deployed in the [Smart Contract Development](../SmartContractDev/) exercises to be running. - -Let's make sure we can successfully run the client application and get some familiarity with how to use it. - -In a terminal window, navigate to the [applications/trader-typescript](../../applications/trader-typescript/) directory. Then complete the following steps: - -1. Install dependencies and build the client application. - ```bash - npm install - ``` - -1. Set environment variables to point to resources required by the application. - ```bash - export ENDPOINT=org1peer-api.127-0-0-1.nip.io:8080 - export MSP_ID=org1MSP - export CERTIFICATE=../../_cfg/uf/_msp/org1/org1admin/msp/signcerts/cert.pem - export PRIVATE_KEY=../../_cfg/uf/_msp/org1/org1admin/msp/keystore/cert_sk - ``` - -1. Run the **getAllAssets** command to check the assets that currently exist on the ledger (if any). - ```bash - npm start getAllAssets - ``` - -1. Run the **transact** command to create (and update / delete) some more sample assets. - ```bash - npm start transact - ``` - -1. Run the **getAllAssets** command again to see the new assets recorded on the ledger. - ```bash - npm start getAllAssets - ``` - -These application CLI commands represent a simplified application that performs one action per call. Note that real world applications will typically be long running and will make calls to a contract on behalf of user requests. - -## Optional steps - -Try using the **create**, **read** and **delete** commands to work with specific assets. - -See the application [Readme](../../applications/trader-typescript/README.md) for details on how to use the commands. diff --git a/full-stack-asset-transfer-guide/docs/ApplicationDev/03-ApplicationOverview.md b/full-stack-asset-transfer-guide/docs/ApplicationDev/03-ApplicationOverview.md deleted file mode 100644 index f827e892..00000000 --- a/full-stack-asset-transfer-guide/docs/ApplicationDev/03-ApplicationOverview.md +++ /dev/null @@ -1,132 +0,0 @@ -# Application overview - -This topic describes key parts of the client application and how it uses the Fabric Gateway client API to interact with the network. This knowledge will allow you to extend the application in subsequent topics. - -## Connect to the Gateway service - -Connection to the peer Gateway service is driven by the **runCommand()** function in [app.ts](../../applications/trader-typescript/src/app.ts). This calls to two other functions to perform the two tasks required before the client application can transact with the Fabric network: - -1. **Create gRPC connection to peer Gateway endpoint** - this is done in the **newGrpcConnection()** function in [connect.ts](../../applications/trader-typescript/src/connect.ts): - ```typescript - const tlsCredentials = grpc.credentials.createSsl(tlsRootCert); - return new grpc.Client(GATEWAY_ENDPOINT, tlsCredentials); - ``` - The gRPC client connection is established using the [gRPC API](https://grpc.io/docs/) and is managed by the client application. The application can use the same gRPC connection to transact on behalf of many client identities. - -1. **Create peer Gateway connection** - this is done in the **newGatewayConnection()** function in [connect.ts](../../applications/trader-typescript/src/connect.ts): - ```typescript - return connect({ - client, - identity: await newIdentity(), - signer: await newSigner(), - // Default timeouts for different gRPC calls - evaluateOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - endorseOptions: () => { - return { deadline: Date.now() + 15000 }; // 15 seconds - }, - submitOptions: () => { - return { deadline: Date.now() + 5000 }; // 5 seconds - }, - commitStatusOptions: () => { - return { deadline: Date.now() + 60000 }; // 1 minute - }, - }); - ``` - The **Gateway** connection is established by calling the [connect()](https://hyperledger.github.io/fabric-gateway/main/api/node/functions/connect.html) factory function with a client [identity](https://hyperledger.github.io/fabric-gateway/main/api/node/interfaces/Identity.html) (user's X.509 certificate) and [signing implementation](https://hyperledger.github.io/fabric-gateway/main/api/node/functions/signers.newPrivateKeySigner.html) (based on the user's private key). It allows a specific user to interact with a Fabric network using the previously created gRPC connection. Optional configuration can also be supplied, and it is strongly recommended to include default timeouts for operations. - -## Application CLI commands - -All the CLI command implementations are located within the [commands](../../applications/trader-typescript/src/commands/) directory. Commands are exposed to [app.ts](../../applications/trader-typescript/src/app.ts) by [commands/index.ts](../../applications/trader-typescript/src/commands/index.ts). - -When invoked, the command is passed the **Gateway** instance it should use to interact with the Fabric network. To do useful work, command implementations typically performs these steps: - -1. **Get Network** - this represents a network of Fabric nodes belonging to a specific Fabric channel: - ```typescript - const network = gateway.getNetwork(CHANNEL_NAME); - ``` - -1. **Get Contract** - this represents a specific smart contract deployed in the **Network**: - ```typescript - const contract = network.getContract(CHAINCODE_NAME); - ``` - -1. **Create smart contract adapter** - this provides a view of the smart contract and its transaction functions in form that is easy to use for the client application business logic: - ```typescript - const smartContract = new AssetTransfer(contract); - ``` - -1. **Invoke transaction functions on a deployed chaincode** - for example: - - Create an asset in [commands/create.ts](../../applications/trader-typescript/src/commands/create.ts) - ```typescript - await smartContract.createAsset({ - ID: assetId, - Owner: owner, - Color: color, - Size: 1, - AppraisedValue: 1, - }); - ``` - - Read all assets in [commands/getAllAssets.ts](../../applications/trader-typescript/src/commands/getAllAssets.ts) - ```typescript - const assets = await smartContract.getAllAssets(); - ``` - -The application CLI commands represent a simplified application that performs one action per call. Note that real world applications will typically be long running, and will re-use a connection to the peer Gateway service when making transaction requests on behalf of client applications. The connection may utilize a single organization identity on behalf of various user requests. - -## Gateway API calls - -The **AssetTransfer** class in [contract.ts](../../applications/trader-typescript/src/contract.ts) presents the smart contract in a form appropriate to the business application. Internally it uses the Fabric Gateway client API to invoke transaction functions, and deals with the translation between the business application and API representation of parameters and return values. - -Refer to the [Contract API documentation](https://hyperledger.github.io/fabric-gateway/main/api/node/interfaces/Contract.html) for more details on the available calls. - -### Transaction submit - -The transaction submit function will submit the request to the peer Gateway service. The peer Gateway service will invoke chaincode and collect the required endorsements from different organization's peers to meet the contract's endorsement policy, and will then submit the transaction to the ordering service on behalf of the client application so that the blockchain ledger can be updated. - -An example of transaction submit is in the **createAsset()** method: - -```typescript -await this.#contract.submit('CreateAsset', { - arguments: [JSON.stringify(asset)], -}); -``` - -### Transaction evaluate - -The transaction evaluate function will request the peer Gateway service to invoke the chaincode and return the results to the client, without submitting a transaction to the ordering service. Use the evaluate function to query the state of the blockchain ledger. - -An example of evaluating a transaction is in the **getAllAssets()** method: -```typescript -const result = await this.#contract.evaluate('GetAllAssets'); -``` - -## Retry of transaction submit - -The nature of the transaction submit flow in Fabric means that failures can occur at different points in the flow. To aid client handling of failures, the Gateway API produces errors of specific types to indicate the point in the flow a failure occurred. The **submitWithRetry()** function in [contract.ts](../../applications/trader-typescript/src/contract.ts) retries transactions that fail to commit successfully: - -```typescript -let lastError: unknown | undefined; - -for (let retryCount = 0; retryCount < RETRIES; retryCount++) { - try { - return await submit(); - } catch (err: unknown) { - lastError = err; - if (err instanceof CommitError) { - // Transaction failed validation and did not update the ledger. Handle specific transaction validation codes. - if (err.code === StatusCode.MVCC_READ_CONFLICT) { - continue; // Retry - } - } - break; // Failure -- don't retry - } -} - -throw lastError; -``` - -See the [submit() API documentation](https://hyperledger.github.io/fabric-gateway/main/api/node/interfaces/Contract.html#submit) for the other error types that can be thrown. - -For some cases it can be useful to retry only a specific step within the transaction submit flow. The Gateway API provides a fine-grained flow to allow this. See the [Contract API documentation](https://hyperledger.github.io/fabric-gateway/main/api/node/interfaces/Contract.html) for examples of this fine-grained flow. diff --git a/full-stack-asset-transfer-guide/docs/ApplicationDev/04-Exercise-AssetTransfer.md b/full-stack-asset-transfer-guide/docs/ApplicationDev/04-Exercise-AssetTransfer.md deleted file mode 100644 index 00b6beb1..00000000 --- a/full-stack-asset-transfer-guide/docs/ApplicationDev/04-Exercise-AssetTransfer.md +++ /dev/null @@ -1,31 +0,0 @@ -# Exercise: Implement asset transfer - -Currently, our trader application can only create, read, and delete assets by invoking the CreateAsset(), ReadAsset(), and DeleteAsset() chaincode functions. To really be useful it needs to be able to transfer assets to new owners by invoking the TransferAsset() chaincode function. - -There is already a **transfer** command implemented in [transfer.ts](../../applications/trader-typescript/src/commands/transfer.ts), which calls the `transferAsset()` method on our **AssetTransfer** class. Unfortunately, this has not yet been implemented and does nothing. - -1. Write an implementation for the `transferAsset()` method in [contract.ts](../../applications/trader-typescript/src/contract.ts). Look at the [API documentation for Contract](https://hyperledger.github.io/fabric-gateway/main/api/node/interfaces/Contract.html) and other methods within the **AssetTransfer** class for ideas on how to proceed. - -1. Recompile the application from your updated TypeScript: - ```bash - npm install - ``` - > **Tip:** You can also leave `npm run build:watch` running in a terminal window to automatically rebuild your application on any code change. - -1. If you are using a new terminal window, set environment variables to point to resources required by the application. - ```bash - export ENDPOINT=org1peer-api.127-0-0-1.nip.io:8080 - export MSP_ID=org1MSP - export CERTIFICATE=../../_cfg/uf/_msp/org1/org1admin/msp/signcerts/cert.pem - export PRIVATE_KEY=../../_cfg/uf/_msp/org1/org1admin/msp/keystore/cert_sk - ``` - -1. Try it out! Use the **transfer** command to transfer assets to new owners with the same MSP ID. - -1. What happens if you try to manipulate (transfer, delete) an asset after transferring it to another MSP ID? - -The smart contract contains logic that only allows users in the owning organization to modify assets. It does this by checking that the Member Services Provider (MSP) ID for the client identity invoking the transaction matches the organization MSP ID of the asset owner. If you didn't notice this before, you might want to check out the smart contract code to see how this is implemented. - -## Optional steps - -Implement an **update** command in the client application to modify the properties of an asset. diff --git a/full-stack-asset-transfer-guide/docs/ApplicationDev/05-ChaincodeEvents.md b/full-stack-asset-transfer-guide/docs/ApplicationDev/05-ChaincodeEvents.md deleted file mode 100644 index 56ee296b..00000000 --- a/full-stack-asset-transfer-guide/docs/ApplicationDev/05-ChaincodeEvents.md +++ /dev/null @@ -1,20 +0,0 @@ -# Chaincode events - -A smart contract transaction function can emit a chaincode event to communicate business events. These events are emitted only after a transaction is successfully committed and updates the ledger. Transactions that fail validation do not emit chaincode events. - -Client applications can listen for chaincode events and trigger external business processes in response to ledger updates. An example might be to schedule collection of a parcel after a delivery order is received. Events can either be replayed from any point in the blockchain, or received in realtime. - -When emitting a chaincode event, the smart contract can specify an arbitrary **payload** to be included in the event. The **payload** is used to communicate business context to client applications receiving the chaincode events. - -The [Network](https://hyperledger.github.io/fabric-gateway/main/api/node/interfaces/Network.html) object in the Gateway API provides methods to obtain chaincode events. - -To ensure the correct operation of business processes, it is important that each chaincode event is received exactly once. We don't want to collect the same parcel twice, or to miss a parcel collection! - -The Gateway API allows a [Checkpointer](https://hyperledger.github.io/fabric-gateway/main/api/node/interfaces/Checkpointer.html) to be used to track (or checkpoint) successfully processed events, and for eventing to be resumed exactly after the last checkpointed event if a failure or application restart occurs. - -For convenience, the Gateway API provides two checkpointer implementations: - -1. [File checkpointer](https://hyperledger.github.io/fabric-gateway/main/api/node/functions/checkpointers.file.html) that persists its state to the file-system. This can be used to resume eventing, even after an application restart. -1. [In-memory checkpointer](https://hyperledger.github.io/fabric-gateway/main/api/node/functions/checkpointers.inMemory.html) that stores its state only in-memory. This can be used to recover from transient failures, such as a network communication error, during a single application run. - -Client applications can also use their own checkpointer implementations, which persist their state in suitable storage such as a database, provided they conform to the simple [Checkpoint](https://hyperledger.github.io/fabric-gateway/main/api/node/interfaces/Checkpoint.html) interface. diff --git a/full-stack-asset-transfer-guide/docs/ApplicationDev/06-Exercise-ChaincodeEvents.md b/full-stack-asset-transfer-guide/docs/ApplicationDev/06-Exercise-ChaincodeEvents.md deleted file mode 100644 index 9140e6f8..00000000 --- a/full-stack-asset-transfer-guide/docs/ApplicationDev/06-Exercise-ChaincodeEvents.md +++ /dev/null @@ -1,46 +0,0 @@ -# Exercise: Use chaincode events - -First, let's try listening for chaincode events to see what information is included in events emitted by the smart contract transaction functions. - -In a new terminal window, navigate to the [applications/trader-typescript](../../applications/trader-typescript/) directory so that we can run the listen application. -It is assumed that you have already built the application in prior steps. - -1. If you are using a new terminal window, set environment variables to point to resources required by the application. - ```bash - export ENDPOINT=org1peer-api.127-0-0-1.nip.io:8080 - export MSP_ID=org1MSP - export CERTIFICATE=../../_cfg/uf/_msp/org1/org1admin/msp/signcerts/cert.pem - export PRIVATE_KEY=../../_cfg/uf/_msp/org1/org1admin/msp/keystore/cert_sk - ``` - -1. Run the **listen** command to listen for ledger updates. The listen command will return prior events and also wait for future events. - ```bash - npm start listen - ``` - -1. Once you have received the available events, interrupt the application using `Control-C`. - -1. Run the **listen** command again. What do we see this time? - -On the second run of the **listen** command, you should have seen exactly the same output as the first run. This is because each run of the **listen** command retrieves all chaincode events from start of the blockchain. That's not so useful if we want to invoke external business processes in response to chaincode events. It would be much better if each event was received exactly once, regardless of whether the client application is restarted. - -Let's implement checkpointing to ensure there are no duplicate or missed events. - -5. Implement checkpointing for the reading of chaincode events in [listen.ts](../../applications/trader-typescript/src/commands/listen.ts). Look at the [API documentation for Network](https://hyperledger.github.io/fabric-gateway/main/api/node/interfaces/Network.html) for ideas on how to proceed. Be sure to only checkpoint events *after* they are successfully processed! - -1. Ensure your changes are compiled, then run the **listen** command with the SIMULATED_FAILURE_COUNT environment variable set to simulate an application error during the processing of a chancode event: - ```bash - SIMULATED_FAILURE_COUNT=3 npm start listen - ``` - -1. Run the **listen** command again. You should see event listening resume from the same chaincode event that the application failed to process on the previous run. - -> **Note:** The checkpointer persists its current listening position in a `checkpoint.json` file. If you want to remove the checkpointer's stored state and start listening from the `startBlock` again, remove the `checkpoint.json` file while the checkpointer is not in use. - -## Optional steps - -So far we have been replaying previously emitted chaincode events. Let's use the **listen** command to notify us in realtime when we take ownership of assets. - -8. Modify the **onEvent()** function in [listen.ts](../../applications/trader-typescript/src/commands/listen.ts) to notify you if you become the owner of a new (`CreateAsset` event) or transferred (`TransferAsset` event) asset. Note that the `payload` property of the event is a [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) containing the [JSON](https://en.wikipedia.org/wiki/JSON) emitted by the smart contract. Look at the **readAsset()** method in [contract.ts](../../applications/trader-typescript/src/contract.ts) for ideas on how to convert this into a JavaScript object so you can inspect its `Owner` property. - -1. Try running the **listen** command in one terminal window while using another terminal window to create and transfer assets. diff --git a/full-stack-asset-transfer-guide/docs/ApplicationDev/README.md b/full-stack-asset-transfer-guide/docs/ApplicationDev/README.md deleted file mode 100644 index 12a719c7..00000000 --- a/full-stack-asset-transfer-guide/docs/ApplicationDev/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Client Application Development - -This session consists of the following topics to be covered in order: - -1. [Fabric Gateway](01-FabricGateway.md) - overview of the Fabric Gateway service used by client applications to interact with the Fabric network. -1. **Exercise:** [Run the client application](02-Exercise-RunApplication.md) - run the Trader sample application. -1. [Application overview](03-ApplicationOverview.md) - description of key parts of the application. -1. **Exercise:** [Implement asset transfer](04-Exercise-AssetTransfer.md) - enhance the client application to allow the transfer of assets. -1. [Chaincode events](05-ChaincodeEvents.md) - overview of chaincode events and their use. -1. **Exercise:** [Use chaincode events](06-Exercise-ChaincodeEvents.md) - listen for chaincode events and use them to implement notifications. diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/00-setup-zh.md b/full-stack-asset-transfer-guide/docs/CloudReady/00-setup-zh.md deleted file mode 100644 index 60302c4f..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/00-setup-zh.md +++ /dev/null @@ -1,92 +0,0 @@ -# 云原生 - -==> [下一步: 部署一个kube集群](./10-kube-zh.md) - ---- - -Hyperledger Fabric的云原生支持一个Hyperledger Fabric中立的分层透视图,其中集成了容器,服务,和API。在这个workshop的这部分例子中,您将会完整的运行应用并且可以尝试从本地开发环境部署到公有云环境中。 - -![Cloud Ready](../images/CloudReady/00-cloud-ready-2.png) - -云原生结构堆栈中的每个应用程序层通常都是模块化的,只需对在不同环境之间切换。在每个应用程序层,客户端库和连接URL用于确保跨运行时堆栈的可移植性和独立性。 - -例如: -- Hyperledger Fabric peer,orderer和CA节点之间的交互都通过编译后的可执行文件,交互通过TCP和GRPCs的方式。一旦Hyperledger Fabric网络被建立,所有的管理员和账本访问将通过服务的方式进行。因此对外Hyperledger Fabric网络仅仅暴露服务地址和x509证书。 - -- 所有和容器的交互都通过k8s API完成,在后续的练习中您将会使用`kubectl`命令从宿主机(本机)访问并连接容器。请注意,这种方式并不局限在本地,您也可以通过合适的配置来访问您的远程集群。 - -- 一些必要的虚拟化技术对本实验有所帮助。您可能需要通过multipass/vagrant或远程虚拟机来执行这个实验。详细信息请参考原文: -In some cases a virtualization layer is necessary to emulate the cloud-native practices. For instance, a VM running - locally with multipass/vagrant (or a remote instance at EC2) can be used to supplement a local development workflow. - This can be extremely useful as a means to build platform-neutral runtimes, supporting a variety of chipsets and - development environments (WSL2, Mac M1, z/OS, amd64, etc.) - -在使用一个 _Cloud Native Fabric_ 堆栈时,您会感到非常困惑。当你是感觉迷失了,专注于上面的分层堆栈,帮助重新定位自己,找到指南针方位,然后继续前进。 -通常,每个应用程序层都被设计为仅与堆栈中其下的直接层一起工作。 - -在本次的云部署之旅中,您也许需要牢记一些知识点(下列知识点涉及部分专有词汇,为防止误解,不做翻译): -1. Services are backed by URLs. (It does not matter _where_ the endpoints are running, only how you _locate_ them.) - -2. Services run in [OCI Containers](https://github.com/opencontainers/image-spec) and are orchestrated by Kubernetes. - -3. All client programs run on your machine, connecting to service endpoints "running somewhere" on a hybrid cloud. - -4. At some point in this course, you may encounter a chaincode contract running in a Java Virtual Machine, running in a - docker container, executing as a service running on Kubernetes, which is running in a Docker container, which - is running on a virtual machine, which is running on an x86 emulation layer, which is running on hyperkit, which is - running on Mac M1 silicon on your laptop. At many times, you will forget _where_ your code is running, and question - if it is in fact running at all. Do not be alarmed: this is a natural reaction to container based application - workflows. (See points 1, 2, and 3 above.) - - -## 让我们开始吧 -运行一下程序来检查我们需要的工具是否安装完毕 -```shell -# If the check passes, proceed to "Deploy a Kube": -./check.sh -``` - - -## 需要安装工具: -我们需要一些客户端程序来完成这个实验。 -您可以使用`./check.sh`来进行检查和查看,或者通过网页的方式: -- [fabric-samples](https://github.com/hyperledger/fabric-samples) (This GitHub project): -```shell -git clone https://github.com/hyperledger/fabric-samples.git fabric-samples -cd fabric-samples/full-stack-asset-transfer-guide -``` - -- [docker](https://www.docker.com/get-started/) - -- [kubectl](https://kubernetes.io/docs/tasks/tools/) - -- [jq](https://stedolan.github.io/jq/download/) - -- [k9s](https://k9scli.io/topics/install/) (recommended) - -- Hyperledger Fabric [客户端](https://hyperledger-fabric.readthedocs.io/en/latest/install.html#download-fabric-samples-docker-images-and-binaries): -```shell -curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary - -``` - -- 本实验需要的环境变量: -```shell - -export WORKSHOP_PATH=$(pwd) -export FABRIC_CFG_PATH=${WORKSHOP_PATH}/config -export PATH=${WORKSHOP_PATH}/bin:$PATH - -``` - -## 如果还有问题,请参考下列原文 - -For the duration of the workshop, a number of temporary, short-run virtual machines will be available on the web for -your usage. The systems have been provisioned with a [#cloud-config](../../infrastructure/ec2-cloud-config.yaml) and -include all dependencies necessary to run the cloud-native workshop. Check your "Conga Card" for the instance IP and -ssh connection details. - - ---- - -==> [下一步: 部署一个kube集群](./10-kube.md) diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/00-setup.md b/full-stack-asset-transfer-guide/docs/CloudReady/00-setup.md deleted file mode 100644 index 93c98441..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/00-setup.md +++ /dev/null @@ -1,112 +0,0 @@ -# Cloud Ready! - -==> [NEXT: Deploy a Kube](./10-kube.md) - ---- - -Cloud Native Hyperledger Fabric provides a neutral, tiered perspective of a Hyperledger Fabric Network as an integration of -containers, service endpoints, and API abstractions. In this module of the workshop, you will assemble a complete -application, building up from a local development running in isolation to a complete blockchain application running -natively on a public cloud. - -![Cloud Ready](../images/CloudReady/00-cloud-ready-2.png) - - -Each _application tier_ in the cloud native fabric stack is generally _modular_, and carries over with minimal change to -switch between different environments. At each _application tier_, client libraries and connection URLs are used to -ensure portability and independence across runtime stacks. - -For instance: - -- All interaction with Fabric peers, orderers, and CAs is performed with native binaries, communicating natively via - TCP and gRPCs. After the Fabric network has been established, all administrative and ledger access - (channel creation, user enrollment, chaincode installation, Gateway Client connections, etc.) occurs via service URL. - From the integration tier, a Fabric network is just "running somewhere" and expressed as a set of service URLs and - x509 certificates. - -- All interaction with the container orchestrator is performed directly via access to the Kubernetes API controller. In - several scenarios in the workshop, you will issue `kubectl` commands from a local system after configuring the client - to connect to a cluster "running somewhere." Note that this approach does not distinguish between a k8s cluster - running locally on the laptop, embedded on a Virtual Machine, or a fully cloud-native vendor such as AKS, EKS, or IKS. - -- In some cases a virtualization layer is necessary to emulate the cloud-native practices. For instance, a VM running - locally with multipass/vagrant (or a remote instance at EC2) can be used to supplement a local development workflow. - This can be extremely useful as a means to build platform-neutral runtimes, supporting a variety of chipsets and - development environments (WSL2, Mac M1, z/OS, amd64, etc.) - - -At some point when working with a _Cloud Native Fabric_ stack, you will feel _mildly disoriented_. When you are -_feeling lost_, focus on the tiered stack above to help re-orient yourself, find a compass bearing, and move forward. -In general, each application tier is designed to work only with the immediate layer beneath it in the stack. - -Here are some key points to keep in mind to help stay "grounded" on your voyage to the cloud: - -1. Services are backed by URLs. (It does not matter _where_ the endpoints are running, only how you _locate_ them.) - -2. Services run in [OCI Containers](https://github.com/opencontainers/image-spec) and are orchestrated by Kubernetes. - -3. All client programs run on your machine, connecting to service endpoints "running somewhere" on a hybrid cloud. - -4. At some point in this course, you may encounter a chaincode contract running in a Java Virtual Machine, running in a - docker container, executing as a service running on Kubernetes, which is running in a Docker container, which - is running on a virtual machine, which is running on an x86 emulation layer, which is running on hyperkit, which is - running on Mac M1 silicon on your laptop. At many times, you will forget _where_ your code is running, and question - if it is in fact running at all. Do not be alarmed: this is a natural reaction to container based application - workflows. (See points 1, 2, and 3 above.) - - -## Ready? - -```shell -# If the check passes, proceed to "Deploy a Kube": -./check.sh -``` - - -## Not Ready? - -To run the cloud workshop, a number of client applications are necessary to interact with the Fabric application tiers. - -Install the workshop prerequisites with instructions from running `./check.sh`, or see detailed guides from the web: - -- [fabric-samples](https://github.com/hyperledger/fabric-samples) (This GitHub project): -```shell -git clone https://github.com/hyperledger/fabric-samples.git fabric-samples -cd fabric-samples/full-stack-asset-transfer-guide -``` - -- [docker](https://www.docker.com/get-started/) - -- [kubectl](https://kubernetes.io/docs/tasks/tools/) - -- [jq](https://stedolan.github.io/jq/download/) - -- [k9s](https://k9scli.io/topics/install/) (recommended) - -- Hyperledger Fabric [client binaries](https://hyperledger-fabric.readthedocs.io/en/latest/install.html#download-fabric-samples-docker-images-and-binaries): -```shell - -curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary - -``` - -- Workshop environment variables: -```shell - -export WORKSHOP_PATH=$(pwd) -export FABRIC_CFG_PATH=${WORKSHOP_PATH}/config -export PATH=${WORKSHOP_PATH}/bin:$PATH - -``` - -## Still not Ready? - -For the duration of the workshop, a number of temporary, short-run virtual machines will be available on the web for -your usage. The systems have been provisioned with a [#cloud-config](../../infrastructure/ec2-cloud-config.yaml) and -include all dependencies necessary to run the cloud-native workshop. Check your "Conga Card" for the instance IP and -ssh connection details. - - ---- - -==> [NEXT: Deploy a Kube](./10-kube.md) diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/10-kube-zh.md b/full-stack-asset-transfer-guide/docs/CloudReady/10-kube-zh.md deleted file mode 100644 index f9815463..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/10-kube-zh.md +++ /dev/null @@ -1,67 +0,0 @@ -# 部署一个k8s集群 - -[上一步: 设置](00-setup-zh.md) <==> [下一步: 部署一个fabric网络](20-fabric-zh.md) - ---- - -Fabric云原生部署,所有的组件直接在工作站上运行,在这个步骤中,您将会配置: -- 一个本地[kind](https://kind.sigs.k8s.io) 集群,来运行k8s. - -- 一个本地[Ingress controller](https://github.com/kubernetes/ingress-nginx), 将k8s集群的路由设置到 `*.localho.st` 这个虚拟域名上. - -- 一个本地[Container Registry](https://docs.docker.com/registry/insecure/), 允许您上传智能合约的docker镜像。 - -![Local KIND](../images/CloudReady/10-kube.png) - - -## 执行: - -```shell - -just check-setup - -``` - -## Kubernetes IN Docker (KIND) - -- 配置 `localho.st` DNS路由 - mapping `*.localho.st` to 127.0.0.1. -```shell - -export WORKSHOP_INGRESS_DOMAIN=localho.st -export WORKSHOP_NAMESPACE=test-network - -``` - -- 创建[kind](https://kind.sigs.k8s.io) 集群, Nginx ingress, 和本地 container registry: -```shell - -just kind - -``` - -- 在新的terminal中执行如下命令来确认: -```shell - -# KIND will set the current kubectl context in ~/.kube/config -kubectl cluster-info - -k9s -n test-network - -``` - - -## 调试 - -- Run KIND on a [multipass VM](11-kube-multipass.md) on your local system -- Run KIND on an [EC2 instance](12-kube-ec2-vm.md) at AWS - - -## 进一步拓展: - -- Run the workshop on an [IKS or EKS or DOKS Cloud Kubernetes cluster](13-kube-public-cloud.md). -- Run the workshop on an AWS VM, using your AWS account and an EC2 [#cloud-config](../../infrastructure/ec2-cloud-config.yaml). - ---- -[上一步: 设置](00-setup-zh.md) <==> [下一步: 部署一个fabric网络](20-fabric-zh.md) - diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/10-kube.md b/full-stack-asset-transfer-guide/docs/CloudReady/10-kube.md deleted file mode 100644 index d29d4b86..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/10-kube.md +++ /dev/null @@ -1,68 +0,0 @@ -# Deploy a Kubernetes Cluster - -[PREV: Setup](00-setup.md) <==> [NEXT: Deploy a Fabric Network](20-fabric.md) - ---- - -With cloud-native Fabric, all the components can run directly on your development workstation. In this exercise, you will configure: - -- A local [kind](https://kind.sigs.k8s.io) cluster, running Kubernetes in Docker. - -- A local [Ingress controller](https://github.com/kubernetes/ingress-nginx), routing traffic into the cluster at the `*.localho.st` virtual DNS domain. - -- A local [Container Registry](https://docs.docker.com/registry/insecure/), allowing you to upload chaincode Docker images to the cluster. - -![Local KIND](../images/CloudReady/10-kube.png) - - -## Ready? - -```shell - -just check-setup - -``` - -## Kubernetes IN Docker (KIND) - -- Set the cluster ingress domain and target k8s namespace. The `localho.st` domain is a public DNS wildcard resolver - mapping `*.localho.st` to 127.0.0.1. -```shell - -export WORKSHOP_INGRESS_DOMAIN=localho.st -export WORKSHOP_NAMESPACE=test-network - -``` - -- Create a [kind](https://kind.sigs.k8s.io) cluster, Nginx ingress, and local container registry: -```shell - -just kind - -``` - -- Open a new terminal window and observe the target namespace: -```shell - -# KIND will set the current kubectl context in ~/.kube/config -kubectl cluster-info - -k9s -n test-network - -``` - - -## Trouble? - -- Run KIND on a [multipass VM](11-kube-multipass.md) on your local system -- Run KIND on an [EC2 instance](12-kube-ec2-vm.md) at AWS - - -## Take it Further: - -- Run the workshop on an [IKS or EKS or DOKS Cloud Kubernetes cluster](13-kube-public-cloud.md). -- Run the workshop on an AWS VM, using your AWS account and an EC2 [#cloud-config](../../infrastructure/ec2-cloud-config.yaml). - ---- -[PREV: Setup](00-setup.md) <==> [NEXT: Deploy a Fabric Network](20-fabric.md) - diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/11-kube-multipass.md b/full-stack-asset-transfer-guide/docs/CloudReady/11-kube-multipass.md deleted file mode 100644 index cc99e7e3..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/11-kube-multipass.md +++ /dev/null @@ -1,110 +0,0 @@ -# Deploy a Kubernetes Cluster - -[PREV: Setup](00-setup.md) <==> [NEXT: Deploy a Fabric Network](20-fabric.md) - ---- - -## Ready? - -```shell - -just check-setup - -``` - -**WINDOWS note**, please create the multipass VM with the command below from an elevated command prompt. Then proceed from logged into this VM with the [KIND instructions](./10-kube.md) - -## Provision a Multipass Virtual Machine - -```shell - -multipass launch \ - --name fabric-dev \ - --disk 80G \ - --cpus 8 \ - --mem 8G \ - --cloud-init infrastructure/multipass-cloud-config.yaml - -# todo: scp not volume mounts -multipass mount $PWD fabric-dev:/home/ubuntu/full-stack-asset-transfer-guide - -export WORKSHOP_IP=$(multipass info fabric-dev --format json | jq -r .info.\"fabric-dev\"."ipv4[0]") -export WORKSHOP_INGRESS_DOMAIN=$(echo $WORKSHOP_IP | tr -s '.' '-').nip.io - -echo "Multipass VM created with IP: $WORKSHOP_IP" -echo "WORKSHOP_DOMAIN=$WORKSHOP_INGRESS_DOMAIN" - -``` - - -## Start a KIND Cluster - -- Open a shell on the virtual machine: -```shell - -# todo ssh authorized_keys -> ubuntu@${WORKSHOP_IP} not multipass shell -multipass shell fabric-dev - -``` - -```shell - -cd ~/full-stack-asset-transfer-guide - -# Bind a docker container registry to the VM's external IP -export CONTAINER_REGISTRY_ADDRESS=0.0.0.0 -export CONTAINER_REGISTRY_PORT=5000 - -# Expose the Kube API controller on the VM's public interface -export KIND_API_SERVER_ADDRESS=$(hostname -I | cut -d ' ' -f 1) -export KIND_API_SERVER_PORT=8888 - -``` - -```shell - -# Create a Kubernetes cluster in Docker, configure an Nginx ingress, and docker container registry -just kind - -# KIND will set the current kube client context in ~/.kube/config -kubectl cluster-info - -# Copy the kube config to the host OS volume share: -# todo: scp not volume share -cp ~/.kube/config ~/full-stack-asset-transfer-guide/config/multipass-kube-config.yaml - -``` - -- Exit the multipass VM - -- From the host OS: -```shell - -# Connect the local kube client to the k8s API server running on the VM: -cp config/multipass-kube-config.yaml ~/.kube/config - -# Display kube client connection to k8s running on the VM: -kubectl cluster-info - -# Observe the target Kubernetes workspace: -k9s -n test-network - -``` - - -## Troubleshooting: - -- Run KIND on your [local system](10-kueb.md) -- Run KIND on an [EC2 instance](12-kube-ec2-vm.md) at AWS -- ssh to a workshop EC2 instance (see the login information on the back of your Conga Trading Card) - - -# Take it Further: - -- Run k8s directly on your laptop with [KIND](todo.md) (`export WORKSHOP_DOMAIN=localho.st`) -- Provision an EC2 instance on your AWS account with a [#cloud-config](../../infrastructure/ec2-cloud-config.yaml) -- Connect your kube client to a cloud k8s provider - - ---- -[PREV: Setup](00-setup.md) <==> [NEXT: Deploy a Fabric Network](20-fabric.md) diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/12-kube-ec2-vm.md b/full-stack-asset-transfer-guide/docs/CloudReady/12-kube-ec2-vm.md deleted file mode 100644 index 3964b5b1..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/12-kube-ec2-vm.md +++ /dev/null @@ -1,136 +0,0 @@ -# Deploy a Kubernetes Cluster - -[PREV: Setup](00-setup.md) <==> [NEXT: Deploy a Fabric Network](20-fabric.md) - ---- - -When working with a cloud native Fabric stack, it is possible to connect the client application binaries -(`kubectl`, `peer`, `node`, etc.) to a Kubernetes cluster running on a remote virtual machine. In this -scenario, you will provision a VM instance at EC2, install a KIND cluster on the VM, and forward a local -port to the remote API controller with SSH. This configuration can be extremely useful in scenarios -where the local system does not have sufficient resources to "run everything," or when a local development -is focused on client-application development and Fabric needs to "just run somewhere." - -This configuration is also an effective way to minimize usage costs associated with a "full Kubernetes" -deployment on cloud vendors, enabling a natural k8s development workflow on disposable, temporary VMs. - -![EC2 Virtual Machine](../images/CloudReady/12-kube-ec2-vm.png) - - -## Provision a Virtual Machine Instance at EC2 - -**Note:** If you are participating in the workshop, an EC2 VM will be made available to you for the duration of the -event. Check your Conga Card for connection details and IP address of the remote VM. - -To create a new EC2 instance with software dependencies pre-installed via [#cloud-init](../../infrastructure/ec2-cloud-config.yaml): - -- Log in to AWS -- Use `t2.xlarge` profile (4 CPU / 8 GRAM / 80 GB gp2) -- open ports 80 (nginx), 443 (nginx), and 5000 (container registry) -- copy/paste `infrastructure/ec2-cloud-config.yaml` as the instance user-data -- Create an ssh key pair for remote login. Save locally as `~/Downloads/ec2-key.pem` -- After the instance is up, identify the PUBLIC IPV4 address. This will be used extensively for all access to the cluster: - -If you are working with a pre-existing VM, connect to the remote system and add your ~/.ssh/id-rsa.pub key to -the ubuntu user's `.ssh/authorized_keys` file. In the examples below, omit the `-i ${EC2_INSTANCE_KEY}` command -arguments. - - -## SSH Port Forward to the k8s API Controller - -- Start a new shell on the host OS and input the instance public IPv4 address and ssh public key. -```shell - -# Set to your EC2 instance Public IPv4 address and SSH connection key. E.g.: -export EC2_INSTANCE_IP=203.0.113.42 -export EC2_INSTANCE_KEY=~/Downloads/ec2-key.pem - -``` - -- Open an [ssh port forward](https://help.ubuntu.com/community/SSH/OpenSSH/PortForwarding) and interactive shell on the - remote system. While this terminal is open, all traffic directed to the host OS port 8888 will be tunneled to the k8s - API controller running on the remote VM. This presents the illusion to kubectl that the cluster is running locally, - when in fact the k8s client is communicating with the remote instance running at AWS. -```shell - -ssh -i $EC2_INSTANCE_KEY -L 8888:127.0.0.1:8888 ubuntu@${EC2_INSTANCE_IP} - -``` - - -## Kubernetes IN Docker (KIND) - -- Clone the project source code and create a KIND cluster on the remote VM: -```shell - -git clone https://github.com/hyperledgendary/full-stack-asset-transfer-guide.git -cd full-stack-asset-transfer-guide - -# Bind a docker container registry to the VM's external IP -export CONTAINER_REGISTRY_ADDRESS=0.0.0.0 -export CONTAINER_REGISTRY_PORT=5000 - -# Create a Kubernetes cluster in Docker, configure an Nginx ingress, and docker container registry -just kind - -``` - -- Leave this terminal window open in the background and observe the target k8s namespace. When this ssh session - is terminated, the ssh port forward will be closed and the host OS will no longer be able to connect to the remote - kubernetes cluster. -```shell - -k9s -n test-network - -``` - - -## Connect kubectl to the Remote Cluster: - -In the original shell opened for the workshop on your local system: - -- Copy the kube config from the remote system to the local user account: -```shell - -scp -i $EC2_INSTANCE_KEY ubuntu@${EC2_INSTANCE_IP}:~/.kube/config ~/.kube/config - -``` - -- Test the connectivity to the remote cluster. -```shell -$ kubectl cluster-info -Kubernetes control plane is running at https://127.0.0.1:8888 -CoreDNS is running at https://127.0.0.1:8888/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy - -To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. -``` - - -## Network DNS Ingress Domain - -- Set the cluster ingress domain to an nip.io resolver. All virtual hosts in this domain will resolve to the nginx ingress. -```shell - -export WORKSHOP_INGRESS_DOMAIN=$(echo $EC2_INSTANCE_IP | cut -d ' ' -f 1 | tr -s '.' '-').nip.io -export WORKSHOP_NAMESPACE=test-network - -``` - -- Double-check that you are able to access a virtual host at the remote ingress domain. The expected response - is an HTTP 404 from nginx: -``` -$ curl foo.${WORKSHOP_INGRESS_DOMAIN} - -404 Not Found - -

404 Not Found

-
nginx
- - -``` - - - ---- -[PREV: Setup](00-setup.md) <==> [NEXT: Deploy a Fabric Network](20-fabric.md) - diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/13-kube-public-cloud.md b/full-stack-asset-transfer-guide/docs/CloudReady/13-kube-public-cloud.md deleted file mode 100644 index 666adb7c..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/13-kube-public-cloud.md +++ /dev/null @@ -1,135 +0,0 @@ -# Deploy a Kubernetes Cluster - -[PREV: Setup](00-setup.md) <==> [NEXT: Deploy a Fabric Network](20-fabric.md) - ---- - -## Ready? - -```shell - -just check-setup - -``` - -## Provision a cloud Kubernetes Instance - -- Provision an IKS or EKS Kubernetes service at IBM or Amazon Cloud. - - - Configure a 3x 4 CPU / 16 GRAM worker pool. - - single region is OK. - - -- Configure your `kubectl` CLI for access to the remote cluster. - -- Test CLI access to the cluster: -```shell - -kubectl cluster-info - -``` - -- Open a new shell and observe the target namespace: -```shell - -k9s -n test-network - -``` - - -## Configuration Options - -### IBM Cloud / IKS -```shell - -export WORKSHOP_NAMESPACE="test-network" -export WORKSHOP_CLUSTER_RUNTIME="k3s" -export WORKSHOP_COREDNS_DOMAIN_OVERRIDE="false" -export WORKSHOP_STAGE_DOCKER_IMAGES="false" -export WORKSHOP_STORAGE_CLASS="ibmc-file-gold" - -``` - - -### Amazon Web Services / EKS -```shell - -export WORKSHOP_NAMESPACE="test-network" -export WORKSHOP_CLUSTER_RUNTIME="k3s" -export WORKSHOP_COREDNS_DOMAIN_OVERRIDE="false" -export WORKSHOP_STAGE_DOCKER_IMAGES="false" -export WORKSHOP_STORAGE_CLASS="gp2" - -``` -### Digital ocean / DOKS -```shell - -export WORKSHOP_NAMESPACE="test-network" -export WORKSHOP_CLUSTER_RUNTIME="k3s" -export WORKSHOP_COREDNS_DOMAIN_OVERRIDE="false" -export WORKSHOP_STAGE_DOCKER_IMAGES="false" -export WORKSHOP_STORAGE_CLASS="do-block-storage" - -``` - -## Install Nginx Ingress - -- Install the Nginx controller to the cluster -```shell - -just nginx - -``` - - -## Cluster Ingress DNS Domain - -### IKS -```shell - -export INGRESS_IPADDR=$(kubectl -n ingress-nginx get svc/ingress-nginx-controller -o json | jq -r '.status.loadBalancer.ingress[0].ip') -export WORKSHOP_INGRESS_DOMAIN=$(echo $INGRESS_IPADDR | tr -s '.' '-').nip.io - -``` - -### EKS -```shell - -export INGRESS_HOSTNAME=$(kubectl -n ingress-nginx get svc/ingress-nginx-controller -o json | jq -r '.status.loadBalancer.ingress[0].hostname') -export INGRESS_IPADDR=$(dig $INGRESS_HOSTNAME +short) -export WORKSHOP_INGRESS_DOMAIN=$(echo $INGRESS_IPADDR | tr -s '.' '-').nip.io - -``` -### Digital ocean -```shell - -export INGRESS_HOSTNAME=$(kubectl -n ingress-nginx get svc/ingress-nginx-controller -o json | jq -r '.status.loadBalancer.ingress[0].ip') -export WORKSHOP_INGRESS_DOMAIN=$(echo $INGRESS_HOSTNAME | tr -s '.' '-').nip.io - -``` - - - - -# Take it Further - -During the workshop, one of the steps involves building a chaincode image, tagging the -image, and publishing to an insecure docker registry running at localhost:5000. For cloud -based clusters, the remote instance will not have access to the local insecure registry. - -To upload custom chaincode, configure your local docker client with access to an IBM -cloud / public container registry. In addition, make sure that the Fabric target namespace -has read access to the repository, allowing the pods created in the cluster with access to -your code. - -To run the workshop without building and uploading custom code, you can install a chaincode -package using the reference asset-transfer smart contract. This reference sample has been -made available for public read access, and does not require `imagePullSecrets` for the -chaincode pods to be started in the cluster. - -To install the reference smart contract, in the "Install Chaincode" section of the workshop, -skip the "build image" sections and [install the contract from a CI pipeline](https://github.com/jkneubuh/full-stack-asset-transfer-guide/blob/feature/iks-notes/docs/CloudReady/30-chaincode.md#install-chaincode-from-a-ci-pipeline). - - ---- -[PREV: Setup](00-setup.md) <==> [NEXT: Deploy a Fabric Network](20-fabric.md) diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/20-fabric-zh.md b/full-stack-asset-transfer-guide/docs/CloudReady/20-fabric-zh.md deleted file mode 100644 index 0d3f9338..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/20-fabric-zh.md +++ /dev/null @@ -1,107 +0,0 @@ -# 部署一个fabric网络 - -[前一步: 部署一个k8s集群](10-kube-zh.md) <==> [下一步:安装智能合约](30-chaincode-zh.md) - ---- -[Fabric-operator](https://github.com/hyperledger-labs/fabric-operator)是通过Operator技术使用 -[custom resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/)来部署Hyperledger Fabric网络中[CA](../../infrastructure/sample-network/config/cas),[peer](../../infrastructure/sample-network/config/peers),[orderer](../../infrastructure/sample-network/config/orderers)节点的一种工具和方式。最终它会将CA,Peer,Orderer转化为对应的k8s资源,如`Pod`,`Deployment`, `Service`, 和 `Ingress` - -一旦Fabric网络启动完成,可以使用`peer`和命令行工具通过Ingress来访问fabric网络。创建通道,合约和应用部署。 - -![Fabric Operator](../images/CloudReady/20-fabric.png) - -## 执行: - -```shell - -just check-kube - -``` - -## 示例网络 - -- 安装 fabric-operator [Kubernetes Custom Resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) -```shell - -kubectl apply -k https://github.com/hyperledger-labs/fabric-operator.git/config/crd - -``` - -- 部署 [CA](../../infrastructure/sample-network/config/cas), [peer](../../infrastructure/sample-network/config/peers), - 和 [orderer](../../infrastructure/sample-network/config/orderers) 资源。并等待operator完成k8s上的资源创建 `Pods`, `Deployments`, `Services`, 和 `Ingress` - -```shell - -just cloud-network - -``` - -- 建立通道: -```shell - -just cloud-channel - -``` - -- 建立TLS证书,channel msp,用户证书创建: -```shell - -export WORKSHOP_CRYPTO=$WORKSHOP_PATH/infrastructure/sample-network/temp - -``` - - -## 检查 - -```shell - -curl \ - -s \ - --cacert $WORKSHOP_CRYPTO/cas/org1-ca/tls-cert.pem \ - https://$WORKSHOP_NAMESPACE-org1-ca-ca.$WORKSHOP_INGRESS_DOMAIN/cainfo \ - | jq - -``` - -## 云原生和peer节点日志 - -我们可以通过如下方式获取peer节点信息比如peer节点的日志。 - -```shell -kubectl config set-context --current --namespace=test-network -kubectl get pods -``` - -假设org1 peer1 pod名称为`org1-peer1-79df64f8d8-7m9mt`, 我们可以通过如下命令来获取日志,从而观察peer节点上的通道,合约,和落块情况。 - -```shell -kubectl logs -f org1-peer1-79df64f8d8-7m9mt peer -``` - -您也可以使用其他工具如[k9s utility](https://k9scli.io/topics/install/).比如: - -```shell -k9s -n test-network -``` - -You'll see the fabric-operator, peer, orderer, and CA pods. Navigate around by hitting `ENTER` on one of the pods, `ENTER` again on one of the containers, and then hit `0` to tail the container's log. Go back up by hitting `ESCAPE`. More tips are available at the top of the k9s user interface. - -## 调试 - -```shell - -# While running "just cloud-network and/or just cloud-channel": -tail -f infrastructure/sample-network/network-debug.log - -``` - - -# 进一步拓展: - -- Deploy the [Fabric Operations Console](21-fabric-operations-console.md) -- Build a network with the [Ansible Blockchain Collection](22-fabric-ansible-collection.md) - - ---- - -[前一步: 部署一个k8s集群](10-kube-zh.md) <==> [下一步:安装智能合约](30-chaincode-zh.md) diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/20-fabric.md b/full-stack-asset-transfer-guide/docs/CloudReady/20-fabric.md deleted file mode 100644 index 629662a6..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/20-fabric.md +++ /dev/null @@ -1,118 +0,0 @@ -# Deploy a Fabric Network - -[PREV: Deploy a Kube](10-kube.md) <==> [NEXT: Install Chaincode](30-chaincode.md) - ---- - -[Fabric-operator](https://github.com/hyperledger-labs/fabric-operator) extends the core Kubernetes API with a set of -[custom resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) suitable for -describing the nodes of a Hyperledger Fabric Network. With the operator, a set of [CA](../../infrastructure/sample-network/config/cas), -[peer](../../infrastructure/sample-network/config/peers), and [orderer](../../infrastructure/sample-network/config/orderers) -resources are applied to the Kube API controller. In turn, the operator reflects the network as a series of `Pod`, -`Deployment`, `Service`, and `Ingress` resources in the target namespace. - -After the nodes in the Fabric network have been started, the fabric `peer` and CLI binaries are used to connect to the -network via Ingress, preparing a channel for smart contracts and application development. - -![Fabric Operator](../images/CloudReady/20-fabric.png) - - -## Ready? - -```shell - -just check-kube - -``` - -## Sample Network - -- Install the fabric-operator [Kubernetes Custom Resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) -```shell - -kubectl apply -k https://github.com/hyperledger-labs/fabric-operator.git/config/crd - -``` - -- Apply a series of [CA](../../infrastructure/sample-network/config/cas), [peer](../../infrastructure/sample-network/config/peers), - and [orderer](../../infrastructure/sample-network/config/orderers) resources directly to the Kube API controller. In - turn, fabric-operator will reconcile a network of Kubernetes `Pods`, `Deployments`, `Services`, and `Ingress` to - reflect the target network structure. -```shell - -just cloud-network - -``` - -- Create a Fabric channel: -```shell - -just cloud-channel - -``` - -- Set the location for the network's TLS certificates, channel MSP, and user enrollments: -```shell - -export WORKSHOP_CRYPTO=$WORKSHOP_PATH/infrastructure/sample-network/temp - -``` - - -## Post Checks - -```shell - -curl \ - -s \ - --cacert $WORKSHOP_CRYPTO/cas/org1-ca/tls-cert.pem \ - https://$WORKSHOP_NAMESPACE-org1-ca-ca.$WORKSHOP_INGRESS_DOMAIN/cainfo \ - | jq - -``` - -## Kube Navigation and Peer Logs - -To watch the peer logs throughout the workshop, we'll need to identify the pod name for one of the peers, let's find the pod name for org1-peer1 by using `kubectl`. -Set the default namespace to `test-network` so that we don't have to pass the namespace (`-n`) to each kubectl command: - -```shell -kubectl config set-context --current --namespace=test-network -kubectl get pods -``` - -You'll see the org1-peer1 pod with a name like `org1-peer1-79df64f8d8-7m9mt`, your pod name will be different! - -We can then tail the org1-peer1 log in a terminal window so that we can see proof that chaincodes get deployed, blocks get created, etc: - -```shell -kubectl logs -f org1-peer1-79df64f8d8-7m9mt peer -``` - -Now that you know how to use kubectl, let's learn the shortcut! You can easily monitor all of the the pods in the [k9s utility](https://k9scli.io/topics/install/). If you haven't started k9s yet, start it in a new terminal: - -```shell -k9s -n test-network -``` - -You'll see the fabric-operator, peer, orderer, and CA pods. Navigate around by hitting `ENTER` on one of the pods, `ENTER` again on one of the containers, and then hit `0` to tail the container's log. Go back up by hitting `ESCAPE`. More tips are available at the top of the k9s user interface. - -## Troubleshooting - -```shell - -# While running "just cloud-network and/or just cloud-channel": -tail -f infrastructure/sample-network/network-debug.log - -``` - - -# Take it Further: - -- Deploy the [Fabric Operations Console](21-fabric-operations-console.md) -- Build a network with the [Ansible Blockchain Collection](22-fabric-ansible-collection.md) - - ---- - -[PREV: Deploy a Kube](10-kube.md) <==> [NEXT: Install Chaincode](30-chaincode.md) diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/21-fabric-operations-console.md b/full-stack-asset-transfer-guide/docs/CloudReady/21-fabric-operations-console.md deleted file mode 100644 index 36beeb47..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/21-fabric-operations-console.md +++ /dev/null @@ -1,46 +0,0 @@ -# Deploy a Fabric Network - -[PREV: Deploy a Kube](10-kube.md) <==> [NEXT: Install Chaincode](30-chaincode.md) - ---- - -[Fabric Operations Console](https://github.com/hyperledger-labs/fabric-operations-console) provides an -interactive GUI layer and set of service SDKs suitable for the programmatic administration of a -Fabric network. - -![Fabric Operations Console](https://github.com/hyperledger-labs/fabric-operations-console/blob/main/docs/images/architecture_hl.png) - - -## Ready? - -```shell - -just check-kube - -``` - -## Operations Console - -- Install the fabric-operator [Kubernetes Custom Resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) -```shell - -kubectl apply -k https://github.com/hyperledger-labs/fabric-operator.git/config/crd - -``` - -- Install the Fabric operator and console in the target namespace: -```shell - -just console - -``` - -- Connect to the console GUI at the hyperlink printed to the terminal. - -- Use the Console GUI or [Ansible Collection](22-fabric-ansible-collection.md) to - [Build a Network](https://cloud.ibm.com/docs/blockchain?topic=blockchain-ibp-console-build-network) - - ---- - -[PREV: Deploy a Kube](10-kube.md) <==> [NEXT: Install Chaincode](30-chaincode.md) diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/22-fabric-ansible-collection.md b/full-stack-asset-transfer-guide/docs/CloudReady/22-fabric-ansible-collection.md deleted file mode 100644 index 4dc4e6f2..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/22-fabric-ansible-collection.md +++ /dev/null @@ -1,144 +0,0 @@ -# Deploy a Fabric Network - -[PREV: Deploy a Kube](10-kube.md) <==> [NEXT: Install Chaincode](30-chaincode.md) - ---- - -In addition to a graphical interface, [Fabric Operations Console](https://github.com/hyperledger-labs/fabric-operations-console) provides a set of RESTful service SDKs which can be utilized to realize a network in a declarative fashion using the Fabric [Blockchain Ansible Collection](https://github.com/IBM-Blockchain/ansible-collection). - -With ansible, a Fabric network of CAs, Peers, Orderers, Channels, Chaincode, and Identities are -realized by applying a series of playbooks to realize the target configuration. - -## Ready? - -```shell - -just check-kube - -``` - -## Build a Fabric Network - -The first step is to create the configuration that Ansible will use, then run the Ansible Playbooks - -### Define the namespace and storage class that will be used for console - -```shell -export WORKSHOP_NAMESPACE="fabricinfra" -# for *IBM Cloud K8S and Openshift* use this storage class -export WORKSHOP_STORAGE_CLASS="ibmc-file-gold" -``` - - -### Configure Ingress controller to the cluster -*IBMCloud IKS Clusters and Kind* - -```shell -just nginx -``` - -Check the Ingress controllers domain - -For IKS: -```shell -export INGRESS_IPADDR=$(kubectl -n ingress-nginx get svc/ingress-nginx-controller -o json | jq -r '.status.loadBalancer.ingress[0].ip') -export WORKSHOP_INGRESS_DOMAIN=$(echo $INGRESS_IPADDR | tr -s '.' '-').nip.io -``` - -For Kind: -```shell -export WORKSHOP_INGRESS_DOMAIN=localho.st -``` - -*IBM Cloud Openshift* - -The ingress subdomain can be obtained from the Cluster's dashboard, for example - -```shell -export WORKSHOP_INGRESS_DOMAIN=theclusterid.eu-gb.containers.appdomain.cloud -``` - -### Generate Ansible Playbook configuration - -```shell -# check the output to ensure the correct domain, storage class and namespace -just ansible-review-config -``` - -Please check the local `_cfg/operator-console-vars.yaml` file. Ensure that the ingress domain, storage class and namespace are correct. By default the all the `WORKSHOP_xxx` varirables are used to see the Ansible configuration, but it's worth double checking the files - -For example: -```shell -# this MUST be set to either k8s or openshift -target: openshift -# Console name/domain -console_domain: 203-0-113-42.nip.io -console_storage_class: ibmc-file-gold -``` - -**For Openshift, please ensure that the `type: openshift` is set** - -``` -target: openshift -``` - -- Set Kubectl context - -A Kubectl context is also requried - the default behaviour is use the current context. - - -Alternatively your K8S provider may give you a different command to get the K8S cxontext. -For IKS use this command instead -```shell -ibmcloud ks cluster config --cluster --output yaml > _cfg/k8s_context.yaml -``` - -The `k8s_context.yaml` will be detected by the shell scripts and that will be used - - -- Run the [00-complete](../../infrastructure/fabric_network_playbooks/00-complete.yml) play: -```shell - -# if you are using IKS/KIND -# do not do this for OpenShift -just ansible-ingress - - -# Start the operator and Fabric Operations Console -just ansible-operator -just ansible-console - -# Construct a network and channel with ansible playbooks -just ansible-network - -``` -The console will be available at the Nginx ingress domain alias: -`https://fabricinfra-hlf-console-console.` - - -In a browser, connect to this URL (accepting the self-signed certificate), log in as `admin` password `password` and view the network structure in the Operations Console user interface. (you will be prompted to change the password!) - -## Generate configuration files - -To connect applications details of the Gateway Endpoints with TLS certificates and the identies to use are required. -The Ansible scripts will have written several files to the `_cfg` directory, run `ls -1` to see the files and refer to the table below for what file is - -| Filename | Contents | -|------------------------------|-----------------------------------------------------------------------| -| 'Ordering Org Admin.json' | Ordering Organizations Admin identity | -| 'Ordering Org CA Admin.json' | Ordering Organization's Certificate Authority's Admin Identity | -| 'Org1 Admin.json' | Organization 1's Admin identity | -| 'Org1 CA Admin.json' | Organization 1's Certificate Authority's Admin Identity | -| 'Org2 Admin.json' | Organization 2's Admin identity | -| 'Org2 CA Admin.json' | Organization 2's Certificate Authority's Admin Identity | -| auth-vars.yml | Configuration for Ansible to connect to the Fabric Operations Console | -| fabric-common-vars.yml | Ansible Configuartion - for common and shared values | -| fabric-ordering-org-vars.yml | - for the ordering organization | -| fabric-org1-vars.yml | - for organization 1 | -| fabric-org2-vars.yml | - for ogranization 2 | -| operator-console-vars.yml | - for creating the operator an dconsole | - - ---- - -[PREV: Deploy a Kube](10-kube.md) <==> [NEXT: Install Chaincode](31-fabric-ansible-chaincode.md) diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/30-chaincode-zh.md b/full-stack-asset-transfer-guide/docs/CloudReady/30-chaincode-zh.md deleted file mode 100644 index da9ff7a5..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/30-chaincode-zh.md +++ /dev/null @@ -1,213 +0,0 @@ -# Chaincode - -[前一步: 部署一个fabric网络](20-fabric-zh.md) <==> [下一步: 部署应用](40-bananas-zh.md) - ---- - -根据Fabric传统的智能合约生命周期及管理,智能合约的部署需要通过Fabric administrator来准备和安装定义好的智能合约,通常包括智能合约源码,metadata和运行时(runtime)。 -当合约提交到通道时,peers节点将会相应编译过程并将源码作为子进程启动。 -这种工作方式可能会引发一些容器运行时的问题。比如在创建智能合约docker镜像的过程中的权限管理问题,以及运行阶段的合约容器适配问题。 -在容器和云原生环境上,如k8s,这中经典的智能合约部署过程需要自定义容器服务启动器的支持。 - -通过Fabric 2.4.1以上提供的[智能合约即服务](https://hyperledger-fabric.readthedocs.io/en/latest/cc_service.html)功能,Fabric管理员可以采用另外一种方式来部署智能合约服务。通过自定义智能合约容器,将智能合约镜像上传至容器registry,并作为k8s服务来启动。通过`peer`命令行执行相关命令来完成这一过程从而完成合约证明周期管理。 - -通过CCaaS / _no-op_ builder 我们可以减少传统合约生命周期中的相关权限管理问题,并提供了完整的智能合约生命周期管理能力。它将两项新主要责任交给了网络管理员: - -- `build` : 管理员需要构建容器镜像并上传。 -- `run` : 管理员需要准备`Service`, `Deployment`, 被配置TLS服务端口。 - -_"But - I just want to write some chaincode!"_ - -在这个练习中,我们将使用新的[Kubernetes Chaincode Builder](https://github.com/hyperledger-labs/fabric-builder-k8s)来开启外部合约构建通道和从而消除与CCaaS相关的管理负担。 - -通过使用fabric-k8s-builder, 我们将部署一个通过一下方式定义的智能合约: - -1. Preparing a chaincode container image and uploading to a distribution registry. -2. Preparing a `type=k8s` chaincode package specifying the unique and immutable [container image digest](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). -3. Using the `peer` CLI binaries to install and commit the smart contract to a channel. - - -![Fabric k8s Builder](../images/CloudReady/30-chaincode.png) - - -## 执行 - -```shell - -just check-network - -``` - - -## 设置peer命令行配置 - -```shell - -export ORG1_PEER1_ADDRESS=${WORKSHOP_NAMESPACE}-org1-peer1-peer.${WORKSHOP_INGRESS_DOMAIN}:443 -export ORG1_PEER2_ADDRESS=${WORKSHOP_NAMESPACE}-org1-peer2-peer.${WORKSHOP_INGRESS_DOMAIN}:443 - -# org1-peer1: -export CORE_PEER_LOCALMSPID=Org1MSP -export CORE_PEER_ADDRESS=${ORG1_PEER1_ADDRESS} -export CORE_PEER_TLS_ENABLED=true -export CORE_PEER_MSPCONFIGPATH=${WORKSHOP_CRYPTO}/enrollments/org1/users/org1admin/msp -export CORE_PEER_TLS_ROOTCERT_FILE=${WORKSHOP_CRYPTO}/channel-msp/peerOrganizations/org1/msp/tlscacerts/tlsca-signcert.pem -export CORE_PEER_CLIENT_CONNTIMEOUT=15s -export CORE_PEER_DELIVERYCLIENT_CONNTIMEOUT=15s -export ORDERER_ENDPOINT=${WORKSHOP_NAMESPACE}-org0-orderersnode1-orderer.${WORKSHOP_INGRESS_DOMAIN}:443 -export ORDERER_TLS_CERT=${WORKSHOP_CRYPTO}/channel-msp/ordererOrganizations/org0/orderers/org0-orderersnode1/tls/signcerts/tls-cert.pem - -``` - -## Docker Engine 配置 - -**NOTE: SKIP THIS STEP IF USING `localho.st` AS THE INGRESS DOMAIN** - -Configure the docker engine with the insecure container registry `${WORKSHOP_INGRESS_DOMAIN}:5000` - -For example: (Docker -> Preferences -> Docker Engine) -```json -{ - "insecure-registries": [ - "192-168-205-6.nip.io:5000" - ] -} -``` - -- apply and restart - -## 合约版本 - -```shell - -CHANNEL_NAME=mychannel -VERSION=v0.0.1 -SEQUENCE=1 - -``` - -## 构建Chaincode Docker Image - -```shell - -CHAINCODE_NAME=asset-transfer -CHAINCODE_PACKAGE=${CHAINCODE_NAME}.tgz -CONTAINER_REGISTRY=$WORKSHOP_INGRESS_DOMAIN:5000 -CHAINCODE_IMAGE=$CONTAINER_REGISTRY/$CHAINCODE_NAME - -# Build the chaincode image -docker build -t $CHAINCODE_IMAGE contracts/$CHAINCODE_NAME-typescript - -# Push the image to the insecure container registry -docker push $CHAINCODE_IMAGE - -``` - - -## 准备 a k8s Chaincode Package - -```shell - -IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' $CHAINCODE_IMAGE | cut -d'@' -f2) - -infrastructure/pkgcc.sh -l $CHAINCODE_NAME -n localhost:5000/$CHAINCODE_NAME -d $IMAGE_DIGEST - -``` - -## 安装智能合约 - -```shell - -# Install the chaincode package on both peers in the org -CORE_PEER_ADDRESS=${ORG1_PEER1_ADDRESS} peer lifecycle chaincode install $CHAINCODE_PACKAGE -CORE_PEER_ADDRESS=${ORG1_PEER2_ADDRESS} peer lifecycle chaincode install $CHAINCODE_PACKAGE - -export PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid $CHAINCODE_PACKAGE) && echo $PACKAGE_ID - -# Approve the contract for org1 -peer lifecycle \ - chaincode approveformyorg \ - --channelID ${CHANNEL_NAME} \ - --name ${CHAINCODE_NAME} \ - --version ${VERSION} \ - --package-id ${PACKAGE_ID} \ - --sequence ${SEQUENCE} \ - --orderer ${ORDERER_ENDPOINT} \ - --tls --cafile ${ORDERER_TLS_CERT} \ - --connTimeout 15s - -# Commit the contract on the channel -peer lifecycle \ - chaincode commit \ - --channelID ${CHANNEL_NAME} \ - --name ${CHAINCODE_NAME} \ - --version ${VERSION} \ - --sequence ${SEQUENCE} \ - --orderer ${ORDERER_ENDPOINT} \ - --tls --cafile ${ORDERER_TLS_CERT} \ - --connTimeout 15s - -``` - -```shell - -peer chaincode query -n $CHAINCODE_NAME -C mychannel -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' | jq - -``` - - -# 进一步探索 - -## 编辑,编译,上传,重新安装合约: - -```shell - -SEQUENCE=$((SEQUENCE + 1)) -VERSION=v0.0.$SEQUENCE - -``` - -- Make a change to the contracts/asset-transfer-typescript source code -- build a new chaincode docker image and publish to the local container registry -- prepare a new chaincode package as above. -- install, approve, and commit as above. - - -## 基于CI pipeline的结果安装智能合约 - -```shell - -SEQUENCE=$((SEQUENCE + 1)) -VERSION=v0.1.3 -CHAINCODE_PACKAGE=asset-transfer-typescript-${VERSION}.tgz - -``` - -- Download a chaincode release artifact from GitHub: -```shell - -curl -LO https://github.com/hyperledgendary/full-stack-asset-transfer-guide/releases/download/${VERSION}/${CHAINCODE_PACKAGE} - -``` - -- install, approve, and commit as above. - - -## 通过智能合约即服务进行调试 - -- prepare a chaincode package with connection.json -> HOST IP:9999 (todo: link to dig out) -- compute CHAINCODE_ID=shasum CC package.tgz -- docker run -e CHAINCODE_ID -e CHAINCODE_SERVER_ADDRESS ... $CHAINCODE_IMAGE in a different shell -- install, approve, commit as above. - - -## 通过Ansible进行合约部署 - -- cp tgz from github releases -> _cfg/ -- edit _cfg/cc yaml with package name -- `just ... chaincode` - - ---- - -[前一步: 部署一个fabric网络](20-fabric-zh.md) <==> [下一步: 部署应用](40-bananas-zh.md) diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/30-chaincode.md b/full-stack-asset-transfer-guide/docs/CloudReady/30-chaincode.md deleted file mode 100644 index f58ae936..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/30-chaincode.md +++ /dev/null @@ -1,225 +0,0 @@ -# Chaincode - -[PREV: Deploy a Fabric Network](20-fabric.md) <==> [NEXT: Go Bananas](40-bananas.md) - ---- - -Using the traditional chaincode lifecycle, smart contract deployment requires a Fabric administrator to prepare -and install a chaincode package declaring the contract source code, metadata, and target language/runtime. When the -contract is committed to a channel, peers are responsible for compiling a custom chaincode binary and launching the -contract as a child process. This workflow creates several issues for container-based runtimes, where the `build` -phase is additionally responsible for compiling a Docker image, and the `run` phase is responsible for managing the -lifecycle of a chaincode process in a container orchestrator. - -In container based environments such as Kubernetes, the classical chaincode deployment was generally supported with a -custom chaincode server / launcher. - -With the introduction of [Chaincode as a Service](https://hyperledger-fabric.readthedocs.io/en/latest/cc_service.html) -(>= 2.4.1), Fabric administrators were provided an alternative deployment option whereby an external chaincode -builder could be configured as a _"no-op builder"_. Using CCaaS, an administrator could prepare a custom chaincode -container, upload the image to a container registry, launch the chaincode "as a service," and complete the peer -lifecycle using traditional `peer` CLI commands. - -While the CCaaS / _no-op_ builder alleviated some mechanical issues and offered full customization of the chaincode -lifecycle, it placed two new major responsibilities on the Fabric network administrator: - -- `build` : The admin must prepare a chaincode image and upload to a container registry. -- `run` : The admin must prepare a `Service`, `Deployment`, and configure TLS for the chaincode endpoint. - -_"But - I just want to write some chaincode!"_ - - -In this exercise, we will see how the new [Kubernetes Chaincode Builder](https://github.com/hyperledger-labs/fabric-builder-k8s) -enables an external container build pipeline and eliminates the administrative burdens associated with CCaaS. - -Using the fabric-k8s-builder, you will deploy (and iterate) a smart contract definition by: - -1. Preparing a chaincode container image and uploading to a distribution registry. -2. Preparing a `type=k8s` chaincode package specifying the unique and immutable [container image digest](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). -3. Using the `peer` CLI binaries to install and commit the smart contract to a channel. - - -![Fabric k8s Builder](../images/CloudReady/30-chaincode.png) - - -## Ready? - -```shell - -just check-network - -``` - - -## Set the peer client environment - -```shell - -export ORG1_PEER1_ADDRESS=${WORKSHOP_NAMESPACE}-org1-peer1-peer.${WORKSHOP_INGRESS_DOMAIN}:443 -export ORG1_PEER2_ADDRESS=${WORKSHOP_NAMESPACE}-org1-peer2-peer.${WORKSHOP_INGRESS_DOMAIN}:443 - -# org1-peer1: -export CORE_PEER_LOCALMSPID=Org1MSP -export CORE_PEER_ADDRESS=${ORG1_PEER1_ADDRESS} -export CORE_PEER_TLS_ENABLED=true -export CORE_PEER_MSPCONFIGPATH=${WORKSHOP_CRYPTO}/enrollments/org1/users/org1admin/msp -export CORE_PEER_TLS_ROOTCERT_FILE=${WORKSHOP_CRYPTO}/channel-msp/peerOrganizations/org1/msp/tlscacerts/tlsca-signcert.pem -export CORE_PEER_CLIENT_CONNTIMEOUT=15s -export CORE_PEER_DELIVERYCLIENT_CONNTIMEOUT=15s -export ORDERER_ENDPOINT=${WORKSHOP_NAMESPACE}-org0-orderersnode1-orderer.${WORKSHOP_INGRESS_DOMAIN}:443 -export ORDERER_TLS_CERT=${WORKSHOP_CRYPTO}/channel-msp/ordererOrganizations/org0/orderers/org0-orderersnode1/tls/signcerts/tls-cert.pem - -``` - -## Docker Engine Configuration - -**NOTE: SKIP THIS STEP IF USING `localho.st` AS THE INGRESS DOMAIN** - -Configure the docker engine with the insecure container registry `${WORKSHOP_INGRESS_DOMAIN}:5000` - -For example: (Docker -> Preferences -> Docker Engine) -```json -{ - "insecure-registries": [ - "192-168-205-6.nip.io:5000" - ] -} -``` - -- apply and restart - -## Chaincode Revision - -```shell - -CHANNEL_NAME=mychannel -VERSION=v0.0.1 -SEQUENCE=1 - -``` - -## Build the Chaincode Docker Image - -```shell - -CHAINCODE_NAME=asset-transfer -CHAINCODE_PACKAGE=${CHAINCODE_NAME}.tgz -CONTAINER_REGISTRY=$WORKSHOP_INGRESS_DOMAIN:5000 -CHAINCODE_IMAGE=$CONTAINER_REGISTRY/$CHAINCODE_NAME - -# Build the chaincode image -docker build -t $CHAINCODE_IMAGE contracts/$CHAINCODE_NAME-typescript - -# Push the image to the insecure container registry -docker push $CHAINCODE_IMAGE - -``` - - -## Prepare a k8s Chaincode Package - -```shell - -IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' $CHAINCODE_IMAGE | cut -d'@' -f2) - -infrastructure/pkgcc.sh -l $CHAINCODE_NAME -n localhost:5000/$CHAINCODE_NAME -d $IMAGE_DIGEST - -``` - -## Install the Chaincode - -```shell - -# Install the chaincode package on both peers in the org -CORE_PEER_ADDRESS=${ORG1_PEER1_ADDRESS} peer lifecycle chaincode install $CHAINCODE_PACKAGE -CORE_PEER_ADDRESS=${ORG1_PEER2_ADDRESS} peer lifecycle chaincode install $CHAINCODE_PACKAGE - -export PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid $CHAINCODE_PACKAGE) && echo $PACKAGE_ID - -# Approve the contract for org1 -peer lifecycle \ - chaincode approveformyorg \ - --channelID ${CHANNEL_NAME} \ - --name ${CHAINCODE_NAME} \ - --version ${VERSION} \ - --package-id ${PACKAGE_ID} \ - --sequence ${SEQUENCE} \ - --orderer ${ORDERER_ENDPOINT} \ - --tls --cafile ${ORDERER_TLS_CERT} \ - --connTimeout 15s - -# Commit the contract on the channel -peer lifecycle \ - chaincode commit \ - --channelID ${CHANNEL_NAME} \ - --name ${CHAINCODE_NAME} \ - --version ${VERSION} \ - --sequence ${SEQUENCE} \ - --orderer ${ORDERER_ENDPOINT} \ - --tls --cafile ${ORDERER_TLS_CERT} \ - --connTimeout 15s - -``` - -```shell - -peer chaincode query -n $CHAINCODE_NAME -C mychannel -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' | jq - -``` - - -# Take it Further - -## Edit, compile, upload, and re-install your chaincode: - -```shell - -SEQUENCE=$((SEQUENCE + 1)) -VERSION=v0.0.$SEQUENCE - -``` - -- Make a change to the contracts/asset-transfer-typescript source code -- build a new chaincode docker image and publish to the local container registry -- prepare a new chaincode package as above. -- install, approve, and commit as above. - - -## Install chaincode from a CI Pipeline - -```shell - -SEQUENCE=$((SEQUENCE + 1)) -VERSION=v0.1.3 -CHAINCODE_PACKAGE=asset-transfer-typescript-${VERSION}.tgz - -``` - -- Download a chaincode release artifact from GitHub: -```shell - -curl -LO https://github.com/hyperledgendary/full-stack-asset-transfer-guide/releases/download/${VERSION}/${CHAINCODE_PACKAGE} - -``` - -- install, approve, and commit as above. - - -## Debug with Chaincode as a Service - -- prepare a chaincode package with connection.json -> HOST IP:9999 (todo: link to dig out) -- compute CHAINCODE_ID=shasum CC package.tgz -- docker run -e CHAINCODE_ID -e CHAINCODE_SERVER_ADDRESS ... $CHAINCODE_IMAGE in a different shell -- install, approve, commit as above. - - -## Deploy Chaincode With Ansible - -- cp tgz from github releases -> _cfg/ -- edit _cfg/cc yaml with package name -- `just ... chaincode` - - ---- - -[PREV: Deploy a Fabric Network](20-fabric.md) <==> [NEXT: Go Bananas](40-bananas.md) diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/31-fabric-ansible-chaincode.md b/full-stack-asset-transfer-guide/docs/CloudReady/31-fabric-ansible-chaincode.md deleted file mode 100644 index 02af54b9..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/31-fabric-ansible-chaincode.md +++ /dev/null @@ -1,182 +0,0 @@ -# Dploying Chaincode with Ansible - -[PREV: Deploy a Fabric Network](22-fabric-ansible-collection.md) <==> [NEXT: Go Bananas](40-bananas.md) - ---- - - -## Ready? - -```shell - -just check-network - -``` -## Build the Chaincode Docker Image - -We need to build the chaincode image, and push it to the local image registry. Here this uses docker to build the image - -```shell -# Build the chaincode image -docker build -t localho.st:5000/asset-transfer contracts/asset-transfer-typescript - -# Push the image to the insecure container registry -docker push localho.st:5000/asset-transfer - -``` - -## Prepare a k8s Chaincode Package - -A chaincode package is requried to inform the peer of which docker image should be used. (strictly it is the K8s-builder that knows which image to use; the peer uses the k8s-builder to do the work creating the container. therefore the peer that Ansible has created is specifically configured to work in k8s) - -```shell -IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' localho.st:5000/asset-transfer | cut -d'@' -f2) -infrastructure/pkgcc.sh -l asset-transfer -n localhost:5000/asset-transfer -d $IMAGE_DIGEST -``` - -Check the tgz package created - -```shell -ls -l asset-transfer.tgz --rw-r--r-- 1 matthew matthew 483 Sep 5 11:05 asset-transfer.tgz -``` -You can see the file is quite small. If you like you can unpack this with tar - -```shell -tar -zxf asset-transfer.tgz && tar -zxf code.tar.gz -``` - -Copy the `asset-transfer.tgz` to the `_cfg` directory. - -```shell -cp asset-transfer.tgz ${WORKSPACE_PATH}/_cfg -``` - -## Deploy the Chaincode - -Firstly we need to create a Ansible variables files that will give the Ansible modules the information on what we want to deploy. - -An example file has been provided, check the contents to see what is needed. -```shell - -cat contracts/asset-transfer-typescript/asset-transfer-chaincode-vars.yml - -smart_contract_name: "asset-transfer" -smart_contract_version: "1.0.0" -smart_contract_sequence: 1 -smart_contract_package: "asset-transfer.tgz" -# smart_contract_constructor: "initLedger" -smart_contract_endorsement_policy: "" -smart_contract_collections_file: "" -``` - -There are three (small) playbooks that need to run to deploy the chaincode. - -- Install and Approve the chaincode on the peers. One each for [org1](../../infrastructure/production_chaincode_playbooks/19-install-and-approve-chaincode.yml) and [org2](../../infrastructure/production_chaincode_playbooks/20-install-and-approve-chaincode.yml) -- Commit the chaincode definition to the channel needs [one playbook](../../infrastructure/production_chaincode_playbooks/21-commit-chaincode.yml) - -Run all of these playbooks now; the example configuration file above will be used - -```shell -just ansible-deploy-chaincode -``` - -This will have created the chaincode containers. - -## Create a user to access the chaincode - -We can run a simple client application here to check the chaincode is deployed and accessible to each. There are two Ansible tasks that are helpful here. - -- `registered_identity` will register an identity to use for the application -- `enrolled_identity` will enroll an already registered identity, returning the certifcate and private keys needed -- `connection_profile` that will put together all the information needed for connecting an application - -```shell -just ansible-ready-application -``` - -This will create two files in `_cfg`; first look at the identity (we've shortened the certificates here) - -```shell - cat _cfg/asset-transfer_appid.json -{ - "name": "asset-transfer.admin", - "cert": "LS0..............", - "ca": "LS0tLS................", - "hsm": false, - "private_key": "LS0tLS1C..........." -} - -``` - -Now look at the `Org1_gateway.json` file; use jq to just look at the address needed for the gateway to connect to - -```shell -cat _cfg/Org1_gateway.json | jq .peers -{ - "Org1 Peer": { - "url": "grpcs://fabricinfra-org1peer-peer.localho.st:443", - "tlsCACerts": { - "pem": "-----BEGIN CERTIFICATE-----...\n-----END CERTIFICATE-----\n" - } - } -} -``` - -## Setup the application - -We can use this information directly in an application; we will use the Gateway SDK to create a simple client that will invoke the ib-built Smart Contract function to return it's metadata. This is available in all smart contracts, so it is a useful and simple way to check everything is deployed. The application is called 'ping-chaincode' for this reason - -- Change to the `applications/ping-chaincode` directory -- Check the `app.env` file, it should look similar to this - -``` -CHANNEL_NAME=mychannel -CHAINCODE_NAME=asset-transfer -CONN_PROFILE_FILE=/home/matthew/github.com/hyperledgendary/full-stack-asset-transfer-guide/_cfg/Org1_gateway.json -ID_FILE=asset-transfer_appid.json -ID_DIR=/home/matthew/github.com/hyperledgendary/full-stack-asset-transfer-guide/_cfg/ -TLS_ENABLED=true -``` - -- Build the application (it's typescript) - -```shell -npm install -npm run build -``` - -- Run the application, and look at the output. - -```shell -npm start - - -> asset-transfer-basic@1.0.0 start -> node dist/app.js - -Created GRPC Connection -Loaded Identity - ---> Evaluate Transaction: Get Contract Metdata from : org.hyperledger.fabric:GetMetadata -*** Result: -$schema: >- - https://hyperledger.github.io/fabric-chaincode-node/main/api/contract-schema.json -contracts: - AssetTransferContract: - name: AssetTransferContract - contractInstance: - name: AssetTransferContract - default: true - transactions: - - tag: - - SUBMIT - - submitTx - parameters: - - name: assetJson - description: '' - schema: - type: string - name: CreateAsset -.... -``` \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/40-bananas-zh.md b/full-stack-asset-transfer-guide/docs/CloudReady/40-bananas-zh.md deleted file mode 100644 index 3b2be76a..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/40-bananas-zh.md +++ /dev/null @@ -1,150 +0,0 @@ -# Gateway Client Application - -[前一步: 安装智能合约](30-chaincode-zh.md) <==> [下一步: 关闭环境](90-teardown.md) - ---- -这是本次workshop的最后一个练习,我们将会使用Gateway Client来将我们开发的应用[应用](../ApplicationDev)部署在云原生的Fabric网络上。 - -为了查询账本和提交交易到`asset-transfer`智能合约,客户端应用必须通过制定CA签发的数字身份来启动。一旦用户身份被注册,我们将会用身份来创建,交易虚拟“token”资产。 - -![Gateway Client Application](../../docs/images/CloudReady/40-gateway-client-app.png) - - -## 执行 - -```shell - -just check-chaincode - -``` - - -## 注册新用户 - -```shell - -# User organization MSP ID -export MSP_ID=Org1MSP -export ORG=org1 -export USERNAME=org1user -export PASSWORD=org1userpw - -``` - -```shell - -ADMIN_MSP_DIR=$WORKSHOP_CRYPTO/enrollments/${ORG}/users/rcaadmin/msp -USER_MSP_DIR=$WORKSHOP_CRYPTO/enrollments/${ORG}/users/${USERNAME}/msp -PEER_MSP_DIR=$WORKSHOP_CRYPTO/channel-msp/peerOrganizations/${ORG}/msp - -fabric-ca-client register \ - --id.name $USERNAME \ - --id.secret $PASSWORD \ - --id.type client \ - --url https://$WORKSHOP_NAMESPACE-$ORG-ca-ca.$WORKSHOP_INGRESS_DOMAIN \ - --tls.certfiles $WORKSHOP_CRYPTO/cas/$ORG-ca/tls-cert.pem \ - --mspdir $WORKSHOP_CRYPTO/enrollments/$ORG/users/rcaadmin/msp - -fabric-ca-client enroll \ - --url https://$USERNAME:$PASSWORD@$WORKSHOP_NAMESPACE-$ORG-ca-ca.$WORKSHOP_INGRESS_DOMAIN \ - --tls.certfiles $WORKSHOP_CRYPTO/cas/$ORG-ca/tls-cert.pem \ - --mspdir $WORKSHOP_CRYPTO/enrollments/$ORG/users/$USERNAME/msp - -mv $USER_MSP_DIR/keystore/*_sk $USER_MSP_DIR/keystore/key.pem - -``` - -## 启动应用 - -- Set the gateway client to connect to the org1-peer1 as the newly enrolled `${USERNAME}`: -```shell - -# Path to private key file -export PRIVATE_KEY=${USER_MSP_DIR}/keystore/key.pem - -# Path to user certificate file -export CERTIFICATE=${USER_MSP_DIR}/signcerts/cert.pem - -# Path to CA certificate -export TLS_CERT=${PEER_MSP_DIR}/tlscacerts/tlsca-signcert.pem - -# Gateway peer SSL host name override -export HOST_ALIAS=${WORKSHOP_NAMESPACE}-${ORG}-peer1-peer.${WORKSHOP_INGRESS_DOMAIN} - -# Gateway endpoint -export ENDPOINT=$HOST_ALIAS:443 - -``` - -```shell - -pushd applications/trader-typescript - -npm install - -``` - -```shell - -# Create a yellow banana token owned by appleman@org1 -npm start create banana bananaman yellow - -npm start getAllAssets - -# Transfer the banana among users / orgs -npm start transfer banana appleman Org1MSP - -npm start getAllAssets - -# Transfer the banana among users / orgs -npm start transfer banana bananaman Org2MSP - -# Error! Which org owns the banana? -npm start transfer banana bananaman Org1MSP - -popd - -``` - -# 进一步探索 - -## Gateway 负载均衡 - -在之前的例子中,我们的Gateway客户端时通过直接连接的方式连接到peer节点上。我们可以进一步通过负载均衡的方式来进行拓展,通过将Gateway连接到虚拟机的Ingress和k8s Service上。当以这种方式连接时,网关客户端连接通过网关在网络中的组织对等端之间进行负载平衡对等方进一步向对等方发送交易请求,同时保持平衡的账本高度。 - -![Fabric Gateway deployment](../images/ApplicationDev/fabric-gateway-deployment.png) - -相关设置 [Service and Ingress](../../infrastructure/sample-network/config/gateway/org1-peer-gateway.yaml): - - -- Create a virtual host name / Ingress endpoint for the org peers: -```shell -pushd applications/trader-typescript - -kubectl kustomize \ - ../../infrastructure/sample-network/config/gateway \ - | envsubst \ - | kubectl -n ${WORKSHOP_NAMESPACE} apply -f - - -``` - -- Run the gateway client application, using the load-balanced Gateway service. When the gateway client -connects to the network, the gRPCs connections will be distributed across peers in the org: -```shell - -unset HOST_ALIAS -export ENDPOINT=${WORKSHOP_NAMESPACE}-org1-peer-gateway.${WORKSHOP_INGRESS_DOMAIN}:443 - -npm start getAllAssets - -popd -``` - -Note that in order to support ingress and host access with the new virtual domain, the peer -CRDs have been instructed to [designate an additional SAN alias](../../infrastructure/sample-network/config/peers/org1-peer1.yaml#L69) -/ host name when provisioning the node TLS certificate with the CA. - - ---- - -[前一步: 安装智能合约](30-chaincode-zh.md) <==> [下一步: 关闭环境](90-teardown.md) diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/40-bananas.md b/full-stack-asset-transfer-guide/docs/CloudReady/40-bananas.md deleted file mode 100644 index 37efc70d..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/40-bananas.md +++ /dev/null @@ -1,159 +0,0 @@ -# Gateway Client Application - -[PREV: Install Chaincode](30-chaincode.md) <==> [NEXT: Teardown](90-teardown.md) - ---- - -In this final workshop exercise, we will port the Gateway Client routines you developed in the -[ApplicationDev](../ApplicationDev) module to run on a cloud-native Fabric network. - -In order to query the ledger and submit transactions to the `asset-transfer` smart contract, the client application -must run with an identity certificate and key pair issued by the organization's CA. Once the user identity has -been enrolled with the CA, we'll use the new identity to create, transfer, and exchange virtual "token" assets -on a shared ledger. - -![Gateway Client Application](../../docs/images/CloudReady/40-gateway-client-app.png) - - -## Ready? - -```shell - -just check-chaincode - -``` - - -## Register and enroll a new user at the org CA - -```shell - -# User organization MSP ID -export MSP_ID=Org1MSP -export ORG=org1 -export USERNAME=org1user -export PASSWORD=org1userpw - -``` - -```shell - -ADMIN_MSP_DIR=$WORKSHOP_CRYPTO/enrollments/${ORG}/users/rcaadmin/msp -USER_MSP_DIR=$WORKSHOP_CRYPTO/enrollments/${ORG}/users/${USERNAME}/msp -PEER_MSP_DIR=$WORKSHOP_CRYPTO/channel-msp/peerOrganizations/${ORG}/msp - -fabric-ca-client register \ - --id.name $USERNAME \ - --id.secret $PASSWORD \ - --id.type client \ - --url https://$WORKSHOP_NAMESPACE-$ORG-ca-ca.$WORKSHOP_INGRESS_DOMAIN \ - --tls.certfiles $WORKSHOP_CRYPTO/cas/$ORG-ca/tls-cert.pem \ - --mspdir $WORKSHOP_CRYPTO/enrollments/$ORG/users/rcaadmin/msp - -fabric-ca-client enroll \ - --url https://$USERNAME:$PASSWORD@$WORKSHOP_NAMESPACE-$ORG-ca-ca.$WORKSHOP_INGRESS_DOMAIN \ - --tls.certfiles $WORKSHOP_CRYPTO/cas/$ORG-ca/tls-cert.pem \ - --mspdir $WORKSHOP_CRYPTO/enrollments/$ORG/users/$USERNAME/msp - -mv $USER_MSP_DIR/keystore/*_sk $USER_MSP_DIR/keystore/key.pem - -``` - -## Go Bananas - -- Set the gateway client to connect to the org1-peer1 as the newly enrolled `${USERNAME}`: -```shell - -# Path to private key file -export PRIVATE_KEY=${USER_MSP_DIR}/keystore/key.pem - -# Path to user certificate file -export CERTIFICATE=${USER_MSP_DIR}/signcerts/cert.pem - -# Path to CA certificate -export TLS_CERT=${PEER_MSP_DIR}/tlscacerts/tlsca-signcert.pem - -# Gateway peer SSL host name override -export HOST_ALIAS=${WORKSHOP_NAMESPACE}-${ORG}-peer1-peer.${WORKSHOP_INGRESS_DOMAIN} - -# Gateway endpoint -export ENDPOINT=$HOST_ALIAS:443 - -``` - -```shell - -pushd applications/trader-typescript - -npm install - -``` - -```shell - -# Create a yellow banana token owned by appleman@org1 -npm start create banana bananaman yellow - -npm start getAllAssets - -# Transfer the banana among users / orgs -npm start transfer banana appleman Org1MSP - -npm start getAllAssets - -# Transfer the banana among users / orgs -npm start transfer banana bananaman Org2MSP - -# Error! Which org owns the banana? -npm start transfer banana bananaman Org1MSP - -popd - -``` - -# Take it Further - -## Gateway Load Balancing - -In the example above, the gateway client connects directly to a peer using the specific peer node's -gRPCs URL. This can be extended with a level of fail-over and load balancing, by instructing the gateway -client to connect at a virtual host Ingress and Kubernetes Service. When connecting in this fashion, -Gateway client connections are load balanced across the org's peers in the network, with the gateway -peer further dispatching transaction requests to peers while maintaining a balanced ledger height. - -![Fabric Gateway deployment](../images/ApplicationDev/fabric-gateway-deployment.png) - -To set up a load-balanced Gateway [Service and Ingress](../../infrastructure/sample-network/config/gateway/org1-peer-gateway.yaml) URL in Kubernetes: - - -- Create a virtual host name / Ingress endpoint for the org peers: -```shell -pushd applications/trader-typescript - -kubectl kustomize \ - ../../infrastructure/sample-network/config/gateway \ - | envsubst \ - | kubectl -n ${WORKSHOP_NAMESPACE} apply -f - - -``` - -- Run the gateway client application, using the load-balanced Gateway service. When the gateway client -connects to the network, the gRPCs connections will be distributed across peers in the org: -```shell - -unset HOST_ALIAS -export ENDPOINT=${WORKSHOP_NAMESPACE}-org1-peer-gateway.${WORKSHOP_INGRESS_DOMAIN}:443 - -npm start getAllAssets - -popd -``` - -Note that in order to support ingress and host access with the new virtual domain, the peer -CRDs have been instructed to [designate an additional SAN alias](../../infrastructure/sample-network/config/peers/org1-peer1.yaml#L69) -/ host name when provisioning the node TLS certificate with the CA. - - ---- - -[PREV: Install Chaincode](30-chaincode.md) <==> [NEXT: Teardown](90-teardown.md) diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/50-OpenShift-Deployment.md b/full-stack-asset-transfer-guide/docs/CloudReady/50-OpenShift-Deployment.md deleted file mode 100644 index 61a80075..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/50-OpenShift-Deployment.md +++ /dev/null @@ -1,41 +0,0 @@ -# Notes on deployment with OpenShift - -There are minor variations in deploying to each different K8S environment; these notes are for open shift specifically - -## Login - -Typically for setup the local k8s context you should login to OpenShift onthe command line; this usually uses token based authentication rather than a password. - -## Storage Classes - -If you don't have any storage classes created by default... - -``` -CLUSTER_TYPE=ocp ./infrastructure/setup_storage_classes.sh -``` - -This uses rook to create storage classes -Set the setup_storage_classes - -``` -WORKSHOP_STORAGE_CLASS=rook-cephfs -``` - -## Image Registry - -Using the built in image registry is possible. - -Follow the instructions at https://docs.openshift.com/container-platform/4.8/registry/accessing-the-registry.html to create a user and permissions that allow for pushing and pulling from the registry - -Expose the registry externally with instructions at https://docs.openshift.com/container-platform/4.8/registry/securing-exposing-registry.html - -## Image names - -Note the name used externally is different from the internal name of the image. The name in the chaincode package MUST be the internal name - -As an example for a bare-metal OpenShift cluster these where the internal and external names of the same image - -``` -WORKSHOP_EXTERNAL_REPO=default-route-openshift-image-registry.apps.report.cp.fyre.ibm.com:443 -WORKSHOP_INTERNAL_REPO=image-registry.openshift-image-registry.svc:5000 -``` \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/90-teardown.md b/full-stack-asset-transfer-guide/docs/CloudReady/90-teardown.md deleted file mode 100644 index 6f7538b1..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/90-teardown.md +++ /dev/null @@ -1,56 +0,0 @@ -# Teardown - -<== [PREV: Go Bananas](40-bananas.md) - ---- - - -## Conga Test - -## Final Exercise: Build Your (Social) Network - -- Write down your email address / linkedin profile / # discord handle / etc. on the back of your Conga Card. -- Use the fabric-ca-client to enroll the user / password listed on your Conga Card. -- `create()` an NFT asset for your Conga Card on the shared workshop blockchain. -- Go around the room and meet people attending the workshop. -- Exchange your Conga Cards with workshop participants, issuing a `transfer()` transaction on the shared ledger. -- When you exchange conga cards, record the new owners (both on the back of the card and the ledger!) -- Bring your Conga Trading Cards home, and reach out to all your new friends and colleagues. - - -## Thank You! - -- Discord: [#dublin-workshop](https://discord.gg/hyperledger) -- Discord: [#fabric-kubernetes](https://discord.gg/hyperledger) -- Thank you for attending the workshop! -- Safe travels home, and happy coding. - - -## Workshop Teardown: - -- Shut down the network, but leave KIND / MP / etc running: -```shell - -just cloud-network-down - -``` - -- Shut down KIND, the private container registry, and Nginx: -```shell - -just unkind - -``` - -- Shut down the Multipass VM, if running: -```shell - -multipass delete fabric-dev -multipass purge - -``` - -## Cloud VMs - -- Terminate EC2 / IKS Instances (Workshop systems will be deleted after the event) - diff --git a/full-stack-asset-transfer-guide/docs/CloudReady/README.md b/full-stack-asset-transfer-guide/docs/CloudReady/README.md deleted file mode 100644 index 5943d873..00000000 --- a/full-stack-asset-transfer-guide/docs/CloudReady/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Cloud Native Fabric - -- [Cloud Ready!](00-setup.md) -- **Exercise:** [Deploy a Kubernetes Cluster](10-kube.md) - - (optional) With a [Multipass VM](11-kube-multipass.md) - - (optional) With an [EC2 VM](12-kube-ec2-vm.md) - - (optional) With a [public cloud](13-kube-public-cloud.md) -- **Exercise:** [Deploy a Fabric Network](20-fabric.md) - - (optional) With the [Fabric Operations Console](21-fabric-operations-console.md) - - (optional) With the [Ansible Blockchain Collection](22-fabric-ansible-collection.md) -- **Exercise:** [Deploy a Smart Contract](30-chaincode.md) - - (optional) With the [Ansible Blockchain Collection](31-fabric-ansible-chaincode.md) -- **Exercise:** [Deploy a Client Application](40-bananas.md) - - diff --git a/full-stack-asset-transfer-guide/docs/SmartContractDev/00-Introduction-ES.md b/full-stack-asset-transfer-guide/docs/SmartContractDev/00-Introduction-ES.md deleted file mode 100644 index d5ffd0e0..00000000 --- a/full-stack-asset-transfer-guide/docs/SmartContractDev/00-Introduction-ES.md +++ /dev/null @@ -1,121 +0,0 @@ -# Desarrollo de Contratos Inteligentes - -En esta sección introduciremos el concepto de Contrato Inteligente, y como la plataforma de Hyperledger Fabric maneja estos contratos. Hablaremos sobre algunos de los aspectos importantes a tener en cuenta; estos pueden ser distintos de los que aplica para otro tipo de desarrollo. - -Este ejemplo muestra como los detalles de un activo pueden ser almacenados en el ledger mismo, con el Contrato Inteligente controlando el ciclo de vida del activo. Provee funciones transaccionales para: - -- Crear un activo -- Recuperar (uno o todos) los activos -- Actualizar un activo -- Borrar un activo -- Transferir propiedad del activo entre partes. - -Este tópico aborda consideraciones de diseño comunes para los contratos inteligentes. Si quieres ir directamente al código del workshop, puedes ir directamente a [comenzar](./01-Exercise-Getting-Started-ES.md) y regresar a esta página posteriormente como referencia. - -Por favor recuerda que Hyperledger Fabric es un Blockchain Ledger y no una Base de Datos! - -[SIG - Comenzar con un Contrato Inteligente](./01-Exercise-Getting-Started-ES.md) - ---- -## Diseñar los activos y contratos - -La primera y quizás la decision mas importante es - "¿qué información necesita estar bajo el control del - ledger?". Esto es importante por varias razones. - -- El ledger es el estado compartido entre organizaciones, ¿aplica que todas las organizaciones puedan ver la información que esta siendo compartida? Ten en cuenta que las colecciones privadas de data de Fabric pueden ser usadas cuando un subconjunto de la data del ledger tiene que permanecer privada entre partes. -- Para cualquier actualización en el estado del ledger, ¿qué organizaciones deben ejecutar el contrato inteligente y 'endosar' los resultados antes para que el cambio sea considerado una transacción válida? ¿La política de endoso será fija, o basada en la data? Por ejemplo, puedes desear que la organización del propietario actual la endose, junto con la organización del regulador. Esto puede ser logrado con las capacidades de endoso basadas en estado. -- ¿Cuán grande es el tamaño de la data? Es mejor cuanto mas chica sea. Recuerda que esta data tiene que ser transferida entre muchas partes y la historia de las transacciones es mantenida en el ledger. ¿Funcionaría mejor un hash seguro salado de un documento escaneado a guardar el documento completo? -- Aunque es posible realizar consultas del estado con JSON enriquecido cuando se usa CouchDB como base de datos del estado, el peer y el ledger están optimizados para procesamiento transaccional mas que consultas. ¿Pueden las consultas ser realizadas fuera del ledger, y los resultados 'validados' mediante un contrato inteligente? - -Para cualquier tutorial de punta-a-punta existe una contrapartida entre hacer el escenario realístico, pero no suficientemente complicado. Para este tutorial definiremos la data a ser almacenada en el ledger como un activo de un único 'objeto' con los siguientes campos. Esto se ha mantenido bastante simple, pero el enfoque debería ser familiar. - -- ID: cadena de caracteres identificador unívoco -- Color: cadena de caracteres representando un color -- Size: valor numérico representando un tamaño -- Owner: cadena de caracteres representando la identidad del propietario del activo (id de la organización mas el nombre común (CN) del certificado del cliente) -- Appraised Value: valor numérico - -Probablemente no todos estos valores requieran estar en el ledger, la data podría estar almacenada en un 'oráculo' fuera del ledger que proveerá un hash de la data a ser guardada en el ledger de blockchain. - -### Claves y Consultas - -Piensa en la base de datos de estados del ledger como un repositorio de clave-valor para persistir los activos, o más genéricamente, cualquier registro de data que quieras mantener en el ledger. - -Es importante tener cuidado al elegir la 'clave' que será usada. Podrías usar claves simples tales como una clave lógica pasada desde un sistema externo, una UUID, o incluso usar la txid de la transacción que creo el activo. Las claves compuestas son también posibles. Éstas son construidas para formar una estructura jerárquica y permitir otros tipos de consultas basadas en claves. - -Una cadena de caracteres para la clave puede ser armada desde una lista de cadena de caracteres separados por el byte nulo `u+0000`. Debe haber al menos una cadena en la lista. Si solo hay una cadena, esto es referido como una clave 'simple', caso contrario, es una clave 'compuesta'. Por ejemplo puedes desear crear una clave compuesta basada en el 'tipo' de activo y el ID. Las APIs de contratos inteligentes te ayudan a crear fácilmente estas claves compuestas. - -Para claves simples, puedes hacer consultas con la misma utilizando la API `getState(key: string)`. - -Puedes consultar también por un rango de claves usando la API `getStateByRange(startKey: string, endKey: string)`. Las consultas por rangos te permiten especificar una clave de comienzo y una de fin, y regresa un iterador de todos los clave-valor que se encontraban entre esos puntos de comienzo y fin (incluidos estos). Las claves estarán ordenadas alfanuméricamente. - -Las claves compuestas proveen un mecanismo de consulta interesante ya que ofrecen una consulta de rango por clave parcial. Por ejemplo, si una clave compuesta tiene las cadenas `fruit:pineapples:supplier_fred:consignment_xx` (usamos aquí un colon para que sea fácil de leer ya que el byte nulo no lo es) entonces es posible emitir consultas con una clave puntera parcial. -Por ejemplo, para consultar por todos los registros de ananás que tiene `supplier_fred` podrías hacer la consulta utilizando la clave parcial `fruit:pineapples:supplier_fred`. - -Una manera de ver esto es visualizando las claves como si formasen una jerarquía. - -Ten en cuenta que las claves 'simple' y 'compuesta' son almacenadas de manera distinta entre ellas. Consecuentemente una consulta por una clave simple no regresará nada que esté guardado bajo una clave compuesta, a la inversa, una consulta por una clave compuesta no regresa nada que esté guardado bajo una clave simple. - -Los tipos de consultas mencionadas anteriormente están soportadas en ambas bases de datos de estado, tanto LevelDB como CouchDB, y consultan las 'claves' del repositorio clave-valor. - - -Si utilizas CouchDB, puedes también consultar por el 'valor' del par clave-valor utilizando una consulta JSON enriquecida. Esto requiere que el valor se encuentre en formato JSON (como en este tutorial). Los indices en CouchDB pueden ser provistos en el paquete del contrato inteligente para hacer que las consultas JSON sean eficientes (y esto es altamente recomendado). Aún así ten presente que las consultas basadas en 'valores' nunca serán tan eficientes como las basadas en 'clave'. - -## Funciones Transaccionales - -Veamos cuales son los diferentes tipos de funciones transaccionales que pueden ser escritos en el Contrato Inteligente. Cada uno de estos puede ser invocado desde la aplicación cliente. -- Funciones de tipo 'Evaluate' son invocadas de manera solo-lectura para consultar el estado en la base de datos del ledger en un peer específico. -- Funciones de tipo 'Submit' son invocadas para enviar una transacción a todos los peers a los que se require que endosen los cambios al ledger, resultando en una operación de escritura o una operación de lectura-escritura que es enviada al servicio de ordenamiento y finalmente ejecutada en todos los peers. - -### Aspectos Generales - -Cada función transaccional del contrato inteligente tiene que ser marcada como tal (utilizando convenciones específicas al lenguaje). Puedes también especificar si la función esta pensada para ser 'enviada' o 'evaluada'. Esto no es obligatorio pero es una indicación para el usuario. - -Cada función deberá considerar cómo manipulará la data para ordenarla al formato requerido para el ledger. - -Cada función debe asegurarse que cada estado inicial es el correcto. Por ejemplo, antes de transferir un activo de Alice a Bob, debe asegurar que Alice es la propietaria, y que Alice es la identidad que esta enviando la transacción de transferencia. - -### Funciones de Creación - -Considera en la función de creación si quieres pasar individualmente cada elemento de data o un objeto completamente formado. Esto es mas una cuestión de preferencia personal, sin embargo, recuerda que cualquier identificador unívoco debe ser creado por fuera del contrato inteligente. La transacción será ejecutada en múltiples peers y los resultados deben coincidir por lo que no pueden ser usados cualquier función de elección aleatoria u otros procesos no determinísticos. - -Con frecuencia hay elementos extras de data (tales como la organización que envía) que deben ser agregados. - -### Recuperar - -Es una buena idea pensar de antemano en los tipos de operaciones de recuperación o consulta que harán falta. ¿Puede la estructura de la clave ser creada para permitir consultas por rangos? - -Si son requeridas consultas con JSON enriquecido, procura hacerlas lo más simple posible e incluye índices. Asegúrate además que si deseas hacer una consulta con JSON enriquecido que involucra la misma data como la 'clave' que este incluído en la estructura JSON como parte del 'valor'. - -Existe un ejemplo de consultas de tipo obtener-todo en este workshop. Por favor considera que con el paso del tiempo esto podría recibir una gran cantidad de data que conlleva un costo en performance, ¡por lo cual generalmente no es recomendado! - -Para consultas avanzadas, considera crear un data store aguas abajo optimizado para el tipo de consultas que necesitas. El [ejemplo de data off-chain](https://github.com/hyperledger/fabric-samples/tree/main/off_chain_data) demuestra como construir un data store aguas abajo basado en los eventos de bloques. - -### Leer-tus-propias-escrituras y conflictos - -Las actualizaciones que una función transaccional hace al estado, no son realizadas inmediatamente; conforman un juego de cambios que deben ser endosados y ordenados. Este comportamiento asíncrono genera 2 consecuencias importantes. - -Si la data bajo una clave es actualizada, y luego consultada *en la misma función del contrato inteligente* la data regresada sera el valor *original* - y no el valor actualizado. - -Adicionalmente, puedes llegar a observar transacciones invalidadas con un error 'MVCC Conflict': esto significa que dos funciones transaccionales se ejecutaron al mismo tiempo y trataron de leer y actualizar las mismas claves. La primera transacción a ser ordenada en un bloque será validada, mientras que la segunda transacción será invalidada ya que la entrada de lectura ha cambiado desde la ejecución del contrato. Diseña tus claves y aplicaciones para que las mismas claves no sean actualizadas concurrentemente. Si esta es una ocurrencia inusual simplemente compénsala en la aplicación, por ejemplo, enviando nuevamente la transacción. - -## Registro de Auditoría vs Registro de Activos - -Una decisión importante a realizar es si el estado que se guarda en el ledger representa un 'registro de auditoría' de las actividades o la 'fuente de la verdad' del activo mismo. Como se observará en los ejemplos siguientes, almacenar la información de los activos es conceptualmente sencillo pero se debe tener en cuenta que esta es una base de datos distribuida mas que solo una base de datos. - -Almacenar un tipo de registro de auditoría puede funcionar bien con el concepto de ledger. La 'fuente de la verdad' aquí es que cierta acción fue tomada y su resultado. Por ejemplo la propiedad de un activo cambió. Los detalles del activo en sí pueden ser almacenados fuera del ledger (off-chain). Esto si significa que se debe considerar mas infraestructura alrededor del ledger pero vale la pena contemplarlo si la principal justificación de negocio es el registro de auditoría. Por ejemplo, seguir el estado de un proceso y como se movió de un estado al siguiente. - -Para ayudar con la integración de otros sistemas bien vale la pena emitir eventos desde la función transaccional. Estos eventos estarán disponibles para las aplicaciones cliente cuando la transacción este finalmente realizada. Estos pueden ser muy útiles para disparar otros procesos. - -## ¿Es un Contrato Inteligente o un Chaincode? - -Simplemente ambos - los términos han sido utilizados en la historia de Fabric casi que como equivalentes, Chaincode fue el nombre original, pero Contrato Inteligente es un término común en blockchain. La clase/estructura que ha sido extendida/implementada en el código se llama `Contract`. - -El objetivo es estandarizar en: -- los Contratos Inteligentes son las clases/estructuras - el código - que escribes en Go/JavaScript/TypeScript/Java etc. -- éstos son luego empaquetadas y se ejecutan dentro de un contenedor de Chaincode (imagen de chaincode / ambiente de ejecución de chaincode dependiendo exactamente en el formato del paquete) -- la definición del chaincode es más que tan solo el código del Contrato Inteligente, ya que incluye tales cosas como los índices de CouchDB, y la política de endoso. - -## Empaquetado - -En la versión 1.x de Hyperledger Fabric, y aún soportado como 'el ciclo de vida antiguo' en v2.x, el formato de paquete de chaincode CDS fue utilizado. El 'nuevo ciclo de vida' de v2.x debe ser utilizado de ahora en más - con el formato estándar `tar.gz`. Usar `tar` y `gzip` son técnicas estándar para herramientas estándar. Con lo cual la cuestión principal pasa a ser qué es lo que irá dentro de esos archivos y cuándo / cómo son usados. diff --git a/full-stack-asset-transfer-guide/docs/SmartContractDev/00-Introduction.md b/full-stack-asset-transfer-guide/docs/SmartContractDev/00-Introduction.md deleted file mode 100644 index 2c11f2c1..00000000 --- a/full-stack-asset-transfer-guide/docs/SmartContractDev/00-Introduction.md +++ /dev/null @@ -1,119 +0,0 @@ -# Smart Contract Development - -In this section, we'll introduce the concept of the Smart Contract, and how the Hyperledger Fabric platform handles these contracts. We'll talk about some of the important aspects to keep in mind; these can be different from other types of development. - -This example shows how details of an asset may be stored in the ledger itself, with the Smart Contract controlling the asset's lifecycle. It provides transaction functions to - -- Create an asset -- Retrieve (one or all) assets -- Update an asset -- Delete an asset -- Transfer ownership between parties - -This topic addresses common design considerations for smart contracts. If you want to dive straight into the workshop code, feel free to skip straight to the [getting started](./01-Exercise-Getting-Started.md) and come back to this page as a reference later. - -Please remember that Hyperledger Fabric is a Blockchain Ledger and not a Database! - -[NEXT - Getting Stared with Code](./01-Exercise-Getting-Started.md) - ---- -## Design the assets and contracts - -An initial and perhaps the most important decision is - "what information needs to be under the ledger's control?". This is important for several reasons. - -- The ledger is the shared state between organizations, is the information being shared applicable for all organizations to see? Note that Fabric's private data collections can be used when a subset of the ledger data needs to remain private between parties. -- For any ledger state updates, which organizations need to execute the smart contract and 'endorse' the results before the change is considered a valid transaction? Is the endorsement policy fixed, or based on the data? For example you may want the current asset owner's organization to endorse, along with a regulator organization. This can be accomplished with Fabric's state-based endorsement capabilities. -- How large is the amount of data? The smaller the better! Remember this data needs to be transferred between many parties and the history of transactions is preserved on the ledger. Would a salted secure hash of a scanned document work rather than the entire document? -- Though rich JSON query of the state is possible when using CouchDB as a state database, the peer and its ledger are optimized for transaction processing rather than query. Can queries be performed off the ledger, and the results 'validated' via a smart contract? - -For any end-to-end tutorial there is a trade-off between making the scenario realistic, but not sufficiently complicated. For this tutorial, we'll define the data stored on the ledger as being a single asset 'object' with the following fields. This has been kept very simple, but the approach should be familiar. - -- ID: string unique-identifier -- Color: string representing a color -- Size: numerical value representing a size -- Owner: string representing the identity of the asset owner (organization id plus common name from the client's certificate) -- Appraised Value: numerical value - -Arguably not all these values need to be on the ledger, the data could be stored in an off-ledger 'oracle' that provides a hash of the data to store on the blockchain ledger. - -### Keys and Queries - -Think of the ledger state database as being a key-value store to persist assets, or more generally, any data record that you want to maintain on the ledger. - -It is important to take care in choosing the 'key' that will be used. You could use simple keys such as a logical key passed in from an external system, a UUID, or even use the txid of the transaction that created the asset. Composite keys are also possible. These are constructed to form a hierarchical structure and enable additional types of key-based queries. - -A key string can be formed from a list of strings, separated by the `u+0000` nil byte. There must be at least one string in the list. If there is only one string, this is referred to as `simple` key, otherwise, it is a `composite` key. For example you may want to create a composite key based on the asset 'type' and ID. The smart contract APIs help you easily create composite keys. - -For simple keys, you can query based on the key using the API `getState(key: string)`. - -You can also query a range of keys using the API `getStateByRange(startKey: string, endKey: string)`. Range queries allow you to specify a start and end key, and return an iterator of all key-values between those start and end points (inclusively). The keys are ordered in alphanumeric order. - -Composite keys provide an interesting query mechanism as they offer a range query by partial key. For example, if a composite key has the strings `fruit:pineapples:supplier_fred:consignment_xx` (using a colon here to make it easier to read, as the nil byte isn't easy to read) then it is possible to issue queries with a leading partial key. -For example, to query all the pineapple records held by `supplier_fred` you could query on the partial key `fruit:pineapples:supplier_fred`. - -A way of thinking about this is to visualize the keys as forming a hierarchy. - -Note that the 'simple' and 'composite' keys are held distinct from each other. Therefore a query on a simple key won't return anything held under a composite key, and conversely a composite key query won't return anything held under a simple key. - -The above types of queries are supported on both LevelDB and CouchDB state databases and query the 'keys' of the key-value store. - -If you use CouchDB, you can also query on the 'value' of the key-value pair using a rich JSON query. This requires the value be in JSON format (as in this tutorial). CouchDB indices can be provided in the smart contract package to make JSON queries efficient (and strongly recommended). But keep in mind that 'value' based queries will never be as efficient as 'key' based queries. - -## Transaction Functions - -Let's look at the separate transaction function types that can be written on the Smart Contract. Each one of these can be invoked from the client application. -- 'Evaluate' functions are invoked in a read-only manner to query the ledger state database on a specific peer. -- 'Submit' functions are invoked to submit a transaction to all the peers that are needed to endorse changes to the ledger, resulting in a write operation or read-write operation that gets submitted to the ordering service and ultimately committed on all peers. - -### General Aspects - -Each smart contract transaction function needs to be marked as such (using language-specific conventions). You can also specify if the function is meant to be 'submitted' or 'evaluated'. This is not enforced but is an indication to the user. - -Each function will need to consider how it handles data to marshal into the format needed for the ledger. - -Each function needs to ensure that any initial state is correct. For example, before transferring an asset from Alice to Bob, ensure that Alice does own the asset, and that Alice is indeed the identity submitting the transfer transaction. - -### Creation Functions - -Consider in the create function if you want to pass in the individual data elements or a fully formed object. This is largely a matter of personal preference; remember though that any unique identifier must be created outside of the smart contract. Any form of random choice or other non-deterministic processes can not be used since the transaction will be executed on multiple peers and the results must match. - -Often there are extra elements of data (such as the submitting organization) that need to be added. - -### Retrieval - -It is a good idea to think ahead of the types of retrieval operations that are needed. Can the key structure be created to allow for range queries? - -If rich JSON queries are required, aim to make these as simple as possible and include indexes. Also ensure that if you wish to do a rich JSON query that involves the same data as the 'key' that it is included in the JSON structure as part of the 'value'. - -There is an example of get-all type queries in this workshop. Please consider that over time this could get a very large amount of data with a performance cost, therefore it is generally not recommended! - -For advanced queries, considering creating a downstream data store optimized for the types of queries that you need. The [off-chain data sample](https://github.com/hyperledger/fabric-samples/tree/main/off_chain_data) demonstrates how to build a downstream data store based on block events. - -### Reading-your-own-writes and conflicts - -The updates a transaction function makes to the state, aren't actioned immediately; they form a set of changes that must be endorsed and ordered. There are two important consequences of this asynchronous behaviour. - -If data under a key is updated, and then queried *in the same smart contract function* the returned data will be the *original* value - not the updated value. - -Additionally, you may see transactions invalidated with a 'MVCC Conflict' error: this means that two transaction functions have executed at the same time and attempted to read and update the same keys. The first transaction to be ordered in a block will get validated, while the second transaction will get invalidated since a read input has changed since contract execution. Design your keys and applications so that the same keys will not get updated concurrently. If this is a rare occurrence then you could simply compensate for it in the application, for example by re-issuing the transaction. - -## Audit Trails vs Asset Store - -An important decision to make is whether the state held on the ledger is representing an 'audit trail' of activity or the 'source of truth' of the actual assets. Storing the information about the assets, as shown in the following samples, is conceptually straightforward but keep in mind that this is a distributed database, rather than a database. - -Storing a form of audit trail can work well with the ledger concept. The 'source of truth' here is that a certain action was taken and it's results. For example the ownership of an asset changed. Details of the actual asset may be stored off chain. This does need more infrastructure provided around the ledger but is worth considering if the primary business reason is for audit purposes. For example, tracking the state of a process and how it moved from one state to the next. - -To help with the integration of other systems it is well worth issuing events from the transaction functions. These events will be available to the client applications when the transaction is finally committed. These can be very useful in triggering other processes. - -## Is it Smart Contract or Chaincode? - -Simply both - the terms have been used in Fabric history almost interchangeable; Chaincode was the original name, but then Smart Contracts is a common a blockchain term. The class/structure that is extended/implemented in code is called `Contract`. - -The aim is to standardize on -- the Smart Contract(s) are classes/structures - the code - that you write in Go/JavaScript/TypeScript/Java etc. -- these are then packaged up and run inside a Chaincode-container (chaincode-image / chaincode-runtime depending on exactly the format of the packaging) -- the chaincode definition is more than just the Smart Contract code, as it includes things such as the CouchDB indexes, and the endorsement policy - -## Packaging - -In Hyperledger Fabric v1.x and still supported as 'the old lifecycle' in v2.x, the CDS chaincode package format was used. The v2.x 'new lifecycle' should be used now - with standard `tar.gz` format. Using `tar` and `gzip` are standard techniques with standard tools. Therefore the main issue becomes what goes into those files and when/how are they used. diff --git a/full-stack-asset-transfer-guide/docs/SmartContractDev/01-Exercise-Getting-Started-ES.md b/full-stack-asset-transfer-guide/docs/SmartContractDev/01-Exercise-Getting-Started-ES.md deleted file mode 100644 index 115191f0..00000000 --- a/full-stack-asset-transfer-guide/docs/SmartContractDev/01-Exercise-Getting-Started-ES.md +++ /dev/null @@ -1,351 +0,0 @@ -# Comenzar con un Contrato Inteligente - -[ANTERIOR - Introducción](./00-Introduction-ES.md) <==> [SIGUIENTE - Agregar una Función Transaccional](./02-Exercise-Adding-tx-function-ES.md) - ---- - -Asegúrate de haber replicado/clonado el workshop: - -```bash -git clone https://github.com/hyperledger/fabric-samples.git fabric-samples -cd fabric-samples/full-stack-asset-transfer-guide - -export WORKSHOP_PATH=$(pwd) -``` - -Primero por favor revisa que tienes las [herramientas requeridas](../../SETUP.md) para la parte de dev de este workshop (docker, just, weft, node.js, y binario del Fabric peer). Para cerciorarse ejecuta el script `check.sh` - -``` -${WORKSHOP_PATH}/check.sh -``` - -Vayamos directo a crear el código para administrar un 'activo'; es mejor tener dos (2) ventanas abiertas, una para correr la 'FabricNetwork' y otra para 'ChaincodeDev'. Puedes querer abrir una tercera ventana para visualizar los logs de la red de Fabric. - -## Inicia la Infraestructura de Fabric - -Estamos utilizando MicroFab para la infraestructura de Fabric ya que es un único contenedor que es fácil de iniciar. -El contenedor de MicroFab incluye un nodo del servicio de ordenamiento y un proceso peer que esta pre configurado para crear un channel e invocar chaincodes externos. -Tiene ademas credenciales para una organización `org1`, que sera utilizada para ejecutar el peer. Usaremos un usuario administrador de `org1` para interactuar con el entorno. - -Usaremos recetas de `just` para ejecutar múltiples comandos. Las recetas `just` son similares a make `make` pero mas fáciles de comprender. Puedes abrir el [justfile](../../justfile) en el directorio raíz del proyecto para ver qué comandos son ejecutados con cada receta. - -Inicia el contenedor de MicroFab ejecutando la receta `just`. Esto establecerá algunas propiedades para el ambiente MicroFab e iniciará el contenedor docker de MicroFab. - -```bash -just microfab -``` - -Esto arrancará el contenedor docker (lo descargara automáticamente si es necesario), y adicionalmente escribirá algunos archivos de configuración/data en el directorio `_cfg/uf`. - -```bash -ls -1 _cfg/uf - -_cfg -_gateways -_wallets -org1admin.env -org2admin.env -``` - -Un archivo `org1admin.env` es generado que contiene las variables de entorno necesarias para ejecutar aplicaciones _con la identidad de org1 admin_. Una segunda organización es creada, con un `org2admin.env` - esto es para ejercicios más adelante y no es requerido para el actual. - -Veamos cuáles son las variables de entorno y usemos source para establecer las mismas: - -```bash -source _cfg/uf/org1admin.env -cat _cfg/uf/org1admin.env -``` - -Veremos establecidas éstas variables de entorno: - -```bash -# valores de ejemplo -export CORE_PEER_LOCALMSPID=org1MSP -export CORE_PEER_MSPCONFIGPATH=/workshop/full-stack-asset-transfer-guide/_cfg/uf/_msp/org1/org1admin/msp -export CORE_PEER_ADDRESS=org1peer-api.127-0-0-1.nip.io:8080 -export FABRIC_CFG_PATH=/workshop/full-stack-asset-transfer-guide/config -export CORE_PEER_CLIENT_CONNTIMEOUT=15s -export CORE_PEER_DELIVERYCLIENT_CONNTIMEOUT=15s -``` - -Ahora revisemos los tres directorios creados `_msp`, `_gateways`, `_wallets`. Si no tienes mucho tiempo puedes [saltear a la siguiente sección para empaquetar e implementar un chaincode](#empaquetar-e-implementar-el-chaincode-a-fabric). - -Primero, el directorio `_msp` contiene los credenciales necesarios del membership services provider (MSP) para ejecutar los comandos CLI del Fabric Peer como org1 admin, incluyendo el certificado público del usuario y la llave privada para firmar las transacciones. La ubicación del MSP esta referenciado en la variable de entorno `CORE_PEER_MSGCONFIGPATH` y contiene los subdirectorios de credenciales que son esperados por el comando CLI del Peer. - -En segundo lugar el directorio `_gateways` contiene dos archivos JSON, uno por organización. Este archivo contiene los detalles de la ruta url del Peer al que se pueden conectar los clientes. Los SDKs de clientes Fabric anteriores necesitaban que toda la información estuviese en este archivo, pero los nuevos "Gateway SDKs" quitaron la necesidad para tanto detalle. Los nuevos SDKs para Gateway solo necesitan la ruta del peer y su configuración de TLS. Puedes ver este [código ejemplo](../../applications/ping-chaincode/src/fabric-connection-profile.ts) para poder analizar este archivo fácilmente para el SDK de Gateway. - -Por último esta el directorio `_wallets` - que tiene tres subdirectorios, uno para cada organización a saber la de Ordering, Organization 1, y Organization 2. Estos directorios contienen archivos `*.id` que tienen los detalles de identidades y sus respectivos credenciales, parecido al contenido del MSP, pero en un formato JSON que las aplicaciones pueden analizar fácilmente: - -``` -_wallets -├── Orderer -│   └── ordereradmin.id -├── org1 -│   ├── org1admin.id -│   └── org1caadmin.id -└── org2 - ├── org2admin.id - └── org2caadmin.id -``` - -`org1admin.id` contiene los credenciales para enviar transacciones desde un administrador de org1. -`org1caadmin.id` contiene los credenciales para crear identidades adicionales en la Autoridad Certificante (CA) de org1. - -Tenga en cuenta que cuando Microfab comenzó lanzó automáticamente una Autoridad Certificante que creó estas identidades y sus respectivas credenciales. - -Elija uno de los archivos de id y observa el contenido JSON del mismo incluyendo el certificado público y la llave privada: - -```bash -cat _cfg/uf/_wallets/org1/org1admin.id | jq -``` - -Verás el contenido de org1admin.id: - -```bash -{ - "credentials": { - "certificate": "-----BEGIN CERTIFICATE-----\n xxxx \n-----END CERTIFICATE-----\n", - "privateKey": "-----BEGIN PRIVATE KEY-----\n xxxx \n-----END PRIVATE KEY-----\n" - }, - "mspId": "org1MSP", - "type": "X.509", - "version": 1 -} -``` - -Esta información puede ser utilizada por las aplicaciones cliente. Ver [este código ejemplo](../../applications/ping-chaincode/src/jsonid-adapter.ts) para entender como puedes analizar este archivo para usarlo con el gateway. - -En este punto quizás quieras ejecutar `docker logs -f microfab` en una ventana separada para visualizar la actividad - no necesitas configurar nada específico aquí.. - -## Empaquetar e implementar el chaincode a Fabric - -Utilizaremos el patrón Chaincode-As-A-Service (CCAAS) para este chaincode. -Con este patrón, el peer de Fabric peer no inicia un chaincode implementado. -En su lugar, ejecutaremos el chaincode como un proceso externo para que podamos fácilmente y localmente ejecutar los comandos para iniciarlo, detenerlo, actualizarlo y depurarlo. -Sin embargo, aún debemos indicarle al peer dónde se esta ejecutando el chaincode. Esto lo logramos implementando un paquete de chaincode que incluye solamente, en vez del verdadero código fuente del mismo, el nombre del chaincode y la dirección del mismo. - -### Empaquetar e implementar el chaincode utilizando la receta `just`. - -```bash -just debugcc -``` - -Veras el id del chaincode y los pasos de implementación como resultado. - -### Detalles de este proceso de empaquetar e implementar - -Si te gustaría entender en mas detalle el proceso de empaquetar e implementar chaincodes puedes hacer manualmente los pasos a continuación. Caso contrario puedes [ir hacia adelante a la sección para ejecutar el chaincode](#ejecuta-el-chaincode-localmente). - -Los paquetes de chaincode en Fabric son archivos en formato `tgz` que contienen dos archivos: - -- `metadata.json` - la etiqueta y tipo del chaincode -- `code.tar.gz` - artefactos fuentes del chaincode - -Crea el archivo `metadata.json` primero, esto le indica al Peer el tipo de chaincode y la etiqueta a usar para referirse a él mas adelante. - -```bash -cat << METADATAJSON-EOF > metadata.json -{ - "type": "ccaas", - "label": "asset-transfer" -} -METADATAJSON-EOF -``` - -Crea el archivo `code.tar.gz` - para el Chaincode-as-a-service, este archivo contendrá un solo archivo JSON `connection.json`. El proceso de empaquetar tradicional de Fabric incluiría aquí todo el código fuente del chaincode. En este caso, necesitamos que el archivo JSON contenga el URL donde el peer encontrará el chaincode y un limite de tiempo de espera. Note que este es un hostname especial para que el peer dentro del contenedor docker pueda localizar al chaincode ejecutándose en el sistema host. - -``` -cat << CONNECTIONJSON-EOF > connection.json -{ - "address":"host.docker.internal:9999", - "dial_timeout":"15s" -} -CONNECTIONJSON-EOF -``` - -Podemos ahora construir el paquete real. Crea un archivo code.tar.gz que contendrá el archivo connection.json. - -```bash -tar -czf code.tar.gz connection.json -``` - -Crea el archivo empaquetado final del chaincode. - -```bash -tar -czf asset-transfer.tgz metadata.json code.tar.gz -``` - -Utilizaremos los comandos CLI del peer para instalar e implementar el chaincode. Éste estará 'implementado' cuando se indique acuerdo para hacerlo y luego se asigne a un channel: - -``` -source _cfg/uf/org1admin.env - -peer lifecycle chaincode install asset-transfer.tgz -``` - -El ChaincodeID que es devuelto por este comando de instalación debe ser almacenado, típicamente esto es mejor como una variable de entorno. - -```bash -export CHAINCODE_ID=$(peer lifecycle chaincode calculatepackageid asset-transfer.tgz) -``` - -Paso siguiente, define el chaincode en el channel de blockchain aprobándolo y asignándoselo. Si ya lo has implementado utilizando la receta `just` de mas arriba, debes incrementar el número de `--sequence` a `2`. - -```bash -peer lifecycle chaincode approveformyorg --channelID mychannel -o $ORDERER_ENDPOINT --name asset-transfer -v 0 --package-id $CHAINCODE_ID --sequence 2 --connTimeout 15s -peer lifecycle chaincode commit --channelID mychannel -o $ORDERER_ENDPOINT --name asset-transfer -v 0 --sequence 2 --connTimeout 15s -``` - -## Ejecuta el chaincode localmente - -Utilizaremos el contrato ejemplo en typescript ya escrito en `$WORKSHOP_PATH/contracts/asset-transfer-typescript`. Siéntete libre de revisar el código del contrato en [contracts/asset-transfer-typescript/src/assetTransfer.ts](../../contracts/asset-transfer-typescript/src/assetTransfer.ts). Podrás observar allí la implementación de funciones del contrato tales como `CreateAsset()` y `ReadAsset()`. - -Utiliza otra ventana de terminal para el chaincode. Asegúrate que la terminal este definida con las mismas variables de entorno como en la primera terminal: - -``` -cd fabric-samples/full-stack-asset-transfer-guide -export WORKSHOP_PATH=$(pwd) -export PATH=${WORKSHOP_PATH}/bin:$PATH -export FABRIC_CFG_PATH=${WORKSHOP_PATH}/config -``` - -Como con cualquier módulo en typescript debemos ejecutar `npm install` para administrar las dependencias del chaincode y luego construir (compilar) el código typescript del chaincode a javascript. - -``` -cd contracts/asset-transfer-typescript - -npm install - -npm run build -``` - -Una forma fácil de verificar que el contrato ha sido construido correctamente es generar la metadata del contrato ('Contract Metadata') en un archivo `metadata.json`. Esta es una definición del contrato y de los tipos de datos que éste retornó que es agnóstica a lenguajes. Toma prestado conceptos de OpenAPI utilizados en la definición de REST APIs. Es también muy útil para compartir con equipos que están escribiendo aplicaciones cliente para que conozcan la estructura de la data y las funciones de las transacciones que pueden invocar. -Como es un documento JSON, puede ser utilizado para crear otros recursos. - -El comando que genera la metadata ha sido colocado en el `package.json`: - -``` -npm run metadata -``` - -Revisa el archivo `metadata.json` generado y observa el resumen de la información del contrato, las funciones de transacciones y los tipos de datos. Esta información puede ser obtenida también en el momento de ejecución y es una buena forma de probar la implementación. - -## Desarrollo Iterativo y Pruebas - -**Todos los pasos hasta ahora han sido por única vez. De aquí en adelante puedes iterar sobre el desarrollo de tu contrato** - -Comencemos el módulo de tu nodo de Contrato Inteligente desde la ventana de terminal de tu contrato. Recuerda que el `CHAINCODE_ID` y el `CHAINCODE_SERVER_ADDRESS` son las únicas piezas de información que se necesita. - -Nota: Usa tu específico CHAINCODE_ID obtenido anteriormente; el `CHAINCODE_SERVER_ADDRESS` es diferente - esto es porque en este caso lo esta indicando al chaincode donde escuchar a conexiones entrantes desde el Peer. Usaremos el puerto 9999 de la maquina local. - -``` -source ${WORKSHOP_PATH}/_cfg/uf/org1admin.env - -# si ejecutaste el justfile de arriba, estos valores ya estarán exportados, pero puedes querer verificar que tengan los siguientes valores: -export CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999 -export CHAINCODE_ID=$(peer lifecycle chaincode calculatepackageid asset-transfer.tgz) - -npm run start:server-debug -``` - -### Ejecutar algunas transacciones - -Elije una ventana de terminal desde donde ejecutar las transacciones; inicialmente utilizaremos el CLI del `peer` para ejecutar los comandos. - -Si es una nueva ventana de terminal configura las variables de entorno: - -``` -cd fabric-samples/full-stack-asset-transfer-guide -export WORKSHOP_PATH=$(pwd) -export PATH=${WORKSHOP_PATH}/bin:$PATH -export FABRIC_CFG_PATH=${WORKSHOP_PATH}/config -``` - -Asegúrate que tanto el binario del peer como el directorio config estén configurados (ejecuta el script `${WORKSHOP_PATH}/check.sh` para verificar). - -Configura el contexto de ambiente para hacer de Administrador Org 1. - -``` -source ${WORKSHOP_PATH}/_cfg/uf/org1admin.env -``` - -Usa el CLI del peer para ejecutar comandos básicos de consulta contra el contrato. Por ejemplo, revisar la metadata del contrato (si tienes jq, es mas fácil leer si haces pipe de los resultados a jq). Usa uno de estos comandos: - -``` -peer chaincode query -C mychannel -n asset-transfer -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' -peer chaincode query -C mychannel -n asset-transfer -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' | jq -``` - -Creemos un activo con ID=001: - -``` -peer chaincode invoke -C mychannel -o orderer-api.127-0-0-1.nip.io:8080 -n asset-transfer -c '{"Args":["CreateAsset","{\"ID\":\"001\", \"Color\":\"Red\",\"Size\":52,\"Owner\":\"Fred\",\"AppraisedValue\":234234}"]}' --connTimeout 15s -``` - -Si estas observando los logs de MicroFab veras que el peer grabo un nuevo bloque al ledger. - -Procede ahora a leer ese activo: - -``` -peer chaincode query -C mychannel -n asset-transfer -c '{"Args":["ReadAsset","001"]}' -``` - -Veras que el activo es regresado: - -``` -{"AppraisedValue":234234,"Color":"Red","ID":"001","Owner":"{\"org\":\"org1MSP\",\"user\":\"Fred\"}","Size":52} -``` - -### Hacer un cambio y re-ejecutar el código - -Si invocamos un comando de consulta en un activo que no existe, por ejemplo 002, obtendremos un error: - -``` -peer chaincode query -C mychannel -n asset-transfer -c '{"Args":["ReadAsset","002"]}' -``` - -da un error: - -``` -Error: endorsement failure during query. response: status:500 message:"Sorry, asset 002 has not been created" -``` - -Supongamos que queremos cambiar ese mensaje de error por otra cosa. - -- Detener el chaincode que se esta ejecutando (CTRL-C en la terminal del chaincode) -- Abrir el archivo `src/assetTransfer.ts` en el editor de tu preferencia -- Alrededor de la linea 51, encuentra el string del error y haz una modificación. Recuerda guardar el cambio. -- Compila nuevamente el contrato en typescript: - -``` -npm run build -``` - -Puedes arrancar nuevamente el contrato como hiciste antes - -``` -npm run start:server-debug -``` - -Y ejecutar la misma consulta visualizando el mensaje de error actualizado: - -``` -peer chaincode query -C mychannel -n asset-transfer -c '{"Args":["ReadAsset","002"]}' -``` - -## Depurar el código - -Como el chaincode fue iniciado con la configuración de depuración de Node.js, se puede conectar al proceso un depurador de node.js. Por example VSCode trae un buen depurador de typescript/node.js. - -Si seleccionas el tab de depurar, y abres las configuraciones de depuración, agrega la configuración "Asociar al proceso node". -VSCode te mostrara el modelo. El puerto por defecto debería ser suficiente. -Puedes entonces arrancar la depuración 'asociada al proceso', y seleccionar el proceso que se quiere depurar. - -Recuerda establecer un punto de quiebre al comienzo de la función transaccional que quieres depurar. - -Presta atención a: - -- VSCode usa node, así que ten cuidado para seleccionar el proceso correcto -- recuerda que existe un límite de tiempo de la transacción cliente/fabric, mientras tengas al chaincode detenido en el depurador, el límite de tiempo sigue 'contando' - -Revisa [Probar y Depurar Contratos](./03-Test-And-Debug-Reference-ES.md) para mas detalles e información en otros lenguajes. diff --git a/full-stack-asset-transfer-guide/docs/SmartContractDev/01-Exercise-Getting-Started.md b/full-stack-asset-transfer-guide/docs/SmartContractDev/01-Exercise-Getting-Started.md deleted file mode 100644 index a9e7aab4..00000000 --- a/full-stack-asset-transfer-guide/docs/SmartContractDev/01-Exercise-Getting-Started.md +++ /dev/null @@ -1,351 +0,0 @@ -# Getting Started with a Smart Contract - -[PREVIOUS - Introduction](./00-Introduction.md) <==> [NEXT Adding a Transaction Function](./02-Exercise-Adding-tx-function.md) - ---- - -Make sure you have cloned the workshop: - -```bash -git clone https://github.com/hyperledger/fabric-samples.git fabric-samples -cd fabric-samples/full-stack-asset-transfer-guide - -export WORKSHOP_PATH=$(pwd) -``` - -First please check you've got the [required tools](../../SETUP.md) needed for the dev part of this workshop (docker, just, weft, node.js, and Fabric peer binary). To double check run the `check.sh` script - -``` -${WORKSHOP_PATH}/check.sh -``` - -Let's dive straight into creating some code to manage an 'asset'; best to have two windows open, one for running the 'FabricNetwork' and one for 'ChaincodeDev'. You may wish to open a third to watch the logs of the running Fabric Network. - -## Start the Fabric Infrastructure - -We're using MicroFab for the Fabric infrastructure as it's a single container that is fast to start. -The MicroFab container includes an ordering service node and a peer process that is pre-configured to create a channel and call external chaincodes. -It also includes credentials for an `org1` organization, which will be used to run the peer. We'll use an `org1` admin user when interacting with the environment. - -We'll use `just` recipes to execute multiple commands. `just` recipes are similar to `make` but simpler to understand. You can open the [justfile](../../justfile) in the project root directory to see which commands are run with each recipe. - -Start the MicroFab container by running the `just` recipe. This will set some properties for the MicroFab environment and start the MicroFab docker container. - -```bash -just microfab -``` - -This will start the docker container (automatically download it if necessary), and also write out some configuration/data files in the `_cfg/uf` directory. - -```bash -ls -1 _cfg/uf - -_cfg -_gateways -_wallets -org1admin.env -org2admin.env -``` - -A file `org1admin.env` is written out that contains the environment variables needed to run applications _as the org1 admin identity_. A second organization is created, with a `org2admin.env` - this is for later exercises and is not needed at the moment. - -Let's take a look at the environment variables and source the file to set the environment variables: - -```bash -source _cfg/uf/org1admin.env -cat _cfg/uf/org1admin.env -``` - -You'll see these environment variables set: - -```bash -# sample contents -export CORE_PEER_LOCALMSPID=org1MSP -export CORE_PEER_MSPCONFIGPATH=/workshop/full-stack-asset-transfer-guide/_cfg/uf/_msp/org1/org1admin/msp -export CORE_PEER_ADDRESS=org1peer-api.127-0-0-1.nip.io:8080 -export FABRIC_CFG_PATH=/workshop/full-stack-asset-transfer-guide/config -export CORE_PEER_CLIENT_CONNTIMEOUT=15s -export CORE_PEER_DELIVERYCLIENT_CONNTIMEOUT=15s -``` - -Next let's look at the three directories that are created `_msp`, `_gateways`, `_wallets`. If you are short on time you can [skip ahead to the next section to package and deploy a chaincode](#package-and-deploy-chaincode-to-fabric). - -Firstly the `_msp` directory contains the membership services provider (MSP) credentials necessary to run the Fabric Peer CLI commands as the org1 admin, including the user's public certificate and private key for signing transactions. The MSP location is referenced in the `CORE_PEER_MSGCONFIGPATH` environment variable and contains the credential subdirectories expected by the Peer CLI command. - -Secondly the `_gateways` directory contains two JSON files, one per organization. This file contains details of the Peer's endpoint url to connect clients to. Older Fabric Client SDKs would need all the information in this file, but the new "Gateway SDKs" remove the need for all the detail. The new Gateway SDKs just need the peer's endpoint and TLS configuration. See this [example code](../../applications/ping-chaincode/src/fabric-connection-profile.ts) on how to parse this file easily for the Gateway SDK. - -Third is the `_wallets` directory - there are three subdirectories, one each for the Ordering Organization, Organization 1, and Organization 2. These directories contain `*.id` files that contain details of identities and their respective credentials, similar to the MSP content, but in a JSON format that applications can more easily parse: - -``` -_wallets -├── Orderer -│   └── ordereradmin.id -├── org1 -│   ├── org1admin.id -│   └── org1caadmin.id -└── org2 - ├── org2admin.id - └── org2caadmin.id -``` - -`org1admin.id` contains the credentials for submitting transactions from an org1 admin. -`org1caadmin.id` contains the credentials for creating additional identities in the org1 Certificate Authority (CA). - -Note that when MicroFab started it automatically launched a Certificate Authority that created these identities and their respective credentials. - -Pick one of the id files and look at the JSON content including the public certificate and private key: - -```bash -cat _cfg/uf/_wallets/org1/org1admin.id | jq -``` - -You'll see the contents of org1admin.id: - -```bash -{ - "credentials": { - "certificate": "-----BEGIN CERTIFICATE-----\n xxxx \n-----END CERTIFICATE-----\n", - "privateKey": "-----BEGIN PRIVATE KEY-----\n xxxx \n-----END PRIVATE KEY-----\n" - }, - "mspId": "org1MSP", - "type": "X.509", - "version": 1 -} -``` - -This information then can be used by the client applications. See [this example code](../../applications/ping-chaincode/src/jsonid-adapter.ts) for how you can directly parse this file to use with the gateway. - -At this point you may wish to run `docker logs -f microfab` in a separate window to watch the activity - you don't need to setup anything specific here. - -## Package and deploy chaincode to Fabric - -We are going to use the Chaincode-As-A-Service (CCAAS) pattern for chaincode. -With the CCAAS pattern, the Fabric peer does not launch a deployed chaincode. -Instead, we will run chaincode as an external process so that we can easily start, stop, update, and debug the chaincode locally. -But we still need to tell the peer where the chaincode is running. We do this by deploying a chaincode package that only includes the name of the chaincode and chaincode address, rather than the actual chaincode source code. - -### Package and deploy chaincode using `just` recipe. - -```bash -just debugcc -``` - -You will see the chaincode id and deployment steps returned. - -### Details of this packaging and deployment - -If you would like to understand chaincode packaging and deployment process in more detail you can walk through the steps manually here. Otherwise you can [skip ahead to the next section to run the chaincode](#run-the-chaincode-locally). - -Fabric chaincode packages are a `tgz` format archive that contain two files: - -- `metadata.json` - the chaincode label and type -- `code.tar.gz` - source artifacts for the chaincode - -Create the `metadata.json` first, this tells the Peer the type of chaincode and a label to use to refer to this later - -```bash -cat << METADATAJSON-EOF > metadata.json -{ - "type": "ccaas", - "label": "asset-transfer" -} -METADATAJSON-EOF -``` - -Create the `code.tar.gz` - for the Chaincode-as-a-service, this file will contain a single JSON file `connection.json`. Traditional Fabric packaging would include all the source code of the chaincode here. In this case, we need the JSON file to contain the URL the peer will find the chaincode at and a timeout. Note this is a special hostname so the peer inside the docker container can locate the chaincode running on the host system - -``` -cat << CONNECTIONJSON-EOF > connection.json -{ - "address":"host.docker.internal:9999", - "dial_timeout":"15s" -} -CONNECTIONJSON-EOF -``` - -We can now build the actual package. Create a code.tar.gz archive containing the connection.json file. - -```bash -tar -czf code.tar.gz connection.json -``` - -Create the final chaincode package archive. - -```bash -tar -czf asset-transfer.tgz metadata.json code.tar.gz -``` - -We're going to use the peer CLI commands to install and deploy the chaincode. Chaincode is 'deployed' by indicating agreement to it and then committing it to a channel: - -``` -source _cfg/uf/org1admin.env - -peer lifecycle chaincode install asset-transfer.tgz -``` - -The ChaincodeID that is returned from this install command needs to be saved, typically this is best as an environment variable - -```bash -export CHAINCODE_ID=$(peer lifecycle chaincode calculatepackageid asset-transfer.tgz) -``` - -Next, define the chaincode on the blockchain channel by approving it and committing it. If you have already deployed the chaincode using the `just` recipe above, then increment the `--sequence` number to `2`. - -```bash -peer lifecycle chaincode approveformyorg --channelID mychannel -o $ORDERER_ENDPOINT --name asset-transfer -v 0 --package-id $CHAINCODE_ID --sequence 2 --connTimeout 15s -peer lifecycle chaincode commit --channelID mychannel -o $ORDERER_ENDPOINT --name asset-transfer -v 0 --sequence 2 --connTimeout 15s -``` - -## Run the chaincode locally - -We'll use the example typescript contract already written in `$WORKSHOP_PATH/contracts/asset-transfer-typescript`. Feel free to take a look at the contract code in [contracts/asset-transfer-typescript/src/assetTransfer.ts](../../contracts/asset-transfer-typescript/src/assetTransfer.ts). You'll see the implementation of contract functions such as `CreateAsset()` and `ReadAsset()` there. - -Use another terminal window for the chaincode. Make sure the terminal is setup with the same environment variables as the first terminal: - -``` -cd fabric-samples/full-stack-asset-transfer-guide -export WORKSHOP_PATH=$(pwd) -export PATH=${WORKSHOP_PATH}/bin:$PATH -export FABRIC_CFG_PATH=${WORKSHOP_PATH}/config -``` - -As with any typescript module we need to run `npm install` to manage the dependencies for the chaincode and then build (compile) the chaincode typescript to javascript. - -``` -cd contracts/asset-transfer-typescript - -npm install - -npm run build -``` - -An easy way to test the contract has been built ok, is to generate the 'Contract Metadata' into a `metadata.json` file. This is a language agnostic definition of the contracts, and the datatypes the contract returns. It borrows from the OpenAPI used for defining REST APIs. It is also very useful to share to teams writing client applications so they know the data structures and transaction functions they can call. -As it's a JSON document, it's amenable to process to create other resources. - -The metadata-generate command has been put into the `package.json`: - -``` -npm run metadata -``` - -Review the generated `metadata.json` and see the summary of the contract information, the transaction functions, and datatypes. This information can also be captured at runtime and is a good way of testing deployment. - -## Iterative Development and Test - -**All the steps up until here are one time only. You can now iterate over the development of your contract** - -From your chaincode terminal window lets start the Smart Contract node module. Remember that the `CHAINCODE_ID` and the `CHAINCODE_SERVER_ADDRESS` are the only pieces of information needed. - -Note: Use your specific CHAINCODE_ID from earlier; the `CHAINCODE_SERVER_ADDRESS` is different - this is because in this case it is telling the chaincode where to listen for incoming connections from the Peer. We'll use port 9999 on the local machine. - -``` -source ${WORKSHOP_PATH}/_cfg/uf/org1admin.env - -# if you ran the justfile above, these will already be exported, but you may want to double check they are set: -export CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999 -export CHAINCODE_ID=$(peer lifecycle chaincode calculatepackageid asset-transfer.tgz) - -npm run start:server-debug -``` - -### Run some transactions - -Choose a terminal window to run the transactions from; initially we'll use the `peer` CLI to run the commands. - -If this is a new terminal window set the environment variables: - -``` -cd fabric-samples/full-stack-asset-transfer-guide -export WORKSHOP_PATH=$(pwd) -export PATH=${WORKSHOP_PATH}/bin:$PATH -export FABRIC_CFG_PATH=${WORKSHOP_PATH}/config -``` - -Make sure that the peer binary and the config directory are set (run the `${WORKSHOP_PATH}/check.sh` script to double check). - -Set up the environment context for acting as the Org 1 Administrator. - -``` -source ${WORKSHOP_PATH}/_cfg/uf/org1admin.env -``` - -Use the peer CLI to issue basic query commands against the contract. For example check the metadata for the contract (if you have jq, it's easier to read if you pipe the results into jq). Use one of these commands: - -``` -peer chaincode query -C mychannel -n asset-transfer -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' -peer chaincode query -C mychannel -n asset-transfer -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' | jq -``` - -Let's create an asset with ID=001: - -``` -peer chaincode invoke -C mychannel -o orderer-api.127-0-0-1.nip.io:8080 -n asset-transfer -c '{"Args":["CreateAsset","{\"ID\":\"001\", \"Color\":\"Red\",\"Size\":52,\"Owner\":\"Fred\",\"AppraisedValue\":234234}"]}' --connTimeout 15s -``` - -If you are watching the MicroFab logs you'll see that the peer committed a new block to the ledger. - -Now read back that asset: - -``` -peer chaincode query -C mychannel -n asset-transfer -c '{"Args":["ReadAsset","001"]}' -``` - -You'll see the asset returned: - -``` -{"AppraisedValue":234234,"Color":"Red","ID":"001","Owner":"{\"org\":\"org1MSP\",\"user\":\"Fred\"}","Size":52} -``` - -### Making a change and re-running the code - -If we invoke a query command on a asset that does not exist, for example 002, we'll get back an error: - -``` -peer chaincode query -C mychannel -n asset-transfer -c '{"Args":["ReadAsset","002"]}' -``` - -returns error: - -``` -Error: endorsement failure during query. response: status:500 message:"Sorry, asset 002 has not been created" -``` - -Let's say we want to change that error message to something else. - -- Stop the running chaincode (CTRL-C in the chaincode terminal) -- Load the `src/assetTransfer.ts` file into an editor of your choice -- Around line 51, find the error string and make a modification. Remember to save the change. -- Rebuild the typescript contract: - -``` -npm run build -``` - -You can now restart the contract as before - -``` -npm run start:server-debug -``` - -And run the same query, and see the updated error message: - -``` -peer chaincode query -C mychannel -n asset-transfer -c '{"Args":["ReadAsset","002"]}' -``` - -## Debugging - -As the chaincode was started with the Node.js debug setting, you can connect a node.js debugger. For example VSCode has a good typescript/node.js debugger. - -If you select the debug tab, and open the debug configurations, add "Attach to a node.js process" configuration. -VSCode will prompt you with the template. The default port should be sufficient here. -You can then start the 'attached to process' debug, and pick the process to debug into. - -Remember to set a breakpoint at the start of the transaction function you want to debug. - -Watch out for: - -- VSCode uses node, so take care in selecting the right process -- remember the client/fabric transaction timeout, whilst you have the chaincode stopped in the debugger, the timeout is still 'ticking' - -Look at the [Test and Debugging Contracts](./03-Test-And-Debug-Reference.md) for more details and information on other languages. diff --git a/full-stack-asset-transfer-guide/docs/SmartContractDev/02-Exercise-Adding-tx-function-ES.md b/full-stack-asset-transfer-guide/docs/SmartContractDev/02-Exercise-Adding-tx-function-ES.md deleted file mode 100644 index dd758d11..00000000 --- a/full-stack-asset-transfer-guide/docs/SmartContractDev/02-Exercise-Adding-tx-function-ES.md +++ /dev/null @@ -1,52 +0,0 @@ -## Agregar una Función Transaccional - -[ANTERIOR - Comenzar](./01-Exercise-Getting-Started-ES.md) <==> [SIGUIENTE - Probar y Depurar](./03-Test-And-Debug-Reference-ES.md) - - En este ejercicio, agregaremos una función transaccional para verificar el valor estimado. Escribiremos esta función como parte del ciclo de desarrollo iterativo de un chaincode-as-a-service externo, por lo cual no hay un requerimiento de detener Fabric o preocuparnos por las versiones implementadas del chaincode. Simplemente estaremos actualizando el código fuente del chaincode, reiniciando el servicio del chaincode, y probando la nueva función. - -La función será: - -- una función de 'solo-lectura' -- esperará un id del activo y un valor superior e inferior -- regresará una indicación por verdadero/false si el valor estimado se encuentra dentro de los valores superior e inferior - -## Pasos - -Asegúrate primero que has ejecutado el Contrato Inteligente y podido emitir transacciones contra él. Vale la pena cerciorarse que puedes detener y reiniciar el código luego de hacer cambios menores. - -- En el archivo `assetTransfer.ts` crea una nueva función `ValidateValue`. La función `ReadAsset` es una buena función para usar como una base. Es una función de solo-lectura y ya obtiene el activo del ledger. -- Agrega un valor superior e inferior a los parámetros de la función. -- La función`ReadAsset` regresa directamente el activo, puedes mirar la función`UpdateAsset` para ver cómo procesar la data. -- Verifica el valor y regresa verdadero/false dependiendo si el valor esta entre los límites o no. -- Si quieres también puedes establecer un evento. - -Recuerda detener el código que está ejecutándose, compilarlo e iniciarlo nuevamente. Recuerda que puedes anexar el depurador para ayudar a identificar los problemas. - -## Probar - -Puedes entonces invocar este código con comandos similares como en [Comenzar](./01-Exercise-Getting-Started-ES.md). - -Por ejemplo para verificar que el valor este entre 1000 y 4200, puedes hacer el llamado similar a: - -``` -peer chaincode query -C mychannel -n asset-transfer -c '{"Args":["ValidateValue","001","1000","4200"]}' -``` - -## Ejemplo de implementación - -Una implementación posible sería: - -``` -@Transaction(false) -async ValidateValue(ctx: Context, id: string, lower:number, upper:number): Promise { - const existingAssetBytes = await this.#readAsset(ctx, id); - const existingAsset = newAsset(unmarshal(existingAssetBytes)); - - if (existingAsset.AppraisedValue > lower && existingAsset.AppraisedValue < upper){ - return true; - } else { - return false; - } - -} -``` diff --git a/full-stack-asset-transfer-guide/docs/SmartContractDev/02-Exercise-Adding-tx-function.md b/full-stack-asset-transfer-guide/docs/SmartContractDev/02-Exercise-Adding-tx-function.md deleted file mode 100644 index 28548acc..00000000 --- a/full-stack-asset-transfer-guide/docs/SmartContractDev/02-Exercise-Adding-tx-function.md +++ /dev/null @@ -1,52 +0,0 @@ -## Adding a Transaction Function - -[PREVIOUS - Getting Started](./01-Exercise-Getting-Started.md) <==> [NEXT - Test And Debug](./03-Test-And-Debug-Reference.md) - - In this exercise, we're going to add a transaction function to check the appraised value. We're going to write this function as part of the iterative development cycle with external chaincode-as-a-service, so there is no requirement to stop fabric or worry about versions of deployed chaincode. We will simply be updating the chaincode source code, restarting the chaincode service, and testing out the new function. - -The function will: - -- be a 'read-only' function -- take a given asset id, and an upper and lower value -- return a true/false indication if the appraised value is within the upper/lower values - -## Steps - -Firstly ensure that you've run the Smart Contract and been able to issue transactions against it. It's also worth making sure that you can stop and restart the code after making some minor changes. - -- In the `assetTransfer.ts` file create a new function `ValidateValue` . The `ReadAsset` function is a good one to use as a basis. This is a read-only function and already gets the asset from the ledger. -- Add an upper and lower value to the parameters of the function -- `ReadAsset` returns the asset directly, look at the `UpdateAsset` function for how to process the data -- Check the value and return true/false depending on if the value is in the bounds. -- If you wish also set an event. - -Remember to stop the running code, rebuild it and start again. Remember you can attach the debugger to help track down issues - -## Testing - -You can invoke this then with similar commands as in Getting Started. - -For example to check if the value is between 1000 and 4200, issue something like - -``` -peer chaincode query -C mychannel -n asset-transfer -c '{"Args":["ValidateValue","001","1000","4200"]}' -``` - -## Example implementation - -A possible implementation would be - -``` -@Transaction(false) -async ValidateValue(ctx: Context, id: string, lower:number, upper:number): Promise { - const existingAssetBytes = await this.#readAsset(ctx, id); - const existingAsset = newAsset(unmarshal(existingAssetBytes)); - - if (existingAsset.AppraisedValue > lower && existingAsset.AppraisedValue < upper){ - return true; - } else { - return false; - } - -} -``` diff --git a/full-stack-asset-transfer-guide/docs/SmartContractDev/03-Test-And-Debug-Reference-ES.md b/full-stack-asset-transfer-guide/docs/SmartContractDev/03-Test-And-Debug-Reference-ES.md deleted file mode 100644 index e253f0f7..00000000 --- a/full-stack-asset-transfer-guide/docs/SmartContractDev/03-Test-And-Debug-Reference-ES.md +++ /dev/null @@ -1,122 +0,0 @@ -# Referencia para Probar y Depurar - -[ANTERIOR - Agregar una Función Transaccional](./02-Exercise-Adding-tx-function-ES.md) - -**Meta:** Iniciar un Contrato Inteligente en Hyperledger Fabric para que pueda ser depurado fácilmente - -**Objetivos:** - -- Introducir qué es Chaincode-as-a-Service, y cómo ayuda -- Mostrar cómo construir y configurar un Chaincode para ejecutar de esta manera -- Cómo se implementan estos en una red que esta levantada de Hyperledger Fabric -- Cómo depurar este Chaincode que se está ejecutando. - ---- - -## Resumen - -Ayuda pensar en estas tres 'partes': - -- La red de Fabric, que consiste de los peers, ordenadores, autoridades certificantes etc. Junto con los channels configurados y las identidades. - Para nuestros propósitos aquí, esto puede ser considerado como una 'caja negra'. La 'caja negra' puede ser configurada de maneras diferentes, pero típicamente será uno o mas contenedores docker. Este workshop usa MicroFab para levantar la red de Fabric en un único contenedor docker. -- El Chaincode - que estará ejecutándose en su propio proceso o contenedor docker. -- El editor - VSCode es usado aquí, pero el enfoque debería ser el mismo con otros depuradores y editores. - -El _proceso a alto nivel_ es - -0. Levantar Fabric -1. Desarrollar el Contrato Inteligente -3. Crear un paquete de chaincode utilizando el enfoque de chaincode-as-a-service -4. Instalar el chaincode en un peer y Aprobar/Asignar el chaincode a un channel -5. Iniciar el chaincode utilizando el enfoque chaincode-as-a-service -6. Anexar el depurador al chaincode ejecutándose y definir un punto de quiebre -7. Invocar una transacción, ésta se detendrá entonces en el depurador para que puedas pasar sobre el código -8. Encontrar los errores y repetir **desde paso 5** - ten en cuenta que no necesitamos Empaquetar/Instalar/Aprobar/Asignar de nuevo el chaincode. - -Este es el proceso exacto que habrás seguido en la sección ['Comenzar'](./01-Exercise-Getting-Started-ES.md). - -### ¿Qué necesitas? - -Necesitaras contar con disponibilidad de docker, junto con VSCode. Además instala las extensiones de VSCode que prefieres para depurar tu lenguaje de programación preferido. Existen otros depuradores disponibles y eres libre de usarlos si cuentas con ellos. - -- Para TypeScript y JavaScript VSCode tiene el soporte incorporado -- Para Java es sugerido el [paquete JavaExtension](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack). - -### ¿Qué es Chaincode como un Servicio? - -La facilidad de chaincode-as-a-service es una manera muy práctica y útil para ejecutar 'Contratos Inteligentes'. Tradicionalmente ha sido el Fabric Peer el que ha tomado el role de orquestar el ciclo de vida completo del chaincode. Esto requería acceso al Daemon de Docker para crear imágenes, e iniciar contenedores. Los marcos de chaincode programados en Java, Node.js y Go eran explícitamente conocidos por el peer incluyendo cómo debían ser compilados e iniciados. - -Como resultado, esto hacía difícil implementar en entornos de estilo Kubernetes (K8S) o ejecutar de cualquier manera en modo depuración. Adicionalmente, el código esta siendo re compilado por el peer entonces existe cierto grado de incertidumbre respecto de qué dependencias deben ser incorporadas. - -Hacer uso de chaincode-as-service requiere que sea uno quien orqueste la fase de compilación e implementación. Aunque esto es un paso adicional, devuelve el control. El Peer aún requiere que un 'paquete de chaincode' sea instalado. En este caso, éste no contiene código, pero si la información de dónde el chaincode esta hospedado (Hostname, Puerto, config de TLS, etc). - - -## Ejecutar los Contratos Inteligentes - -Un punto importante es que el código escrito para el Contrato Inteligente sea el mismo, sea que esté administrado por el peer o como Chaincode-as-a-Service. -Lo que difiere es como es iniciado y empaquetado. El proceso global es el mismo, sin importar si el contrato inteligente este escrito en Java/Typescript/Go. - -### TypeScript/JavaScript - -Usando el contrato en Typescript como un ejemplo, se puede visualizar mejor la diferencia. El package.json contiene 4 comandos de 'start'. - -``` - "start": "fabric-chaincode-node start", - "start:server-nontls": "fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID", - "start:server": "fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID --chaincode-tls-key-file=/hyperledger/privatekey.pem --chaincode-tls-client-cacert-file=/hyperledger/rootcert.pem --chaincode-tls-cert-file=/hyperledger/cert.pem", - "start:server-debug": "set -x && NODE_OPTIONS='--inspect=0.0.0.0:9229' fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID" -``` - -El primero es usado cuando el peer es quien controla completamente el chaincode. El segundo `start:server-nontls` se inicia en modo Chaincode-as-a-service (sin usar TLS). El comando es muy similar a `fabric-chaincode-node server` mas que `fabric-chaincode-node start`. Se proveen dos opciones aquí, que son, la dirección de red donde estará escuchando el chaincode y su id (aparte de cuando el Peer ejecuta el chaincode, si pasa opciones extras, pero no se pueden ver en el package.json). - -El tercer `start:server` agrega la configuración TLS requerida, pero fuera de esto es igual. -El cuarto `start:server-debug` es igual al caso de no-TLS, pero incluye la variable de entorno necesaria para que Node.js abra un puerto para permitirle al depurador conectarse remotamente. - -### Java - -Los cambios para los chaincode en Java son lógicamente los mismos. El build.gradle (o si deseas usa Maven) es exactamente igual (como si no hubiese cambios en la compilación de -TypeScript). Con las librerías v2.4.1 de Chaincode en Java, no hay cambios en el código para hacer o compilar cambios. El modo '-as-a-service' será usado si esta definida la variable de entorno `CHAINCODE_SERVER_ADDRESS`. - -Para el caso no-TLS el chaincode en Java es iniciado con `java -jar /chaincode.jar` - y usará el modo Chaincode-as-a-service _si_ esta definida la variable de entorno `CHAINCODE_SERVER_ADDRESS`. - -Para depurar, la JVM necesita ser colocada en modo depuración `java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:8000 -jar /chaincode.jar` - -## ¿En qué se diferencia el paquete de chaincode? - -Una diferencia clave es que el paquete de chaincode no contiene código. Es utilizado como un contenedor de data que le indica al peer donde se encuentra el chaincode. -¿Qué host/port y qué configuración TLS se necesitan? Los paquetes de chaincode ya contienen data respecto de los indices de CouchDB a usar o las colecciones de data privada. - -Dentro del paquete, el archivo `connection.json` es importante. En su expresión mas simple sería: - -```json -{ - "address": "assettransfer_ccaas:9999", - "dial_timeout": "10s", - "tls_required": false -} -``` - -Esto le esta indicando al peer que el chaincode esta en el host `assettransfer_ccaas` puerto 9999. Define 10s como el tiempo de espera para conectarse y que TLS no es requerido. - -El paquete puede ser construido manualmente, es un conjunto de archivos json, que se pueden juntar con `tgz`. - -### Importante aviso de interconexión - -El paquete del chaincode que es instalado críticamente contiene el nombre de red y puerto donde el peer espera que el chaincode este escuchando. Si nada contesta al peer, la transacción obviamente fallará. - -Ten en cuenta que esta bien que el chaincode no se este ejecutando todo el tiempo, el peer no se quejará hasta que le sea efectivamente pedido conectarse al chaincode. Esta es una facilidad importante ya que permite que se pueda depurar y re iniciar el contenedor. - -El nombre de red que es suministrado debe ser algo que el peer, desde su perspectiva, pueda resolver. Típicamente el peer se encontrará dentro de un contenedor docker, entonces proporcionar `localhost` o `127.0.0.1` resolverá al mismo contenedor donde esta ejecutándose el peer.. - -Asumiendo que el peer esta ejecutándose en un contenedor docker, el chaincode podría estar corriendo en su propio contenedor docker en la misma red de docker que el contenedor del peer, o podría estar ejecutándose directamente en el sistema host. - -Dependiendo del sistema operativo de tu host, el 'specialhostname' que es usado desde dentro del contenedor docker para acceder al host varía. - Por ejemplo, mira esto [stackoverflow post](https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach#:~:text=To%20access%20host%20machine%20from,using%20it%20to%20anything%20else.&text=Then%20make%20sure%20that%20you,0.0%20.) - -La ventaja de esto es que el chaincode puede ejecutarse localmente en tu maquina host y es fácil conectarse al mismo desde un depurador. - -Alternativamente, puedes empaquetar el chaincode en su propio contenedor docker, y ejecutar eso. Aún puedes conectarte para depurar pero debes asegurarte que los puertos del contenedor esten expuestos correctamente para el ambiente de ejecución de tu lenguaje. - -## Paso individual y tiempos de espera - -- Si vas a depurar paso a paso, entonces probablemente te topes con el valor del tiempo de espera de la transacción de Fabric. Por defecto este valor es de 30 segundos, que significa que el chaincode debe completar la transacción en 30 segundos o menos antes de que el peer limite el tiempo del requerimiento. En tu `config/core.yaml` actualiza `executetimeout` a `300s`, o agrega `CORE_CHAINCODE_EXECUTETIMEOUT=300s` a las variables de entorno de cada peer, para que puedas pasar por el código de tu contrato en un depurador por 5 minutos por función transaccional invocada. diff --git a/full-stack-asset-transfer-guide/docs/SmartContractDev/03-Test-And-Debug-Reference.md b/full-stack-asset-transfer-guide/docs/SmartContractDev/03-Test-And-Debug-Reference.md deleted file mode 100644 index 665f9798..00000000 --- a/full-stack-asset-transfer-guide/docs/SmartContractDev/03-Test-And-Debug-Reference.md +++ /dev/null @@ -1,134 +0,0 @@ -# Test and Debug Reference - -[PREVIOUS - Adding a Transaction Function](./02-Exercise-Adding-tx-function.md) - -**Aim:** Stand up a Hyperledger Fabric Smart Contract so it can easily be debugged - -**Objectives:** - -- Introduce what Chaincode-as-a-Service is, and how it helps -- Show how to build & configure a Chaincode to run like this -- How to deploy these in a running Hyperledger Fabric network -- How then to debug this running Chaincode. - ---- - -## Overview - -It helps to think of three 'parts' - -- The Fabric network, consisting of the peers, orderers, certificate authorities etc. Along with configured channels and identities. - For our purposes here, this can be considered as a 'black box'. The 'black box' can be configured a number of different ways, but typically will be one or more docker containers. This workshop uses MicroFab to bring up the Fabric network in a single docker container. -- The Chaincode - this will be running in its own process or docker container. -- The editor - VSCode is covered here, but the approach should hold with other debuggers and editors. - -The _high level process_ is - -0. Stand-up Fabric -1. Develop the Smart Contract -3. Create a chaincode package using the chaincode-as-a-service approach -4. Install the chaincode to a peer and Approve/Commit the chaincode on a channel -5. Start the chaincode using the chaincode-as-a-service approach -6. Attach your debugger to the running chaincode and set a breakpoint -7. Invoke a transaction, this will then halt in the debugger to let you step over the code -8. Find the bugs and repeat **from step 5** - note that we don't need to Package/Install/Approve/Commit the chaincode again. - -This is the exact process that you will have followed in the ['Getting Started'](./01-Exercise-Getting-Started.md) section - -### What do you need? - -You'll need to have docker available to you, along with VSCode. Also, install the VSCode extensions you prefer for debugging your preferred language. Other debuggers are available and you're free to use those if you have them available. - -- For TypeScript and JavaScript VSCode has built-in support -- For Java the [JavaExtension pack](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack) is suggested - -### What is Chaincode as Service? - -The chaincode-as-a-service feature is a very useful and practical way to run 'Smart Contracts'. Traditionally the Fabric Peer has taken on the role of orchestrating -the complete lifecycle of the chaincode. It required access to the Docker Daemon to create images, and start containers. Java, Node.js and Go chaincode frameworks were - explicitly known to the peer including how they should be built and started. - -As a result, this makes it very hard to deploy into Kubernetes (K8S) style environments or to run in any form of debug mode. Additionally, the code is being rebuilt by - the peer therefore there is some degree of uncertainty about what dependencies have been pulled in. - -Chaincode-as-service requires you to orchestrate the build and deployment phase yourself. Whilst this is an additional step, it gives control back. The Peer still -requires a 'chaincode package' to be installed. In this case, this doesn't contain code, but the information about where the chaincode is hosted. (Hostname, Port, TLS config etc) - - -## Running the Smart Contracts - -An important point is that the code written for the Smart Contract is the same, whether it's managed by the peer or Chaincode-as-a-Service. -What is different is how that is started and packaged. The overall process is the same, regardless of whether your smart contract is written in Java/Typescript/Go. - -### TypeScript/JavaScript - -Using the Typescript contract as an example, the difference is easier to see. The package.json contains 4 'start' commands - -``` - "start": "fabric-chaincode-node start", - "start:server-nontls": "fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID", - "start:server": "fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID --chaincode-tls-key-file=/hyperledger/privatekey.pem --chaincode-tls-client-cacert-file=/hyperledger/rootcert.pem --chaincode-tls-cert-file=/hyperledger/cert.pem", - "start:server-debug": "set -x && NODE_OPTIONS='--inspect=0.0.0.0:9229' fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID" -``` - -The first is used when the peer is completely controlling the chaincode. The second `start:server-nontls` starts in the Chaincode-as-a-service mode (without using TLS). The command -is very similar `fabric-chaincode-node server` rather than `fabric-chaincode-node start`. Two options are provided here, these are the network address the chaincode - will listen on and its id. (aside when the Peer runs the chaincode, it does pass extra options, but they aren't seen in the package.json) - -The third `start:server` adds the required TLS configuration, but is otherwise the same. -The fourth `start:server-debug` is the same as the non-TLS case, but includes the environment variable required to get Node.js to open a port to allow a debugger to connect remotely. - -### Java - -The changes for the Java chaincode are logically the same. The build.gradle (or use Maven if you wish) is exactly the same (like there were no changes to the -TypeScript compilation). With the v2.4.1 Java Chaincode libraries, there are no code changes to make or build changes. The '-as-a-service' mode will be used if - the environment variable `CHAINCODE_SERVER_ADDRESS` is set. - -For the non-TLS case the Java chaincode is started with `java -jar /chaincode.jar` - and will use the Chaincode-as-a-service mode _if_ the environment variable `CHAINCODE_SERVER_ADDRESS` is set. - -For debug, the JVM needs to put into debug mode `java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:8000 -jar /chaincode.jar` - -## How is the chaincode package different? - -A key difference is that the chaincode package does not contain code. It is used as a holder of data that indicates to the peer where the chaincode is. -What host/port and what TLS configuration is needed? Chaincode packages already can hold data about the CouchDB indexes to use or the private data collections. - -Within the package, the `connection.json` is an important file. At its simplest it would be - -```json -{ - "address": "assettransfer_ccaas:9999", - "dial_timeout": "10s", - "tls_required": false -} -``` - -This is telling the peer the chaincode is on host `assettransfer_ccaas` port 9999. 10s timeout on connecting and tls is not needed. - -The packager can be constructed by hand, it's a set of json files, collected together with `tgz`. - -### Important networking warning - -The chaincode package that is installed critically contains the hostname and port that the peer is expecting the chaincode to listen on. If nothing answers the -peer, it obviously will fail the transaction. - -Note that it is ok not to have the chaincode running at all times, the peer won't complain until it is asked to actually connect to the chaincode. This is an important - ability as it allows for debugging and restarting of the container. - -The hostname that is supplied must be something that the peer, from its perspective, can resolve. Typically the peer will be inside a docker container, therefore - supplying `localhost` or `127.0.0.1` will resolve to the same container the peer is running in. - -Assuming that the peer is running in a docker container, the chaincode could either be run in its own docker container, on the same docker network as the peers - container, or it could be run directly on the host system. - -Depending your host OS, the 'specialhostname' that is used from within the docker container to access the host varies. - For example, see this [stackoverflow post](https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach#:~:text=To%20access%20host%20machine%20from,using%20it%20to%20anything%20else.&text=Then%20make%20sure%20that%20you,0.0%20.) - -The advantage of this is the chaincode can run locally on your host machine and is simple to connect to from a debugger. - -Alternatively, you can package the chaincode into its own docker container, and run that. You can still debug into this, but need to ensure that the ports of the -container are exposed correctly for your language runtime. - -## Single stepping and timeouts - -- If you are going to single step in a debugger, then you are likely to hit the Fabric transaction timeout value. By default this is 30 seconds, meaning the chaincode has to complete transactions in 30 seconds or less before the peer timesout the request. In your `config/core.yaml` update `executetimeout` to be `300s`, or add `CORE_CHAINCODE_EXECUTETIMEOUT=300s` to the environment variable options of each peer, so that you can step through your contract code in a debugger for 5 minutes for each invoked transaction function. diff --git a/full-stack-asset-transfer-guide/docs/images/ApplicationDev.pptx b/full-stack-asset-transfer-guide/docs/images/ApplicationDev.pptx deleted file mode 100644 index 4b1da292..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/ApplicationDev.pptx and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/ApplicationDev/fabric-gateway-deployment.png b/full-stack-asset-transfer-guide/docs/images/ApplicationDev/fabric-gateway-deployment.png deleted file mode 100644 index a3a42254..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/ApplicationDev/fabric-gateway-deployment.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/ApplicationDev/fabric-gateway-model.png b/full-stack-asset-transfer-guide/docs/images/ApplicationDev/fabric-gateway-model.png deleted file mode 100644 index f059cc03..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/ApplicationDev/fabric-gateway-model.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/ApplicationDev/legacy-sdk-model.png b/full-stack-asset-transfer-guide/docs/images/ApplicationDev/legacy-sdk-model.png deleted file mode 100644 index ce46f043..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/ApplicationDev/legacy-sdk-model.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/ApplicationDev/transaction-submit-flow.png b/full-stack-asset-transfer-guide/docs/images/ApplicationDev/transaction-submit-flow.png deleted file mode 100644 index b21a9758..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/ApplicationDev/transaction-submit-flow.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/CloudReady.pptx b/full-stack-asset-transfer-guide/docs/images/CloudReady.pptx deleted file mode 100644 index 46eb014f..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/CloudReady.pptx and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/CloudReady/00-cloud-ready-2.png b/full-stack-asset-transfer-guide/docs/images/CloudReady/00-cloud-ready-2.png deleted file mode 100644 index 5b48adb0..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/CloudReady/00-cloud-ready-2.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/CloudReady/10-kube.png b/full-stack-asset-transfer-guide/docs/images/CloudReady/10-kube.png deleted file mode 100644 index 8d61750d..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/CloudReady/10-kube.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/CloudReady/12-kube-ec2-vm.png b/full-stack-asset-transfer-guide/docs/images/CloudReady/12-kube-ec2-vm.png deleted file mode 100644 index bcc4201f..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/CloudReady/12-kube-ec2-vm.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/CloudReady/20-fabric.png b/full-stack-asset-transfer-guide/docs/images/CloudReady/20-fabric.png deleted file mode 100644 index 228da427..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/CloudReady/20-fabric.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/CloudReady/30-chaincode.png b/full-stack-asset-transfer-guide/docs/images/CloudReady/30-chaincode.png deleted file mode 100644 index ad0a3f24..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/CloudReady/30-chaincode.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/CloudReady/40-gateway-client-app.png b/full-stack-asset-transfer-guide/docs/images/CloudReady/40-gateway-client-app.png deleted file mode 100644 index 87222ea9..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/CloudReady/40-gateway-client-app.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/CloudReady/kube-ec2-vm.png b/full-stack-asset-transfer-guide/docs/images/CloudReady/kube-ec2-vm.png deleted file mode 100644 index 17b30ad7..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/CloudReady/kube-ec2-vm.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/cloud-vm-with-operator-network.png b/full-stack-asset-transfer-guide/docs/images/cloud-vm-with-operator-network.png deleted file mode 100644 index 9cd1a883..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/cloud-vm-with-operator-network.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/multipass-operator-network.png b/full-stack-asset-transfer-guide/docs/images/multipass-operator-network.png deleted file mode 100644 index 70b62f29..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/multipass-operator-network.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/multipass-test-network.png b/full-stack-asset-transfer-guide/docs/images/multipass-test-network.png deleted file mode 100644 index f4d1190c..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/multipass-test-network.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/images/readme_diagram.png b/full-stack-asset-transfer-guide/docs/images/readme_diagram.png deleted file mode 100644 index 9cd1732f..00000000 Binary files a/full-stack-asset-transfer-guide/docs/images/readme_diagram.png and /dev/null differ diff --git a/full-stack-asset-transfer-guide/docs/tips-for-windows-dev.md b/full-stack-asset-transfer-guide/docs/tips-for-windows-dev.md deleted file mode 100644 index a686bacb..00000000 --- a/full-stack-asset-transfer-guide/docs/tips-for-windows-dev.md +++ /dev/null @@ -1,56 +0,0 @@ -# Using Windows - -We recommend using the Windows Subsystem for Linux (WSL2) or use Multipass to create VMs. If you've never used either then Multipass is probably the quickest way to start initially. - -## Multipass - -- Setup [Multipass](https://multipass.run/) on Windows (recommened to enable Hyper_V) -- From a Windows Command Prompt - -``` -multipass launch --name fabric-dev --disk 80G --cpus 8 --mem 8G --cloud-init https://raw.githubusercontent.com/hyperledgendary/full-stack-asset-transfer-guide/main/infrastructure/multipass-cloud-config.yaml -``` - -## Using VSCode -- Setup [vscode](https://code.visualstudio.com/) and make sure you've the [remote development extension pack ](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)installed - -- Find out the IP address of the machines thats created - `multipass list` will show you this. For example - -``` -C:\Users\014961866>multipass list -Name State IPv4 Image -primary Running 172.31.125.88 Ubuntu 20.04 LTS -fabric-dev Running 172.31.118.103 Ubuntu 20.04 LTS - 172.17.0.1 -``` - -- You will need to find the private ssh key that multipass uses; this _should_ be at `C:\ProgramData\Multipass\data\ssh-keys\id_rsa` -- Copy this to you home directory (otherwise SSH will not use the file as it's 'too open') - -``` -copy C:\ProgramData\Multipass\data\ssh-keys\id_rsa %HOMEDRIVE%%HOMEPATH%\.ssh\multipass_id_rsa -``` - -- In VSCode, click on the remote development icon in the toolbar, and in the *Remote Explorer*, choose *SSH Targets* -- In the title bar of *SSH Targets*, click on the cog, and pick the default configuration file. -- Create an entry in this configuration file - - change the HostName to the IP of the multipass created VM - - ensure the identity file points to the file you copied - - you can change the `fabric-dev` name if you have multiple entries - -``` -Host fabric-dev - HostName 172.31.118.103 - User ubuntu - Port 22 - StrictHostKeyChecking no - PasswordAuthentication no - IdentityFile C:/Users//.ssh/multipass_id_rsa - IdentitiesOnly yes - LogLevel FATAL -``` - -- When save, an entry for *fabric-dev* will appear in the *SSH Targets* view -- Click on the 'Open Window' icon next to it -- First time you'll be asked to confirm the system is Linux, and VSCode will setup it's remote server. -- Then you're good to go with browsing files, and also using the inbuilt terminal. diff --git a/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-common-vars.yml b/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-common-vars.yml deleted file mode 100644 index 1f5db563..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-common-vars.yml +++ /dev/null @@ -1,23 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -# These vars are used in more than one file, -# i.e. needed by multiple orgs so can't just live in a per org file -ordering_org_name: "Ordering Org" -ordering_service_name: "Ordering Service" -org1_name: "Org1" -org1_msp_id: Org1MSP -org2_name: "Org2" -org2_msp_id: Org2MSP -channel_name: "mychannel" -# smart_contract_name: "fabcar" -# smart_contract_version: "1.0.0" -# smart_contract_sequence: 1 -# smart_contract_package: "fabcar@1.0.0.tgz" -# smart_contract_constructor: "initLedger" -# smart_contract_endorsement_policy: "" -# smart_contract_collections_file: "" -ca_version: ">=1.4,<2.0" -peer_version: ">=2.2,<3.0" -ordering_service_version: ">=2.2,<3.0" diff --git a/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-ordering-org-vars.yml b/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-ordering-org-vars.yml deleted file mode 100644 index 426d00fd..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-ordering-org-vars.yml +++ /dev/null @@ -1,13 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -ca_admin_enrollment_id: admin -ca_admin_enrollment_secret: adminpw -organization_admin_enrollment_id: orderingorgadmin -organization_admin_enrollment_secret: orderingorgadminpw -ordering_service_enrollment_id: orderingorgorderer -ordering_service_enrollment_secret: orderingorgordererpw -ordering_service_msp: OrdererMSP -ordering_service_nodes: 1 -wait_timeout: 600 diff --git a/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-org1-vars.yml b/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-org1-vars.yml deleted file mode 100644 index d9256429..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-org1-vars.yml +++ /dev/null @@ -1,17 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -ca_admin_enrollment_id: admin -ca_admin_enrollment_secret: adminpw -organization_admin_enrollment_id: org1admin -organization_admin_enrollment_secret: org1adminpw -peer_enrollment_id: org1peer -peer_enrollment_secret: org1peerpw -application_enrollment_id: org1app -application_enrollment_secret: org1apppw -application_enrollment_type: client -application_max_enrollments: 10 -org1_ca_name: "Org1 CA" -org1_peer_name: "Org1 Peer" -wait_timeout: 600 diff --git a/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-org2-vars.yml b/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-org2-vars.yml deleted file mode 100644 index 2480632c..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-org2-vars.yml +++ /dev/null @@ -1,17 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -ca_admin_enrollment_id: admin -ca_admin_enrollment_secret: adminpw -organization_admin_enrollment_id: org2admin -organization_admin_enrollment_secret: org2adminpw -peer_enrollment_id: org2peer -peer_enrollment_secret: org2peerpw -application_enrollment_id: org2app -application_enrollment_secret: org2apppw -application_enrollment_type: client -application_max_enrollments: 10 -org2_ca_name: "Org2 CA" -org2_peer_name: "Org2 Peer" -wait_timeout: 600 diff --git a/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-sail.yaml b/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-sail.yaml deleted file mode 100644 index 5c8e6c34..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/configuration/fabric-sail.yaml +++ /dev/null @@ -1,36 +0,0 @@ -network: - name: asset-transfer-basic - domain: localho.st - namespace: test-network - - organizations: - - name: org0 - orderers: - - name: org0-orderers - count: 3 - - - name: org1 - peers: - - name: org1-peer1 - anchor: true - - name: org1-peer2 - - - name: org2 - peers: - - name: org2-peer1 - anchor: true - - name: org2-peer2 - - channels: - - name: mychannel - organizations: - - org1 - - org2 - - chaincode: - - name: asset-transfer - version: v0.1.1 - package: https://github.com/hyperledgendary/asset-transfer-basic/releases/download/v0.1.1/asset-transfer-basic-v0.1.1.tgz - channels: - - name: mychannel - policy: "OR('org1.member', 'org2.member')" \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/configuration/operator-console-vars.yml b/full-stack-asset-transfer-guide/infrastructure/configuration/operator-console-vars.yml deleted file mode 100644 index d61a7e2c..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/configuration/operator-console-vars.yml +++ /dev/null @@ -1,39 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -# The type of K8S cluster this is using -target: ${cluster_type} - -# If the target cluster is OpenShift use this value for target -# target: openshift - -# If the target cluster is any other k8s use this value for target -# target: k8s - - - -arch: amd64 - -# k8s namespace for the operator and console -namespace: ${namespace} - -# used if this is openshift -project: ${namespace} - -# Console name/domain -console_name: hlf-console -console: hlf-console -console_domain: ${ingress_domain} - -# default configuration for the console -# password reset will be required on first login -console_email: admin -console_default_password: password - -# different k8s clusters will be shipped with differently named default storage providers -# or none at all. KIND for example has one called 'standard' -console_storage_class: ${storage_class} - - -container_cli: podman \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/ec2-cloud-config.yaml b/full-stack-asset-transfer-guide/infrastructure/ec2-cloud-config.yaml deleted file mode 100644 index 62d06c59..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/ec2-cloud-config.yaml +++ /dev/null @@ -1,59 +0,0 @@ -#cloud-config - -write_files: - - path: /config/provision-root.sh - permissions: '0744' - content: | - #!/usr/bin/env bash - set -ex - # set -o errexit - # set -o pipefail - - # APT setup for kubectl - curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - - apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main" - - # Install kubectl - apt-get -y --no-upgrade install kubectl - - # Install yq - YQ_VERSION=4.23.1 - if [ ! -x "/usr/local/bin/yq" ]; then - curl --fail --silent --show-error -L "https://github.com/mikefarah/yq/releases/download/v${YQ_VERSION}/yq_linux_amd64" -o /usr/local/bin/yq - chmod 755 /usr/local/bin/yq - fi - - # Install kind - KIND_VERSION=0.14.0 - if [ ! -x "/usr/local/bin/kind" ]; then - curl --fail --silent --show-error -L "https://kind.sigs.k8s.io/dl/v${KIND_VERSION}/kind-linux-amd64" -o /usr/local/bin/kind - chmod 755 /usr/local/bin/kind - fi - - # Install k9s - K9S_VERSION=0.25.3 - if [ ! -x "/usr/local/bin/k9s" ]; then - curl --fail --silent --show-error -L "https://github.com/derailed/k9s/releases/download/v${K9S_VERSION}/k9s_Linux_x86_64.tar.gz" -o "/tmp/k9s_Linux_x86_64.tar.gz" - tar -zxf "/tmp/k9s_Linux_x86_64.tar.gz" -C /usr/local/bin k9s - chown root:root /usr/local/bin/k9s - chmod 755 /usr/local/bin/k9s - fi - - # Install just - JUST_VERSION=1.2.0 - if [ ! -x "/usr/local/bin/just" ]; then - curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --tag ${JUST_VERSION} --to /usr/local/bin - chown root:root /usr/local/bin/just - chmod 755 /usr/local/bin/just - fi - -runcmd: - - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - - - add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" - - apt-get update -y - - apt-get install -y docker.io - - usermod -a -G docker ubuntu - - apt-get install -y jq - - /config/provision-root.sh - -final_message: "The system is finally up, after $UPTIME seconds" diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/00-complete.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/00-complete.yml deleted file mode 100644 index 436c5059..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/00-complete.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -- hosts: localhost - vars_files: - - /_cfg/auth-vars.yml - tasks: - - ansible.builtin.debug: - msg: "Running complete Fabric network build {{ api_endpoint}} " - - include_vars: /_cfg/auth-vars.yml - -- ansible.builtin.import_playbook: 01-create-ordering-organization-components.yml -- ansible.builtin.import_playbook: 02-create-endorsing-organization-components.yml -- ansible.builtin.import_playbook: 05-enable-capabilities.yml -- ansible.builtin.import_playbook: 06-add-organization-to-consortium.yml -- ansible.builtin.import_playbook: 09-create-channel.yml -- ansible.builtin.import_playbook: 10-join-peer-to-channel.yml -- ansible.builtin.import_playbook: 11-add-anchor-peer-to-channel.yml -- ansible.builtin.import_playbook: 12-create-endorsing-organization-components.yml -- ansible.builtin.import_playbook: 15-add-organization-to-channel.yml -- ansible.builtin.import_playbook: 17-join-peer-to-channel.yml -- ansible.builtin.import_playbook: 18-add-anchor-peer-to-channel.yml - - diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/01-create-ordering-organization-components.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/01-create-ordering-organization-components.yml deleted file mode 100644 index a03d3b8e..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/01-create-ordering-organization-components.yml +++ /dev/null @@ -1,16 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Create components for an ordering organization - hosts: localhost - vars: - state: present - organization_name: "{{ ordering_org_name }}" - organization_msp_id: "{{ ordering_service_msp }}" - wallet: "/_cfg" - vars_files: - - /_cfg/fabric-common-vars.yml - - /_cfg/fabric-ordering-org-vars.yml - roles: - - ibm.blockchain_platform.ordering_organization diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/02-create-endorsing-organization-components.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/02-create-endorsing-organization-components.yml deleted file mode 100644 index 4de2abfa..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/02-create-endorsing-organization-components.yml +++ /dev/null @@ -1,18 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Create components for an endorsing organization - hosts: localhost - vars: - state: present - organization_name: "{{ org1_name }}" - organization_msp_id: "{{ org1_msp_id }}" - ca_name: "{{ org1_ca_name }}" - peer_name: "{{ org1_peer_name }}" - wallet: "/_cfg" - vars_files: - - /_cfg/fabric-common-vars.yml - - /_cfg/fabric-org1-vars.yml - roles: - - ibm.blockchain_platform.endorsing_organization diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/05-enable-capabilities.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/05-enable-capabilities.yml deleted file mode 100644 index 95cc5339..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/05-enable-capabilities.yml +++ /dev/null @@ -1,84 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Enable Fabric v2.x capabilities - hosts: localhost - vars: - wallet: "/_cfg" - vars_files: - - /_cfg/fabric-common-vars.yml - - /_cfg/fabric-ordering-org-vars.yml - tasks: - - name: Get the ordering service information - ibm.blockchain_platform.ordering_service_info: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - name: "{{ ordering_service_name }}" - register: ordering_service - - - name: Fail if the ordering service does not exist - fail: - msg: "{{ ordering_service_name }} does not exist" - when: not ordering_service.exists - - - name: Fetch the system channel configuration - ibm.blockchain_platform.channel_config: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ ordering_org_name }} Admin.json" - msp_id: "{{ ordering_service_msp }}" - operation: fetch - name: "{{ ordering_service.ordering_service[0].system_channel_id }}" - path: original_config.bin - - - name: Create a copy of the system channel configuration - copy: - src: original_config.bin - dest: updated_config.bin - - - name: Enable Fabric v2.x capabilities - ibm.blockchain_platform.channel_capabilities: - path: updated_config.bin - channel: V2_0 - orderer: V2_0 - - - name: Compute the system channel configuration update - ibm.blockchain_platform.channel_config: - operation: compute_update - name: "{{ ordering_service.ordering_service[0].system_channel_id }}" - original: original_config.bin - updated: updated_config.bin - path: config_update.bin - register: compute_update - - - name: Sign the system channel configuration update - ibm.blockchain_platform.channel_config: - operation: sign_update - identity: "{{ wallet }}/{{ ordering_org_name }} Admin.json" - msp_id: "{{ ordering_service_msp }}" - name: "{{ ordering_service.ordering_service[0].system_channel_id }}" - path: config_update.bin - when: compute_update.path - - - name: Apply the system channel configuration update - ibm.blockchain_platform.channel_config: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - operation: apply_update - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ ordering_org_name }} Admin.json" - msp_id: "{{ ordering_service_msp }}" - name: "{{ ordering_service.ordering_service[0].system_channel_id }}" - path: config_update.bin - when: compute_update.path diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/06-add-organization-to-consortium.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/06-add-organization-to-consortium.yml deleted file mode 100644 index d38a4fb0..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/06-add-organization-to-consortium.yml +++ /dev/null @@ -1,89 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Add the organization to the consortium - hosts: localhost - vars: - wallet: "/_cfg" - vars_files: - - /_cfg/fabric-common-vars.yml - - /_cfg/fabric-ordering-org-vars.yml - tasks: - - name: Get the ordering service information - ibm.blockchain_platform.ordering_service_info: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - name: "{{ ordering_service_name }}" - register: ordering_service - - - name: Fail if the ordering service does not exist - fail: - msg: "{{ ordering_service_name }} does not exist" - when: not ordering_service.exists - - - name: Fetch the system channel configuration - ibm.blockchain_platform.channel_config: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ ordering_org_name }} Admin.json" - msp_id: "{{ ordering_service_msp }}" - operation: fetch - name: "{{ ordering_service.ordering_service[0].system_channel_id }}" - path: original_config.bin - - - name: Create a copy of the system channel configuration - copy: - src: original_config.bin - dest: updated_config.bin - - - name: Add the organization to the consortium - ibm.blockchain_platform.consortium_member: - state: present - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - organization: "{{ org1_name }}" - path: updated_config.bin - - - name: Compute the system channel configuration update - ibm.blockchain_platform.channel_config: - operation: compute_update - name: "{{ ordering_service.ordering_service[0].system_channel_id }}" - original: original_config.bin - updated: updated_config.bin - path: config_update.bin - register: compute_update - - - name: Sign the system channel configuration update - ibm.blockchain_platform.channel_config: - operation: sign_update - identity: "{{ wallet }}/{{ ordering_org_name }} Admin.json" - msp_id: "{{ ordering_service_msp }}" - name: "{{ ordering_service.ordering_service[0].system_channel_id }}" - path: config_update.bin - when: compute_update.path - - - name: Apply the system channel configuration update - ibm.blockchain_platform.channel_config: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - operation: apply_update - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ ordering_org_name }} Admin.json" - msp_id: "{{ ordering_service_msp }}" - name: "{{ ordering_service.ordering_service[0].system_channel_id }}" - path: config_update.bin - when: compute_update.path diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-admins-policy.json.j2 b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-admins-policy.json.j2 deleted file mode 100644 index 9bb23865..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-admins-policy.json.j2 +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": 1, - "value": { - "rule": { - "n_out_of": { - "n": 1, - "rules": [ - { - "signed_by": 0 - } - ] - } - }, - "identities": [ - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org1_msp_id }}", - "role": "ADMIN" - } - } - ] - } -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-create-channel.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-create-channel.yml deleted file mode 100644 index 6b4948e8..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-create-channel.yml +++ /dev/null @@ -1,79 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Create the channel - hosts: localhost - vars: - wallet: "/_cfg" - vars_files: - - /_cfg/fabric-common-vars.yml - - /_cfg/fabric-org1-vars.yml - tasks: - - name: Check to see if the channel already exists - ibm.blockchain_platform.channel_block: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - operation: fetch - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ org1_name }} Admin.json" - msp_id: "{{ org1_msp_id }}" - name: "{{ channel_name }}" - target: "0" - path: channel_genesis_block.bin - failed_when: False - register: result - - - name: Fail on any error other than the channel not existing - fail: - msg: "{{ result.msg }}" - when: result.msg is defined and 'NOT_FOUND' not in result.msg - - - name: Create the configuration update for the new channel - ibm.blockchain_platform.channel_config: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - operation: create - name: "{{ channel_name }}" - path: config_update.bin - organizations: - - "{{ org1_name }}" - policies: - Admins: "{{ lookup('template', '09-admins-policy.json.j2') }}" - Readers: "{{ lookup('template', '09-readers-policy.json.j2') }}" - Writers: "{{ lookup('template', '09-writers-policy.json.j2') }}" - Endorsement: "{{ lookup('template', '09-endorsement-policy.json.j2') }}" - LifecycleEndorsement: "{{ lookup('template', '09-lifecycle-endorsement-policy.json.j2') }}" - capabilities: - application: V2_0 - when: result.msg is defined and 'NOT_FOUND' in result.msg - - - name: Sign the channel configuration update for the new channel - ibm.blockchain_platform.channel_config: - operation: sign_update - identity: "{{ wallet }}/{{ org1_name }} Admin.json" - msp_id: "{{ org1_msp_id }}" - name: "{{ channel_name }}" - path: config_update.bin - when: result.msg is defined and 'NOT_FOUND' in result.msg - - - name: Apply the channel configuration update for the new channel - ibm.blockchain_platform.channel_config: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - operation: apply_update - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ org1_name }} Admin.json" - msp_id: "{{ org1_msp_id }}" - name: "{{ channel_name }}" - path: config_update.bin - when: result.msg is defined and 'NOT_FOUND' in result.msg diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-endorsement-policy.json.j2 b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-endorsement-policy.json.j2 deleted file mode 100644 index a7b7a1a2..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-endorsement-policy.json.j2 +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": 1, - "value": { - "rule": { - "n_out_of": { - "n": 1, - "rules": [ - { - "signed_by": 0 - } - ] - } - }, - "identities": [ - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org1_msp_id }}", - "role": "MEMBER" - } - } - ] - } -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-lifecycle-endorsement-policy.json.j2 b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-lifecycle-endorsement-policy.json.j2 deleted file mode 100644 index a7b7a1a2..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-lifecycle-endorsement-policy.json.j2 +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": 1, - "value": { - "rule": { - "n_out_of": { - "n": 1, - "rules": [ - { - "signed_by": 0 - } - ] - } - }, - "identities": [ - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org1_msp_id }}", - "role": "MEMBER" - } - } - ] - } -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-readers-policy.json.j2 b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-readers-policy.json.j2 deleted file mode 100644 index a7b7a1a2..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-readers-policy.json.j2 +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": 1, - "value": { - "rule": { - "n_out_of": { - "n": 1, - "rules": [ - { - "signed_by": 0 - } - ] - } - }, - "identities": [ - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org1_msp_id }}", - "role": "MEMBER" - } - } - ] - } -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-writers-policy.json.j2 b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-writers-policy.json.j2 deleted file mode 100644 index a7b7a1a2..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/09-writers-policy.json.j2 +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": 1, - "value": { - "rule": { - "n_out_of": { - "n": 1, - "rules": [ - { - "signed_by": 0 - } - ] - } - }, - "identities": [ - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org1_msp_id }}", - "role": "MEMBER" - } - } - ] - } -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/10-join-peer-to-channel.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/10-join-peer-to-channel.yml deleted file mode 100644 index d8c48bbc..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/10-join-peer-to-channel.yml +++ /dev/null @@ -1,39 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Join the channel - hosts: localhost - vars: - wallet: "/_cfg" - vars_files: - - /_cfg/fabric-common-vars.yml - - /_cfg/fabric-org1-vars.yml - tasks: - - name: Fetch the genesis block for the channel - ibm.blockchain_platform.channel_block: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - operation: fetch - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ org1_name }} Admin.json" - msp_id: "{{ org1_msp_id }}" - name: "{{ channel_name }}" - target: "0" - path: channel_genesis_block.bin - - - name: Join the peer to the channel - ibm.blockchain_platform.peer_channel: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - operation: join - peer: "{{ org1_peer_name }}" - identity: "{{ wallet }}/{{ org1_name }} Admin.json" - msp_id: "{{ org1_msp_id }}" - path: channel_genesis_block.bin diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/11-add-anchor-peer-to-channel.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/11-add-anchor-peer-to-channel.yml deleted file mode 100644 index 06cd1bb8..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/11-add-anchor-peer-to-channel.yml +++ /dev/null @@ -1,91 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Add the anchor peer to the channel - hosts: localhost - vars: - wallet: "/_cfg" - vars_files: - - /_cfg/fabric-common-vars.yml - - /_cfg/fabric-org1-vars.yml - tasks: - - name: Get the ordering service information - ibm.blockchain_platform.ordering_service_info: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - name: "{{ ordering_service_name }}" - register: ordering_service - - - name: Fail if the ordering service does not exist - fail: - msg: "{{ ordering_service_name }} does not exist" - when: not ordering_service.exists - - - name: Fetch the channel configuration - ibm.blockchain_platform.channel_config: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ org1_name }} Admin.json" - msp_id: "{{ org1_msp_id }}" - operation: fetch - name: "{{ channel_name }}" - path: original_config.bin - - - name: Create a copy of the channel configuration - copy: - src: original_config.bin - dest: updated_config.bin - - - name: Update the organization - ibm.blockchain_platform.channel_member: - state: present - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - organization: "{{ org1_name }}" - anchor_peers: - - "{{ org1_peer_name }}" - path: updated_config.bin - - - name: Compute the channel configuration update - ibm.blockchain_platform.channel_config: - operation: compute_update - name: "{{ channel_name }}" - original: original_config.bin - updated: updated_config.bin - path: config_update.bin - register: compute_update - - - name: Sign the channel configuration update - ibm.blockchain_platform.channel_config: - operation: sign_update - identity: "{{ wallet }}/{{ org1_name }} Admin.json" - msp_id: "{{ org1_msp_id }}" - name: "{{ channel_name }}" - path: config_update.bin - when: compute_update.path - - - name: Apply the channel configuration update - ibm.blockchain_platform.channel_config: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - operation: apply_update - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ org1_name }} Admin.json" - msp_id: "{{ org1_msp_id }}" - name: "{{ channel_name }}" - path: config_update.bin - when: compute_update.path diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/12-create-endorsing-organization-components.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/12-create-endorsing-organization-components.yml deleted file mode 100644 index 8ca33daa..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/12-create-endorsing-organization-components.yml +++ /dev/null @@ -1,18 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Create components for an endorsing organization - hosts: localhost - vars: - state: present - organization_name: "{{ org2_name }}" - organization_msp_id: "{{ org2_msp_id }}" - ca_name: "{{ org2_ca_name }}" - peer_name: "{{ org2_peer_name }}" - wallet: "/_cfg" - vars_files: - - /_cfg/fabric-common-vars.yml - - /_cfg/fabric-org2-vars.yml - roles: - - ibm.blockchain_platform.endorsing_organization diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-add-organization-to-channel.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-add-organization-to-channel.yml deleted file mode 100644 index 278bd961..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-add-organization-to-channel.yml +++ /dev/null @@ -1,124 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Add the organization to the channel - hosts: localhost - vars: - wallet: "/_cfg" - vars_files: - - /_cfg/fabric-common-vars.yml - - /_cfg/fabric-org1-vars.yml - tasks: - - name: Get the ordering service information - ibm.blockchain_platform.ordering_service_info: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - name: "{{ ordering_service_name }}" - register: ordering_service - - - name: Fail if the ordering service does not exist - fail: - msg: "{{ ordering_service_name }} does not exist" - when: not ordering_service.exists - - - name: Fetch the channel configuration - ibm.blockchain_platform.channel_config: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ org1_name }} Admin.json" - msp_id: "{{ org1_msp_id }}" - operation: fetch - name: "{{ channel_name }}" - path: original_config.bin - - - name: Create a copy of the channel configuration - copy: - src: original_config.bin - dest: updated_config.bin - - - name: Add the organization to the channel - ibm.blockchain_platform.channel_member: - state: present - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - organization: "{{ org2_name }}" - path: updated_config.bin - - - name: Update the channel admins policy - ibm.blockchain_platform.channel_policy: - state: present - path: updated_config.bin - name: Admins - policy: "{{ lookup('template', '15-admins-policy.json.j2') }}" - - - name: Update the channel readers policy - ibm.blockchain_platform.channel_policy: - state: present - path: updated_config.bin - name: Readers - policy: "{{ lookup('template', '15-readers-policy.json.j2') }}" - - - name: Update the channel writers policy - ibm.blockchain_platform.channel_policy: - state: present - path: updated_config.bin - name: Writers - policy: "{{ lookup('template', '15-writers-policy.json.j2') }}" - - - name: Update the channel endorsement policy - ibm.blockchain_platform.channel_policy: - state: present - path: updated_config.bin - name: Endorsement - policy: "{{ lookup('template', '15-endorsement-policy.json.j2') }}" - - - name: Update the channel lifecycle endorsement policy - ibm.blockchain_platform.channel_policy: - state: present - path: updated_config.bin - name: LifecycleEndorsement - policy: "{{ lookup('template', '15-lifecycle-endorsement-policy.json.j2') }}" - - - name: Compute the channel configuration update - ibm.blockchain_platform.channel_config: - operation: compute_update - name: "{{ channel_name }}" - original: original_config.bin - updated: updated_config.bin - path: config_update.bin - register: compute_update - - - name: Sign the channel configuration update - ibm.blockchain_platform.channel_config: - operation: sign_update - identity: "{{ wallet }}/{{ org1_name }} Admin.json" - msp_id: "{{ org1_msp_id }}" - name: "{{ channel_name }}" - path: config_update.bin - when: compute_update.path - - - name: Apply the channel configuration update - ibm.blockchain_platform.channel_config: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - operation: apply_update - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ org1_name }} Admin.json" - msp_id: "{{ org1_msp_id }}" - name: "{{ channel_name }}" - path: config_update.bin - when: compute_update.path diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-admins-policy.json.j2 b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-admins-policy.json.j2 deleted file mode 100644 index 3012d99a..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-admins-policy.json.j2 +++ /dev/null @@ -1,34 +0,0 @@ -{ - "type": 1, - "value": { - "rule": { - "n_out_of": { - "n": 2, - "rules": [ - { - "signed_by": 0 - }, - { - "signed_by": 1 - } - ] - } - }, - "identities": [ - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org1_msp_id }}", - "role": "ADMIN" - } - }, - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org2_msp_id }}", - "role": "ADMIN" - } - } - ] - } -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-endorsement-policy.json.j2 b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-endorsement-policy.json.j2 deleted file mode 100644 index 7d4a1611..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-endorsement-policy.json.j2 +++ /dev/null @@ -1,34 +0,0 @@ -{ - "type": 1, - "value": { - "rule": { - "n_out_of": { - "n": 2, - "rules": [ - { - "signed_by": 0 - }, - { - "signed_by": 1 - } - ] - } - }, - "identities": [ - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org1_msp_id }}", - "role": "MEMBER" - } - }, - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org2_msp_id }}", - "role": "MEMBER" - } - } - ] - } -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-lifecycle-endorsement-policy.json.j2 b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-lifecycle-endorsement-policy.json.j2 deleted file mode 100644 index 7d4a1611..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-lifecycle-endorsement-policy.json.j2 +++ /dev/null @@ -1,34 +0,0 @@ -{ - "type": 1, - "value": { - "rule": { - "n_out_of": { - "n": 2, - "rules": [ - { - "signed_by": 0 - }, - { - "signed_by": 1 - } - ] - } - }, - "identities": [ - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org1_msp_id }}", - "role": "MEMBER" - } - }, - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org2_msp_id }}", - "role": "MEMBER" - } - } - ] - } -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-readers-policy.json.j2 b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-readers-policy.json.j2 deleted file mode 100644 index beb0596a..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-readers-policy.json.j2 +++ /dev/null @@ -1,34 +0,0 @@ -{ - "type": 1, - "value": { - "rule": { - "n_out_of": { - "n": 1, - "rules": [ - { - "signed_by": 0 - }, - { - "signed_by": 1 - } - ] - } - }, - "identities": [ - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org1_msp_id }}", - "role": "MEMBER" - } - }, - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org2_msp_id }}", - "role": "MEMBER" - } - } - ] - } -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-writers-policy.json.j2 b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-writers-policy.json.j2 deleted file mode 100644 index beb0596a..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/15-writers-policy.json.j2 +++ /dev/null @@ -1,34 +0,0 @@ -{ - "type": 1, - "value": { - "rule": { - "n_out_of": { - "n": 1, - "rules": [ - { - "signed_by": 0 - }, - { - "signed_by": 1 - } - ] - } - }, - "identities": [ - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org1_msp_id }}", - "role": "MEMBER" - } - }, - { - "principal_classification": "ROLE", - "principal": { - "msp_identifier": "{{ org2_msp_id }}", - "role": "MEMBER" - } - } - ] - } -} \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/16-import-ordering-service.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/16-import-ordering-service.yml deleted file mode 100644 index b5228b9f..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/16-import-ordering-service.yml +++ /dev/null @@ -1,18 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Import the ordering service - hosts: localhost - vars_files: - - /_cfg/fabric-common-vars.yml - - /_cfg/fabric-org2-vars.yml - tasks: - - name: Import the ordering service - ibm.blockchain_platform.external_ordering_service: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - ordering_service: "{{ lookup('file', ordering_service_name+'.json') }}" diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/17-join-peer-to-channel.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/17-join-peer-to-channel.yml deleted file mode 100644 index fd6af27c..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/17-join-peer-to-channel.yml +++ /dev/null @@ -1,39 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Join the channel - hosts: localhost - vars: - wallet: "/_cfg" - vars_files: - - /_cfg/fabric-common-vars.yml - - /_cfg/fabric-org2-vars.yml - tasks: - - name: Fetch the genesis block for the channel - ibm.blockchain_platform.channel_block: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - operation: fetch - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ org2_name }} Admin.json" - msp_id: "{{ org2_msp_id }}" - name: "{{ channel_name }}" - target: "0" - path: channel_genesis_block.bin - - - name: Join the peer to the channel - ibm.blockchain_platform.peer_channel: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - operation: join - peer: "{{ org2_peer_name }}" - identity: "{{ wallet }}/{{ org2_name }} Admin.json" - msp_id: "{{ org2_msp_id }}" - path: channel_genesis_block.bin diff --git a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/18-add-anchor-peer-to-channel.yml b/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/18-add-anchor-peer-to-channel.yml deleted file mode 100644 index 4ca0908f..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/fabric_network_playbooks/18-add-anchor-peer-to-channel.yml +++ /dev/null @@ -1,91 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Add the anchor peer to the channel - hosts: localhost - vars: - wallet: "/_cfg" - vars_files: - - /_cfg/fabric-common-vars.yml - - /_cfg/fabric-org2-vars.yml - tasks: - - name: Get the ordering service information - ibm.blockchain_platform.ordering_service_info: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - name: "{{ ordering_service_name }}" - register: ordering_service - - - name: Fail if the ordering service does not exist - fail: - msg: "{{ ordering_service_name }} does not exist" - when: not ordering_service.exists - - - name: Fetch the channel configuration - ibm.blockchain_platform.channel_config: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ org2_name }} Admin.json" - msp_id: "{{ org2_msp_id }}" - operation: fetch - name: "{{ channel_name }}" - path: original_config.bin - - - name: Create a copy of the channel configuration - copy: - src: original_config.bin - dest: updated_config.bin - - - name: Update the organization - ibm.blockchain_platform.channel_member: - state: present - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - organization: "{{ org2_name }}" - anchor_peers: - - "{{ org2_peer_name }}" - path: updated_config.bin - - - name: Compute the channel configuration update - ibm.blockchain_platform.channel_config: - operation: compute_update - name: "{{ channel_name }}" - original: original_config.bin - updated: updated_config.bin - path: config_update.bin - register: compute_update - - - name: Sign the channel configuration update - ibm.blockchain_platform.channel_config: - operation: sign_update - identity: "{{ wallet }}/{{ org2_name }} Admin.json" - msp_id: "{{ org2_msp_id }}" - name: "{{ channel_name }}" - path: config_update.bin - when: compute_update.path - - - name: Apply the channel configuration update - ibm.blockchain_platform.channel_config: - api_endpoint: "{{ api_endpoint }}" - api_authtype: "{{ api_authtype }}" - api_key: "{{ api_key }}" - api_secret: "{{ api_secret | default(omit) }}" - api_token_endpoint: "{{ api_token_endpoint | default(omit) }}" - operation: apply_update - ordering_service: "{{ ordering_service_name }}" - identity: "{{ wallet }}/{{ org2_name }} Admin.json" - msp_id: "{{ org2_msp_id }}" - name: "{{ channel_name }}" - path: config_update.bin - when: compute_update.path diff --git a/full-stack-asset-transfer-guide/infrastructure/kind_console_ingress/90-KIND-ingress.yml b/full-stack-asset-transfer-guide/infrastructure/kind_console_ingress/90-KIND-ingress.yml deleted file mode 100644 index 257c742c..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/kind_console_ingress/90-KIND-ingress.yml +++ /dev/null @@ -1,37 +0,0 @@ ---- -- name: Setup ingress for KIND for use with Fabric Operator/Console - hosts: localhost - tasks: - - name: Create kubernetes resources for the ingress - k8s: - definition: "{{ lookup('kubernetes.core.kustomize', dir='templates/ingress') }}" - register: resultingress - - - name: Wait for the ingress - command: kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=2m - changed_when: false - - # Override the cluster DNS with a local override to refer pods to the HOST interface - # when connecting to ingress. - - name: Need the cluster ip address - k8s_info: - api_version: v1 - kind: service - namespace: ingress-nginx - name: "ingress-nginx-controller" - register: ingress_info - - - name: Applying CoreDNS overrides for ingress domain - vars: - clusterip: "{{ ingress_info.resources[0].spec.clusterIP }}" - k8s: - state: present - namespace: kube-system - resource_definition: "{{ lookup('template','templates/coredns/coredns.yaml.j2') }}" - apply: yes - - - name: Rollout the CoreDNS - shell: | - kubectl -n kube-system rollout restart deployment/coredns - kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=2m - changed_when: false diff --git a/full-stack-asset-transfer-guide/infrastructure/kind_console_ingress/templates/coredns/coredns.yaml.j2 b/full-stack-asset-transfer-guide/infrastructure/kind_console_ingress/templates/coredns/coredns.yaml.j2 deleted file mode 100644 index 59065d96..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/kind_console_ingress/templates/coredns/coredns.yaml.j2 +++ /dev/null @@ -1,33 +0,0 @@ ---- -kind: ConfigMap -apiVersion: v1 -metadata: - name: coredns - namespace: kube-system -data: - Corefile: | - .:53 { - errors - health { - lameduck 5s - } - rewrite name regex (.*)\.localho\.st host.ingress.internal - hosts { - {{ clusterip }} host.ingress.internal - fallthrough - } - ready - kubernetes cluster.local in-addr.arpa ip6.arpa { - pods insecure - fallthrough in-addr.arpa ip6.arpa - ttl 30 - } - prometheus :9153 - forward . /etc/resolv.conf { - max_concurrent 1000 - } - cache 30 - loop - reload - loadbalance - } \ No newline at end of file diff --git a/full-stack-asset-transfer-guide/infrastructure/kind_console_ingress/templates/ingress/ingress-nginx-controller.yaml b/full-stack-asset-transfer-guide/infrastructure/kind_console_ingress/templates/ingress/ingress-nginx-controller.yaml deleted file mode 100644 index 72b7feed..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/kind_console_ingress/templates/ingress/ingress-nginx-controller.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright contributors to the Hyperledger Fabric Operator project -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - namespace: ingress-nginx - name: ingress-nginx-controller -spec: - template: - spec: - containers: - - name: controller - args: - - /nginx-ingress-controller - - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller - - --election-id=ingress-controller-leader - - --controller-class=k8s.io/ingress-nginx - - --ingress-class=nginx - - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller - - --validating-webhook=:8443 - - --validating-webhook-certificate=/usr/local/certificates/cert - - --validating-webhook-key=/usr/local/certificates/key - - --enable-ssl-passthrough diff --git a/full-stack-asset-transfer-guide/infrastructure/kind_console_ingress/templates/ingress/kustomization.yaml b/full-stack-asset-transfer-guide/infrastructure/kind_console_ingress/templates/ingress/kustomization.yaml deleted file mode 100644 index e1392885..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/kind_console_ingress/templates/ingress/kustomization.yaml +++ /dev/null @@ -1,36 +0,0 @@ -# -# Copyright contributors to the Hyperledger Fabric Operator project -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: -- https://github.com/kubernetes/ingress-nginx.git/deploy/static/provider/cloud?ref=controller-v1.1.2 - - -# Remove the port `appProtocol` attribute as this is not accepted by all cloud providers -patches: -- patch: |- - - op: remove - path: "/spec/ports/0/appProtocol" - - op: remove - path: "/spec/ports/1/appProtocol" - target: - kind: Service - name: ingress-nginx-controller - version: v1 -- path: ingress-nginx-controller.yaml diff --git a/full-stack-asset-transfer-guide/infrastructure/kind_with_nginx.sh b/full-stack-asset-transfer-guide/infrastructure/kind_with_nginx.sh deleted file mode 100755 index 39ac1a58..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/kind_with_nginx.sh +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/bash -# -# Copyright contributors to the Hyperledgendary Full Stack Asset Transfer project -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -set -eo pipefail -set -x - -KIND_CLUSTER_NAME=kind -KIND_CLUSTER_IMAGE=${KIND_CLUSTER_IMAGE:-kindest/node:v1.28.0} # Important! k8s v1.25.0 brings breaking changes. -KIND_API_SERVER_ADDRESS=${KIND_API_SERVER_ADDRESS:-127.0.0.1} -KIND_API_SERVER_PORT=${KIND_API_SERVER_PORT:-8888} -CONTAINER_REGISTRY_NAME=${CONTAINER_REGISTRY_NAME:-kind-registry} -CONTAINER_REGISTRY_ADDRESS=${CONTAINER_REGISTRY_ADDRESS:-127.0.0.1} -CONTAINER_REGISTRY_PORT=${CONTAINER_REGISTRY_PORT:-5000} - -function kind_with_nginx() { - - delete_cluster - - create_cluster - - start_nginx - - apply_coredns_override - - launch_docker_registry -} - -# -# Delete a kind cluster if it exists -# -function delete_cluster() { - kind delete cluster --name $KIND_CLUSTER_NAME -} - -# -# Create a local KIND cluster -# -function create_cluster() { - cat << EOF | kind create cluster --name $KIND_CLUSTER_NAME --image $KIND_CLUSTER_IMAGE --config=- ---- -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -nodes: - - role: control-plane - kubeadmConfigPatches: - - | - kind: InitConfiguration - nodeRegistration: - kubeletExtraArgs: - node-labels: "ingress-ready=true" - extraPortMappings: - - containerPort: 80 - hostPort: 80 - protocol: TCP - - containerPort: 443 - hostPort: 443 - protocol: TCP -networking: - apiServerAddress: ${KIND_API_SERVER_ADDRESS} - apiServerPort: ${KIND_API_SERVER_PORT} - -# create a cluster with the local registry enabled in containerd -containerdConfigPatches: -- |- - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${CONTAINER_REGISTRY_PORT}"] - endpoint = ["http://${CONTAINER_REGISTRY_NAME}:${CONTAINER_REGISTRY_PORT}"] -EOF - - # - # Work around a bug in KIND where DNS is not always resolved correctly on machines with IPv6 - # - for node in $(kind get nodes); - do - docker exec "$node" sysctl net.ipv4.conf.all.route_localnet=1; - done -} - -# -# Install an Nginx ingress controller bound to port 80 and 443. -# ssl_passthrough mode is enabled for TLS termination at the Fabric node enpdoints. -# -function start_nginx() { - kubectl apply -k https://github.com/hyperledger-labs/fabric-operator.git/config/ingress/kind - - sleep 20 - - kubectl wait --namespace ingress-nginx \ - --for=condition=ready pod \ - --selector=app.kubernetes.io/component=controller \ - --timeout=3m -} - -# -# Override Core DNS with a wildcard matcher for the "*.localho.st" domain, binding to the -# IP address of the Nginx ingress controller on the kubernetes internal network. Effectively this -# "steals" the domain name for *.localho.st, directing traffic to the Nginx load balancer, rather -# than to the loopback interface at 127.0.0.1. -# -function apply_coredns_override() { - CLUSTER_IP=$(kubectl -n ingress-nginx get svc ingress-nginx-controller -o json | jq -r .spec.clusterIP) - - cat << EOF | kubectl apply -f - ---- -kind: ConfigMap -apiVersion: v1 -metadata: - name: coredns - namespace: kube-system -data: - Corefile: | - .:53 { - errors - health { - lameduck 5s - } - ready - rewrite name regex (.*)\.localho\.st host.ingress.internal - hosts { - ${CLUSTER_IP} host.ingress.internal - fallthrough - } - kubernetes cluster.local in-addr.arpa ip6.arpa { - pods insecure - fallthrough in-addr.arpa ip6.arpa - ttl 30 - } - prometheus :9153 - forward . /etc/resolv.conf { - max_concurrent 1000 - } - cache 30 - loop - reload - loadbalance - } -EOF - - kubectl -n kube-system rollout restart deployment/coredns -} - -function launch_docker_registry() { - - # create registry container unless it already exists - running="$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" - if [ "${running}" != 'true' ]; then - docker run \ - --detach \ - --restart always \ - --name "${CONTAINER_REGISTRY_NAME}" \ - --publish "${CONTAINER_REGISTRY_ADDRESS}:${CONTAINER_REGISTRY_PORT}:${CONTAINER_REGISTRY_PORT}" \ - registry:2 - fi - - # connect the registry to the cluster network - # (the network may already be connected) - docker network connect "kind" "${CONTAINER_REGISTRY_NAME}" || true - - # Document the local registry - # https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry - cat < - - -pacakge_update: true -package_upgrade: true -packages: - - jq - - curl - - software-properties-common - -write_files: -- path: /config/provision-root.sh - permissions: '0744' - content: | - #!/usr/bin/env bash - set -ex - # set -o errexit - # set -o pipefail - - if [ -z $1 ]; then - HLF_VERSION=2.2.0 - else - HLF_VERSION=$1 - fi - - if [ ${HLF_VERSION:0:4} = '2.5.' -o ${HLF_VERSION:0:4} = '2.4.']; then - export GO_VERSION=1.18.10 - elif [ ${HLF_VERSION:0:4} = '2.2.' -o ${HLF_VERSION:0:4} = '2.3.' ]; then - export GO_VERSION=1.14.11 - elif [ ${HLF_VERSION:0:4} = '2.0.' -o ${HLF_VERSION:0:4} = '2.1.' ]; then - export GO_VERSION=1.13.15 - elif [ ${HLF_VERSION:0:4} = '1.2.' -o ${HLF_VERSION:0:4} = '1.3.' -o ${HLF_VERSION:0:4} = '1.4.' ]; then - export GO_VERSION=1.10.4 - elif [ ${HLF_VERSION:0:4} = '1.1.' ]; then - export GO_VERSION=1.9.7 - else - >&2 echo "Unexpected HLF_VERSION ${HLF_VERSION}" - >&2 echo "HLF_VERSION must be a 1.1.x, 1.2.x, 1.3.x, 1.4.x, 2.0.x, 2.1.x, 2.2.x, 2.3.x, 2.4.x, or 2.5.x version" - exit 1 - fi - - - # APT setup for kubectl - curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - - apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main" - - # Install kubectl - apt-get -y --no-upgrade install kubectl - - # Install yq - YQ_VERSION=4.23.1 - if [ ! -x "/usr/local/bin/yq" ]; then - curl --fail --silent --show-error -L "https://github.com/mikefarah/yq/releases/download/v${YQ_VERSION}/yq_linux_amd64" -o /usr/local/bin/yq - chmod 755 /usr/local/bin/yq - fi - - # Install docker compose - if [ ! -x /usr/local/bin/docker-compose ]; then - curl --fail --silent --show-error -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose - chmod 755 /usr/local/bin/docker-compose - fi - - # Install kind - KIND_VERSION=0.14.0 - if [ ! -x "/usr/local/bin/kind" ]; then - curl --fail --silent --show-error -L "https://kind.sigs.k8s.io/dl/v${KIND_VERSION}/kind-linux-amd64" -o /usr/local/bin/kind - chmod 755 /usr/local/bin/kind - fi - - # Install k9s - K9S_VERSION=0.25.3 - if [ ! -x "/usr/local/bin/k9s" ]; then - curl --fail --silent --show-error -L "https://github.com/derailed/k9s/releases/download/v${K9S_VERSION}/k9s_Linux_x86_64.tar.gz" -o "/tmp/k9s_Linux_x86_64.tar.gz" - tar -zxf "/tmp/k9s_Linux_x86_64.tar.gz" -C /usr/local/bin k9s - chown root:root /usr/local/bin/k9s - chmod 755 /usr/local/bin/k9s - fi - - # Install ccmetadata - CCMETADATA_VERSION=0.2.0 - if [ ! -x "/usr/local/bin/ccmetadata" ]; then - curl --fail --silent --show-error -L "https://github.com/hyperledgendary/ccmetadata/releases/download/v${CCMETADATA_VERSION}/ccmetadata-Linux-X64.tgz" -o "/tmp/ccmetadata-Linux-X64.tgz" - tar -zxf "/tmp/ccmetadata-Linux-X64.tgz" -C /usr/local/bin ccmetadata - chown root:root /usr/local/bin/ccmetadata - chmod 755 /usr/local/bin/ccmetadata - fi - - # Install just - JUST_VERSION=1.2.0 - if [ ! -x "/usr/local/bin/just" ]; then - curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --tag ${JUST_VERSION} --to /usr/local/bin - chown root:root /usr/local/bin/just - chmod 755 /usr/local/bin/just - fi - -- path: /config/provision-user.sh - permissions: '0777' - owner: ubuntu:ubuntu - content: | - export NVM_DIR="$HOME/.nvm" - [ -s "$NVM_DIR/nvm.sh" ] || curl --fail --silent --show-error -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.3/install.sh | bash - . "$NVM_DIR/nvm.sh" - - # Install latest node v16.x, latest typescript, weft - nvm install 16 - npm install -g typescript - npm install -g @hyperledger-labs/weft - -# Use Google DNS as the mac resolvers are not 100% reliable for the npm dependency builds in Docker -bootcmd: - - printf "[Resolve]\nDNS=8.8.8.8" > /etc/systemd/resolved.conf - - [systemctl, restart, systemd-resolved] - -runcmd: - - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - - - add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" - - apt-get update -y - - apt-get install -y docker.io - - usermod -a -G docker ubuntu - - /config/provision-root.sh - - su -c /config/provision-user.sh ubuntu - -final_message: "The system is finally up, after $UPTIME seconds" diff --git a/full-stack-asset-transfer-guide/infrastructure/operator_console_playbooks/01-operator-install.yml b/full-stack-asset-transfer-guide/infrastructure/operator_console_playbooks/01-operator-install.yml deleted file mode 100644 index daba33ce..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/operator_console_playbooks/01-operator-install.yml +++ /dev/null @@ -1,13 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Deploy Opensource custom resource definitions and operator - hosts: localhost - vars_files: - - /_cfg/operator-console-vars.yml - vars: - state: present - wait_timeout: 3600 - roles: - - hyperledger.fabric_ansible_collection.fabric_operator_crds diff --git a/full-stack-asset-transfer-guide/infrastructure/operator_console_playbooks/02-console-install.yml b/full-stack-asset-transfer-guide/infrastructure/operator_console_playbooks/02-console-install.yml deleted file mode 100644 index 936621ff..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/operator_console_playbooks/02-console-install.yml +++ /dev/null @@ -1,13 +0,0 @@ -# -# SPDX-License-Identifier: Apache-2.0 -# ---- -- name: Deploy Opensource Console - hosts: localhost - vars_files: - - /_cfg/operator-console-vars.yml - vars: - state: present - wait_timeout: 3600 - roles: - - hyperledger.fabric_ansible_collection.fabric_console diff --git a/full-stack-asset-transfer-guide/infrastructure/pkgcc.sh b/full-stack-asset-transfer-guide/infrastructure/pkgcc.sh deleted file mode 100755 index 33cce1a2..00000000 --- a/full-stack-asset-transfer-guide/infrastructure/pkgcc.sh +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/sh -l - - -# From the github action -# https://github.com/hyperledgendary/package-k8s-chaincode-action/blob/main/pkgk8scc.sh -# -# SPDX-License-Identifier: Apache-2.0 -# - -usage() { - echo "Usage: pkgk8scc.sh -l /fabric-samples/test-network -> ``` -> -> See the bottom of this readme for instructions to use another Fabric network than the test network. - -Install tokengen. Tokengen is a tool to create the configuration file for the token chaincode (once, when deploying the chaincode). It generates the public parameters that the network participants will use to generate their proofs, and it specifies the public identities of the issuer, auditor and CA for signature validation. - -```bash -go install github.com/hyperledger-labs/fabric-token-sdk/cmd/tokengen@v0.3.0 -``` - -### Quick start - -The quickest way to get going is to run: - -```bash -./scripts/up.sh -``` - -This generates the crypto material, starts Fabric, deploys the chaincode, and starts the token nodes. - -When you're done and want to delete everything: - -```bash -./scripts/down.sh -``` - -#### Using the application - -The services are accessible on the following ports: - -| port | service | -|------|--------------------------| -| 8080 | API documentation (web) | -| 9000 | auditor | -| 9100 | issuer | -| 9200 | owner 1 (alice and bob) | -| 9300 | owner 2 (carlos and dan) | - -Besides that, the nodes communicate with each other via 9001, 9101, 9201 and 9301 respectively. - -Now let's issue and transfer some tokens! View the API documentation and try some actions at [http://localhost:8080](http://localhost:8080). Or, directly from the commandline: - -```bash -curl -X POST http://localhost:9100/api/v1/issuer/issue -H 'Content-Type: application/json' -d '{ - "amount": {"code": "TOK","value": 1000}, - "counterparty": {"node": "owner1","account": "alice"}, - "message": "hello world!" -}' - -curl -X GET http://localhost:9200/api/v1/owner/accounts -curl -X GET http://localhost:9300/api/v1/owner/accounts - -curl -X POST http://localhost:9200/api/v1/owner/accounts/alice/transfer -H 'Content-Type: application/json' -d '{ - "amount": {"code": "TOK","value": 100}, - "counterparty": {"node": "owner2","account": "dan"}, - "message": "hello dan!" -}' - -curl -X GET http://localhost:9300/api/v1/owner/accounts/dan/transactions -curl -X GET http://localhost:9200/api/v1/owner/accounts/alice/transactions -``` - -Notice that the transaction overview uses the UTXO model (like bitcoin). The issuer created a new TOK token of 1000 and assigned its ownership to alice. When alice transfered 100 TOK to dan, she used the token of 1000 as **input** for her transaction. As **output**, she creates two new tokens: - -1. one for 100 TOK with dan as the owner -2. one with _herself_ as the owner for the remaining 900 TOK. - -This way, each transaction can have multiple inputs and multiple outputs. Their sum should always be the same, and every new transfer must be based on previously created outputs. - -#### Deep dive: what happens when doing a transfer? - -It may look simple from the outside, but there's a lot going on to securely and privately transfer tokens. Let's take the example of alice (on the Owner 1 node) transfering 100 TOK to dan (on the Owner 2 node). - -1. **Create Transaction**: Alice requests an anonymous key from dan that will own the tokens. She then creates the transaction, with commitments that can be verified by anyone, but _only_ be opened (read) by dan and the auditor. The commitments contain the value, sender and recipient of each of the in- and output tokens. -2. **Get Endorsements**: Alice (or more precisely the TransferView in the Owner 1 node) now submits the transaction to the auditor, who validates and stores it. The auditor _may_ enforce any specific business logic that is needed for this token in this ecosystem (for instance a transaction or holding limit). - - Alice then submits the transaction (which is now also signed by the auditor) to the Token Chaincode which is running on the Fabric peers. The chaincode verifies that all the proofs are valid and all the necessary signatures are there. Note that the peer and token chaincode cannot see what is transferred between who thanks to the zero knowledge proofs. -3. **Commit Transaction**: Alice submits the endorsed Fabric transaction to the ordering service. Alice (Owner 1), dan (Owner 2) and the Auditor nodes have been listening for Fabric events involving this transaction. When receiving the 'commit' event, they change the status of the stored transaction to 'Confirmed'. The transaction is now final; dan owns the 100 TOK. - -The names of the Views below correspond to the code in `owner/service/transfer.go`, `owner/service/accept.go` and `auditor/service/audit.go`. - -![transfer](transfer.png) - -[plantuml source](http://www.plantuml.com/plantuml/uml/TLD1JoCz3BtdLrZb0X98yEaxhTGLRA5xu50EQ0-hNZA92r6dpcpY3Eg_tsHcYDmoUvb9hFUUxHVxFh8Ed0wjOiSjmclG57SOWCj16tQUbCf_7s3nq3g32z0HjEeopHdNQM9OR3ueK-wsjALFWLyEFmOezt2n-l6qNZ_ESVuhd0TZiEELZk-LrRXvraEoZdqOMELO2JhPob18xFW8YxLkWZFmWXZYWEhA2IuU_ry_hfxEOPjWCNmYVRb8i5ekOHLGCqflOBbK6cw-bpQ_0N-wTtTx2w-Rvosn1wi9Cd3gLnLUhnc5CJKcs-Q-o3OkomRyap1o_cSR71A3isFjIiefgQCQL_bcB5kJf-F1fxYbIqzum-w0DodY5UpnAF5lI1WA8sAcCkoAuR-VNy3umy7n0OcZ2iWf47IfQPqf2jSJN5ayAOhxwa_45Ws3eouniDyZHTb0XTQQHv0qFDS-qA_19nx-NV1-5tDszqQQKy0hwLryrm6bmBzCyXsIRF1wIpq6jpkEoldBFk2MNf2iepSfENanuD12mDXvYWZdJkG9-eaCMS27Y4EMF3zJjJfPyTJvvbXwKyydarxEbTlhrjcC6AFLyzEYncpZ8jHyiYQHzNHRnflWEkhzVdeYywuT6M-nZ7ojPCwaAPE5ox6oAnZNJs9dZ5iDBoD1rRgwgwNRr6JOdEISbr-tl0PEPST9a7fvFAOHRLflze8e76g2rzReo43uCG4jVicUhPsOvqimD3r4SaZdoERvr9kpcr2IqrsL1Bfn4gsJbSCqHoWGTOzaqw7z2m00) - -### Alternative: manual start - -To get a better view or have more control on the different layers of the network, you can also start the services manually. If you want to do that, first bring down everything with `./scripts/down.sh`. - -#### Generate crypto material - -In this step, we create all the identities which are used by the Token network. We use a normal Fabric CA for this. Technically, only the Owner identities (the wallets that will hold the tokens) need some form of hierarchy; they use Idemix credentials which must be issued by a single, known issuer (see [Fabric documentation](https://hyperledger-fabric.readthedocs.io/en/latest/idemix.html) for more info about idemix). To keep things simple, we use the same CA for the other identities too. The Token SDK expects the folders for the identities to be in Fabric's 'msp' structure. - -The following crypto will be generated: - - - Fabric Smart Client node identities, used by the nodes to authenticate each other - - Token Issuer identity (x509 certificate and private key) - - Token Auditor identity (x509 certificate and private key) - - Owner identities (idemix credentials) - -```bash -mkdir -p keys/ca -docker-compose -f compose-ca.yaml up -d -./scripts/enroll-users.sh -``` - -> If you want, you can stop the CA now. You don't need it unless you want to register more users. -> -> ```bash -> docker-compose -f compose-ca.yaml down -> ``` - -The Issuer and Auditor identities are used by the Token Chaincode to validate token transactions. It also needs the identity of the CA that issues the Idemix credentials to the Owner wallets. The tokengen command generates the configuration that contains these identities and the cryptographic parameters for the proofs. We store it in the `tokenchaincode` folder, so that it will be baked into the chaincode docker image later. - -```bash -tokengen gen dlog --base 300 --exponent 5 --issuers keys/issuer/iss/msp --idemix keys/owner1/wallet/alice --auditors keys/auditor/aud/msp --output tokenchaincode -``` - -> You only have to do this once. But if for any reason you want to re-generate the material: `rm -rf keys; rm tokenchaincode/zkatdlog_pp.json` and execute the steps above again. If any owner has existing tokens, they will now be invalid because the old proofs can not be verified with the new parameters. - -#### Start Fabric and install the chaincode - -For simplicity, in this sample all nodes use the credentials of User1 from Org1MSP and have Peer1 as a trusted peer. In a more serious setup, each instance would have its own (idemix) Fabric user and _may_ have it's own MSP and peers, depending on the network topology and trust relationships. - -Start a Fabric sample network and deploy the Token Chaincode as a service: - -```bash -../test-network/network.sh up createChannel -INIT_REQUIRED="--init-required" ../test-network/network.sh deployCCAAS -ccn tokenchaincode -ccp $(pwd)/tokenchaincode -cci "init" -verbose -ccs 1 - -mkdir -p keys/fabric && cp -r ../test-network/organizations keys/fabric/ -``` - -> To fully remove the whole network: -> ```bash -> docker stop peer0org1_tokenchaincode_ccaas peer0org2_tokenchaincode_ccaas -> ../test-network/network.sh" down -> rm -rf keys/fabric -> ``` - -#### Start the Token network - -> On the bottom of this document you'll find instructions to run the nodes as golang binaries natively instead of with docker compose. - -```bash -rm -rf data/auditor data/issuer data/owner1 data/owner2 -mkdir -p data/auditor data/issuer data/owner1 data/owner2 -docker-compose up -d -``` - -Visit [http://localhost:8080](http://localhost:8080) to view the API documentation and execute some transactions. - -### View the blockchain explorer - -As a bonus, this sample contains configuration to connect the [blockchain explorer](https://github.com/hyperledger-labs/blockchain-explorer/) with the fabric-samples network. It allows you to inspect the transactions which are committed to the ledger. It shows more of what the Token SDK does under the covers. - -Start it as follows: - -```bash -cd explorer -docker-compose up -d -``` - -And visit it in the browser on [localhost:8081](http://localhost:8081). - -To tear it down, do this (the -v is important; it removes the volumes that contain the identities and blocks): - -```bash -docker-compose down -v -``` - -## Development - -### End to end tests - -See the `e2e` folder for some tests that exercise the APIs. The end to end tests require the services to be running. They create new transactions, so don't run them on a deployment you want to keep clean. - -```bash -go test ./e2e -count=1 -v -``` - -### Code structure - -This repo contains 3 different, isolated golang applications, one for each of the roles: *issuer*, *auditor*, and *owner*. They are maintained separately and each have their own dependencies. In a production scenario these would have their own lifecycle, and most likely be maintained and deployed by different organizations. - -The code structure of each of the roles is the same. There is overlap between the roles; each has the boilerplate code to start the Fabric Smart Client and Token SDK. The main.go is almost identical; the only difference is which 'responders' the application registers. Also the contents of the routes and the services will depend on the features that a role needs: - -- Issuers can issue funds -- Auditors see and sign every transaction -- Owners can transfer funds. - -Here's an example of the code structure for the auditor: - -``` -auditor -├── main.go -├── oapi-server.yaml -├── conf -│ └── core.yaml -├── routes -│ ├── operations.go -│ ├── routes.gen.go -│ ├── routes.go -│ └── server.go -└── service - ├── audit.go - ├── balance.go - └── history.go -``` - -As you can see, the business logic is all in the 'service' directory. The 'routes' are purely the code needed for the REST API. We chose to use *openapi-codegen* to generate the code for the routes, and *echo* as the server. The 'routes' package is just the presentation layer; you could easily replace it and call the code from the 'service' package from somewhere else. For instance if you wanted to create a CLI application for the issuer! - -![dependencies](./dependencies.png) - -[plantuml](http://www.plantuml.com/plantuml/uml/RP71QlCm3CVlVWhHxnpw1X_jeR32e6FhRVIWEafgubX6ThgMqNTVQZjqAOD0PFd7pt_Pgn1Huj1RrGZs18lTboE19Mn365An7ceJMHRmhG36ht1R5qaSMl2eEsmfB00369ymWCyUZJlSM_S2_gszjqPZDEpoll0GAIGYbtymWUHiD2KedFKpSLEGxLLT_Ry3itMsAfZq1NbCy7Br99RgbWHUyHZcav2FqoWD7iNeAlGeiTBMa8ifKXF6I7lI9yUMs-iCZjoHgqBT9NByFv7pxEIZWZHYMJnIxkA91EYIRxj4uocQxzebYR24GvPcINQo-kNPN9xU2neMUDzyx67zjYrUdBoCtbIQQsh97NAhCwvYJsxSAPrn7fwEBPTSJaPrKojozT3R7m00) - -For more information about how we interact with the Token SDK, check out an example on the [Token SDK GitHub](https://github.com/hyperledger-labs/fabric-token-sdk/blob/main/samples/fungible/README.md). - -### Add or change a REST API endpoint - -We generate the API based on `swagger.yaml`. To keep things a bit simple, we have only one definition which includes all of the roles (even though they are separate applications, running on different ports!) Any changes should be made in this file first. Then generate the code with: - -```bash -go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@latest - -oapi-codegen -config auditor/oapi-server.yaml swagger.yaml -oapi-codegen -config issuer/oapi-server.yaml swagger.yaml -oapi-codegen -config owner/oapi-server.yaml swagger.yaml -oapi-codegen -config e2e/oapi-client.yaml swagger.yaml -``` - -### Upgrade the Token SDK and Fabric Smart Client versions - -Token SDK and Fabric Smart Client are under active development. To upgrade to the latest versions: - -- change the commit hash of fabric-smart-client and fabric-token-sdk in {auditor,issuer,owner}/go.mod (and do `go mod tidy`) -- change the commit hash in tokenchaincode/Dockerfile -- install tokengen with the new commit hash -- update the readme - -### Use another Fabric network - -Of course you're not tied to the Fabric samples testnetwork. If you want to anchor your Token services to another blockchain, you have to: - -1. Deploy the token chaincode with the generated parameters to the Fabric network -2. Configure the token services with the correct channel, peer and orderer addresses and certs, MSP configuration, and a user (see the `core.yaml` files in the `conf` dir). - -### Add a user / account - -To add another user, simply register and enroll it at the Token CA (see `scripts/enroll-users.sh`), and configure it at one of the owner nodes (see `conf` dir). - -### Run the service directly (instead of with docker-compose) - -For a faster development cycle, you may choose to run the services outside of docker. It requires some adjustments to your environment to make the paths and routes work. - -Add the following to your `/etc/hosts`: - -``` -127.0.0.1 peer0.org1.example.com -127.0.0.1 peer0.org2.example.com -127.0.0.1 orderer.example.com -127.0.0.1 owner1.example.com -127.0.0.1 owner2.example.com -127.0.0.1 auditor.example.com -127.0.0.1 issuer.example.com -``` - -> The Token SDK discovers the peer addresses from the channel config (after connecting to a configured trusted peer). - -For the paths you have two options: - -1. Find/replace all instances of /var/fsc in the conf directory with the path to this repo. **Or** -2. Create a symlink to this folder to make the configuration files work (they don't play nice with relative paths): - ```bash - sudo ln -s "${PWD}" /var/fsc - ``` - The advantage of this approach is that the configuration is portable across developer laptops and works with docker-compose as well as without. - -Start the blockchain and deploy the chaincode (see above). - -Instead of doing docker-compose up, start the token services with (each in their own terminal): - -```bash -mkdir bin -go build -o bin/auditor ./auditor -go build -o bin/issuer ./issuer -go build -o bin/owner ./owner - -PORT=9000 CONF_DIR=./auditor/conf ./bin/auditor -PORT=9100 CONF_DIR=./issuer/conf ./bin/issuer -PORT=9200 CONF_DIR=./owner/conf/owner1 ./bin/owner -PORT=9300 CONF_DIR=./owner/conf/owner2 ./bin/owner -``` - -Now you can use the REST APIs to control the services (see the swagger definition). - -When you made changes in the code, stop a service with CTRL+C, `go build -o bin/owner ./owner` and start it again. - -If you want to reset the transaction history: - -```bash -rm -rf data/auditor data/issuer data/owner1 data/owner2 && mkdir data/auditor data/issuer data/owner1 data/owner2 -``` diff --git a/token-sdk/auditor/conf/core.yaml b/token-sdk/auditor/conf/core.yaml deleted file mode 100644 index e1f52927..00000000 --- a/token-sdk/auditor/conf/core.yaml +++ /dev/null @@ -1,112 +0,0 @@ -logging: - spec: info - format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' - -# ------------------- FSC Node Configuration ------------------------- -# The FSC node is responsible for the peer to peer communication with other token services. -fsc: - identity: - cert: - file: /var/fsc/keys/auditor/fsc/msp/signcerts/cert.pem - key: - file: /var/fsc/keys/auditor/fsc/msp/keystore/priv_sk - tls: - enabled: false # TODO - p2p: - listenAddress: /ip4/0.0.0.0/tcp/9001 - # If empty, this is a P2P boostrap node. Otherwise, it contains the name of the FSC node that is a bootstrap node. - # The name of the FSC node that is a bootstrap node must be set under fsc.endpoint.resolvers - bootstrapNode: - kvs: # key-value-store - persistence: - type: badger # badger or memory - opts: - path: /var/fsc/data/auditor/kvs - - # The endpoint section tells how to reach other FSC node in the network. - # For each node, the name, the domain, the identity of the node, and its addresses must be specified. - endpoint: - resolvers: - - name: issuer - identity: - id: issuer - path: /var/fsc/keys/issuer/fsc/msp/signcerts/cert.pem - addresses: - P2P: issuer.example.com:9101 - - name: owner1 - identity: - id: owner1 - path: /var/fsc/keys/owner1/fsc/msp/signcerts/cert.pem - addresses: - P2P: owner1.example.com:9201 - - name: owner2 - identity: - id: owner2 - path: /var/fsc/keys/owner2/fsc/msp/signcerts/cert.pem - addresses: - P2P: owner2.example.com:9301 - -# ------------------- Fabric Configuration ------------------------- -fabric: - enabled: true - mynetwork: - default: true - mspConfigPath: /var/fsc/keys/fabric/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp - defaultMSP: Org1MSP - msps: - - id: Org1MSP - mspType: bccsp - mspID: Org1MSP - path: /var/fsc/keys/fabric/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp - tls: - enabled: true - # If the keepalive values are too low, Fabric peers will complain with: ENHANCE_YOUR_CALM, debug data: "too_many_pings" - keepalive: - interval: 300s - timeout: 600s - # List of orderer nodes this node can connect to. There must be at least one orderer node. Others are discovered. - orderers: - - address: orderer.example.com:7050 - connectionTimeout: 10s - tlsEnabled: true - tlsRootCertFile: /var/fsc/keys/fabric/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt - serverNameOverride: orderer.example.com - # List of trusted peers this node can connect to. There must be at least one trusted peer. Others are discovered. - peers: - - address: peer0.org1.example.com:7051 - connectionTimeout: 10s - tlsEnabled: true - tlsRootCertFile: /var/fsc/keys/fabric/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt - serverNameOverride: peer0.org1.example.com - # Channel where the token chaincode is deployed - channels: - - name: mychannel - default: true - # Configuration of the vault used to store the RW sets assembled by this node - vault: - persistence: - type: badger - opts: - path: /var/fsc/data/auditor/vault - -# ------------------- Token SDK Configuration ------------------------- -token: - enabled: true - tms: - mytms: # unique name of this token management system - network: mynetwork # the name of the fabric network as configured above - channel: mychannel # the name of the network's channel this TMS refers to, if applicable - namespace: tokenchaincode # chaincode name - driver: zkatdlog # privacy preserving driver (zero knowledge asset transfer) - wallets: - auditors: - - id: auditor # the unique identifier of this wallet. Here is an example of use: `ttx.GetIssuerWallet(context, "issuer)` - default: true # is this the default issuer wallet - path: /var/fsc/keys/auditor/aud/msp - # Internal database to keep track of token transactions. - # It is used by auditors and token owners to track history - ttxdb: - persistence: - type: badger - opts: - path: /var/fsc/data/auditor/txdb diff --git a/token-sdk/auditor/go.mod b/token-sdk/auditor/go.mod deleted file mode 100644 index 4767b523..00000000 --- a/token-sdk/auditor/go.mod +++ /dev/null @@ -1,245 +0,0 @@ -module github.com/hyperledger/fabric-samples/token-sdk/auditor - -go 1.22.0 - -replace github.com/ugorji/go v1.1.4 => github.com/ugorji/go/codec v1.2.9 - -require ( - github.com/deepmap/oapi-codegen v1.15.0 - github.com/getkin/kin-openapi v0.120.0 - github.com/hyperledger-labs/fabric-smart-client v0.3.0 - github.com/hyperledger-labs/fabric-token-sdk v0.3.0 - github.com/labstack/echo/v4 v4.11.1 - github.com/pkg/errors v0.9.1 -) - -require ( - github.com/BurntSushi/toml v1.3.2 // indirect - github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect - github.com/CloudyKit/jet/v6 v6.2.0 // indirect - github.com/IBM/idemix v0.0.2-0.20230831093709-b7a940638990 // indirect - github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20230831093709-b7a940638990 // indirect - github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20230831093709-b7a940638990 // indirect - github.com/IBM/idemix/bccsp/types v0.0.0-20230831093709-b7a940638990 // indirect - github.com/IBM/mathlib v0.0.3-0.20230831091907-c532c4d3b65c // indirect - github.com/Joker/jade v1.1.3 // indirect - github.com/ReneKroon/ttlcache/v2 v2.11.0 // indirect - github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect - github.com/ale-linux/aries-framework-go/component/kmscrypto v0.0.0-20230817163708-4b3de6d91874 // indirect - github.com/andybalholm/brotli v1.0.5 // indirect - github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/aymerick/douceur v0.2.0 // indirect - github.com/benbjohnson/clock v1.3.5 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/bytedance/sonic v1.9.1 // indirect - github.com/cenkalti/backoff/v4 v4.2.0 // indirect - github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/consensys/bavard v0.1.13 // indirect - github.com/consensys/gnark-crypto v0.9.1 // indirect - github.com/containerd/cgroups v1.1.0 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect - github.com/dgraph-io/badger/v3 v3.2103.2 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/elastic/gosigar v0.14.2 // indirect - github.com/fatih/structs v1.1.0 // indirect - github.com/flosch/pongo2/v4 v4.0.2 // indirect - github.com/flynn/noise v1.0.0 // indirect - github.com/francoispqt/gojay v1.2.13 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-gonic/gin v1.9.1 // indirect - github.com/go-kit/kit v0.10.0 // indirect - github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-logr/logr v1.2.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/swag v0.22.4 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/godbus/dbus/v5 v5.1.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang/glog v1.0.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12 // indirect - github.com/google/flatbuffers v1.12.1 // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect - github.com/google/uuid v1.3.1 // indirect - github.com/gorilla/css v1.0.0 // indirect - github.com/gorilla/mux v1.8.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-uuid v1.0.2 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/huin/goupnp v1.2.0 // indirect - github.com/hyperledger-labs/orion-sdk-go v0.2.5 // indirect - github.com/hyperledger-labs/orion-server v0.2.5 // indirect - github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.3-alpha.1 // indirect - github.com/hyperledger-labs/weaver-dlt-interoperability/sdks/fabric/go-sdk v1.2.3-alpha.1.0.20210812140206-37f430515b8c // indirect - github.com/hyperledger/fabric v1.4.0-rc1.0.20230401164317-bd8e24856939 // indirect - github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2 // indirect - github.com/hyperledger/fabric-chaincode-go v0.0.0-20220920210243-7bc6fa0dd58b // indirect - github.com/hyperledger/fabric-lib-go v1.0.0 // indirect - github.com/hyperledger/fabric-private-chaincode v0.0.0-20210907122433-d56466264e4d // indirect - github.com/hyperledger/fabric-protos-go v0.2.0 // indirect - github.com/invopop/yaml v0.2.0 // indirect - github.com/ipfs/boxo v0.8.0-rc1 // indirect - github.com/ipfs/go-cid v0.4.1 // indirect - github.com/ipfs/go-datastore v0.6.0 // indirect - github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-log v1.0.5 // indirect - github.com/ipfs/go-log/v2 v2.5.1 // indirect - github.com/ipld/go-ipld-prime v0.20.0 // indirect - github.com/iris-contrib/schema v0.0.6 // indirect - github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect - github.com/jbenet/goprocess v0.1.4 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/kataras/blocks v0.0.7 // indirect - github.com/kataras/golog v0.1.9 // indirect - github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 // indirect - github.com/kataras/pio v0.0.12 // indirect - github.com/kataras/sitemap v0.0.6 // indirect - github.com/kataras/tunnel v0.0.4 // indirect - github.com/kilic/bls12-381 v0.1.0 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect - github.com/koron/go-ssdp v0.0.4 // indirect - github.com/labstack/gommon v0.4.0 // indirect - github.com/leodido/go-urn v1.2.4 // indirect - github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p v0.31.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.22.0 // indirect - github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect - github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-msgio v0.3.0 // indirect - github.com/libp2p/go-nat v0.2.0 // indirect - github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.4.0 // indirect - github.com/libp2p/go-yamux/v4 v4.0.1 // indirect - github.com/magiconair/properties v1.8.5 // indirect - github.com/mailgun/raymond/v2 v2.0.48 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/microcosm-cc/bluemonday v1.0.25 // indirect - github.com/miekg/dns v1.1.55 // indirect - github.com/miekg/pkcs11 v1.1.1 // indirect - github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect - github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect - github.com/minio/sha256-simd v1.0.1 // indirect - github.com/mitchellh/mapstructure v1.4.3 // indirect - github.com/mmcloughlin/addchain v0.4.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/mr-tron/base58 v1.2.0 // indirect - github.com/multiformats/go-base32 v0.1.0 // indirect - github.com/multiformats/go-base36 v0.2.0 // indirect - github.com/multiformats/go-multiaddr v0.11.0 // indirect - github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect - github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect - github.com/multiformats/go-multibase v0.2.0 // indirect - github.com/multiformats/go-multicodec v0.9.0 // indirect - github.com/multiformats/go-multihash v0.2.3 // indirect - github.com/multiformats/go-multistream v0.4.1 // indirect - github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.11.0 // indirect - github.com/opencontainers/runtime-spec v1.1.0 // indirect - github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect - github.com/pelletier/go-toml v1.9.4 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect - github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.1 // indirect - github.com/quic-go/webtransport-go v0.5.3 // indirect - github.com/raulk/go-watchdog v1.3.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/schollz/closestmatch v2.1.0+incompatible // indirect - github.com/sirupsen/logrus v1.9.0 // indirect - github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/spf13/afero v1.6.0 // indirect - github.com/spf13/cast v1.4.1 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.10.1 // indirect - github.com/stretchr/testify v1.8.4 // indirect - github.com/subosito/gotenv v1.2.0 // indirect - github.com/sykesm/zap-logfmt v0.0.4 // indirect - github.com/tdewolff/minify/v2 v2.12.9 // indirect - github.com/tdewolff/parse/v2 v2.6.8 // indirect - github.com/test-go/testify v1.1.4 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.2 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect - github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - github.com/yosssi/ace v0.0.5 // indirect - go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.13.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.13.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.13.0 // indirect - go.opentelemetry.io/otel/sdk v1.13.0 // indirect - go.opentelemetry.io/otel/trace v1.14.0 // indirect - go.opentelemetry.io/proto/otlp v0.19.0 // indirect - go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.20.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.25.0 // indirect - golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.13.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.12.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.53.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.2.1 // indirect - rsc.io/tmplfunc v0.0.3 // indirect -) diff --git a/token-sdk/auditor/go.sum b/token-sdk/auditor/go.sum deleted file mode 100644 index 60388580..00000000 --- a/token-sdk/auditor/go.sum +++ /dev/null @@ -1,2020 +0,0 @@ -bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c/go.mod h1:hSVuE3qU7grINVSwrmzHfpg9k87ALBk+XaualNyUzI4= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= -cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -code.cloudfoundry.org/clock v1.0.0/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME= -github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4= -github.com/DATA-DOG/go-txdb v0.1.3/go.mod h1:DhAhxMXZpUJVGnT+p9IbzJoRKvlArO2pkHjnGX7o0n0= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= -github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= -github.com/IBM/idemix v0.0.2-0.20230831093709-b7a940638990 h1:hEZKSPmBJddcapbHqCSogIMTIzUXQhL/vTWzbngnRjw= -github.com/IBM/idemix v0.0.2-0.20230831093709-b7a940638990/go.mod h1:A9w6lDhpXujKBck1rcw6unxAzJtx+QsuT5qd1CS7BKc= -github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20230831093709-b7a940638990 h1:2h+Ou3S30pkBlkukOfprO5wGD4A13NBnyQx/gDQVzaQ= -github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20230831093709-b7a940638990/go.mod h1:sgvrLB3a8mKr4rX+aBDXPCZBgSRRmQxlyxA3jmwq/Sk= -github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20230831093709-b7a940638990 h1:crSJPccrt4hk0dqbmBUc+T1w91oTkauADD/UQvRRB10= -github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20230831093709-b7a940638990/go.mod h1:EPAfwEciT+Yke9xTooqJUcEuf2R8pmIA0QjPG6df1xM= -github.com/IBM/idemix/bccsp/types v0.0.0-20230831093709-b7a940638990 h1:UkW/eqL8hlqaGLLsY9oZsv1iwEMJOuNbAomK07C30/8= -github.com/IBM/idemix/bccsp/types v0.0.0-20230831093709-b7a940638990/go.mod h1:2lO6nmsoSH3WDJdat4kIicU+WTs4qDntGZkF8XdgHm8= -github.com/IBM/mathlib v0.0.3-0.20230831091907-c532c4d3b65c h1:QVrlfdfx7MslApfSdSLiLIOFmYlLhP6wY4LyRBVed4I= -github.com/IBM/mathlib v0.0.3-0.20230831091907-c532c4d3b65c/go.mod h1:k0NBSWMYVgaZ2keDuI8DSwdIEhUNhp8XnlVmm6Xwyuk= -github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk= -github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= -github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI= -github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= -github.com/ReneKroon/ttlcache/v2 v2.11.0 h1:OvlcYFYi941SBN3v9dsDcC2N8vRxyHcCmJb3Vl4QMoM= -github.com/ReneKroon/ttlcache/v2 v2.11.0/go.mod h1:mBxvsNY+BT8qLLd6CuAJubbKo6r0jh3nb5et22bbfGY= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 h1:KkH3I3sJuOLP3TjA/dfr4NAY8bghDwnXiU7cTKxQqo0= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/sarama v1.20.1/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/sarama v1.26.3 h1:wSN3FpDXLe3e2z47OzGii5VAK693oVkyHFwh240jWjg= -github.com/Shopify/sarama v1.26.3/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= -github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/ale-linux/aries-framework-go/component/kmscrypto v0.0.0-20230817163708-4b3de6d91874 h1:O08ZCyb1f7UeyOmTeItAw7eSZOlyM0fBnrPgaYgKEiA= -github.com/ale-linux/aries-framework-go/component/kmscrypto v0.0.0-20230817163708-4b3de6d91874/go.mod h1:4sHtFlGI84SVjaSW7u1pCfC0bjijd9ZeqbKptU/Qljs= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= -github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= -github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= -github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/badgerodon/peg v0.0.0-20130729175151-9e5f7f4d07ca/go.mod h1:TWe0N2hv5qvpLHT+K16gYcGBllld4h65dQ/5CNuirmk= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= -github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cayleygraph/cayley v0.7.7 h1:z+7xkAbg6bKiXJOtOkEG3zCm2K084sr/aGwFV7xcQNs= -github.com/cayleygraph/cayley v0.7.7/go.mod h1:VUd+PInYf94/VY41ePeFtFyP99BAs953kFT4N+6F7Ko= -github.com/cayleygraph/quad v1.1.0 h1:w1nXAmn+nz07+qlw89dke9LwWkYpeX+OcvfTvGQRBpM= -github.com/cayleygraph/quad v1.1.0/go.mod h1:maWODEekEhrO0mdc9h5n/oP7cH1h/OTgqQ2qWbuI9M4= -github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= -github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a/go.mod h1:rzgs2ZOiguV6/NpiDgADjRLPNyZlApIWxKpkT+X8SdY= -github.com/cloudflare/cfssl v1.4.1/go.mod h1:KManx/OJPb5QY+y0+o/898AMcM128sF0bURvoVUSjTo= -github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4= -github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= -github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.9.1 h1:mru55qKdWl3E035hAoh1jj9d7hVnYY5pfb6tmovSmII= -github.com/consensys/gnark-crypto v0.9.1/go.mod h1:a2DQL4+5ywF6safEeZFEPGRiiGbjzGFRUN2sg06VuU4= -github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= -github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a h1:W8b4lQ4tFF21aspRGoBuCNV6V2fFJBF+pm1J6OY8Lys= -github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cucumber/godog v0.8.0/go.mod h1:Cp3tEV1LRAyH/RuCThcxHS/+9ORZ+FMzPva2AZ5Ki+A= -github.com/cznic/mathutil v0.0.0-20170313102836-1447ad269d64/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= -github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= -github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= -github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= -github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/deepmap/oapi-codegen v1.15.0 h1:SQqViaeb4k2vMul8gx12oDOIadEtoRqTdLkxjzqtQ90= -github.com/deepmap/oapi-codegen v1.15.0/go.mod h1:a6KoHV7lMRwsPoEg2C6NDHiXYV3EQfiFocOlJ8dgJQE= -github.com/dennwc/base v1.0.0 h1:xlBzvBNRvkQ1LFI/jom7rr0vZsvYDKtvMM6lIpjFb3M= -github.com/dennwc/base v1.0.0/go.mod h1:zaTDIiAcg2oKW9XhjIaRc1kJVteCFXSSW6jwmCedUaI= -github.com/dennwc/graphql v0.0.0-20180603144102-12cfed44bc5d/go.mod h1:lg9KQn0BgRCSCGNpcGvJp/0Ljf1Yxk8TZq9HSYc43fk= -github.com/dgraph-io/badger v1.5.4/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= -github.com/dgraph-io/badger v1.5.5/go.mod h1:QgCntgIUPsjnp7cMLhUybJHb7iIoQWAHT6tF8ngCjWk= -github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= -github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= -github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= -github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-farm v0.0.0-20190416075124-e1214b5e05dc/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.1.4/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.7.3-0.20180412203414-a422774e593b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v0.7.3-0.20190309235953-33c3200e0d16/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v17.12.0-ce-rc1.0.20190628135806-70f67c6240bb+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dop251/goja v0.0.0-20190105122144-6d5bf35058fa/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= -github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/flimzy/diff v0.1.5/go.mod h1:lFJtC7SPsK0EroDmGTSrdtWKAxOk3rO+q+e04LL05Hs= -github.com/flimzy/diff v0.1.6/go.mod h1:lFJtC7SPsK0EroDmGTSrdtWKAxOk3rO+q+e04LL05Hs= -github.com/flimzy/kivik v1.8.1/go.mod h1:S2aPycbG0eDFll4wgXt9uacSNkXISPufutnc9sv+mdA= -github.com/flimzy/testy v0.1.16/go.mod h1:3szguN8NXqgq9bt9Gu8TQVj698PJWmyx/VY1frwwKrM= -github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= -github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= -github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= -github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= -github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/frankban/quicktest v1.9.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/fsouza/go-dockerclient v1.2.2/go.mod h1:KpcjM623fQYE9MZiTGzKhjfxXAV9wbyX2C1cyRHfhl0= -github.com/fsouza/go-dockerclient v1.4.1/go.mod h1:PUNHxbowDqRXfRgZqMz1OeGtbWC6VKyZvJ99hDjB0qs= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/getkin/kin-openapi v0.120.0 h1:MqJcNJFrMDFNc07iwE8iFC5eT2k/NPUFDIpNeiZv8Jg= -github.com/getkin/kin-openapi v0.120.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw= -github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-kivik/couchdb v1.8.1/go.mod h1:5XJRkAMpBlEVA4q0ktIZjUPYBjoBmRoiWvwUBzP3BOQ= -github.com/go-kivik/kivik v1.8.1/go.mod h1:nIuJ8z4ikBrVUSk3Ua8NoDqYKULPNjuddjqRvlSUyyQ= -github.com/go-kivik/kiviktest v1.1.2/go.mod h1:JdhVyzixoYhoIDUt6hRf1yAfYyaDa5/u9SDOindDkfQ= -github.com/go-kivik/pouchdb v1.3.5/go.mod h1:U+siUrqLCVxeMU3QjQTYIC3/F/e6EUKm+o5buJb7vpw= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= -github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.1 h1:OQl5ys5MBea7OGCdvPbBJWRgnhC/fGona6QKfvFeau8= -github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= -github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/logger v1.0.7 h1:LTLwWelETXDYyqF/ASf0nxaIcdEOIJNxRokPcfI/xbU= -github.com/gobuffalo/logger v1.0.7/go.mod h1:u40u6Bq3VVvaMcy5sRBclD8SXhBYPS0Qk95ubt+1xJM= -github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= -github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= -github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= -github.com/gobuffalo/packr/v2 v2.7.1 h1:n3CIW5T17T8v4GGK5sWXLVWJhCz7b5aNLSxW6gYim4o= -github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12 h1:uK3X/2mt4tbSGoHvbLBHUny7CKiuwUip3MArtukol4E= -github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= -github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/jsbuiltin v0.0.0-20180426082241-50091555e127/go.mod h1:7X1acUyFRf+oVFTU6SWw9mnb57Vxn+Nbh8iPbKg95hs= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= -github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= -github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.4.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= -github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4= -github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hidal-go/hidalgo v0.0.0-20190814174001-42e03f3b5eaa/go.mod h1:bPkrxDlroXxigw8BMWTEPTv4W5/rQwNgg2BECXsgyX0= -github.com/hidal-go/hidalgo v0.0.0-20201109092204-05749a6d73df h1:bvz3e467dv98bVHQ9F5QbGKtGvyQO3rPD8lwu6fZ/D4= -github.com/hidal-go/hidalgo v0.0.0-20201109092204-05749a6d73df/go.mod h1:bPkrxDlroXxigw8BMWTEPTv4W5/rQwNgg2BECXsgyX0= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/hyperledger-labs/fabric-smart-client v0.3.0 h1:CNSFdHfhlvAjD4OrOojvtsZBEN50sl6uSl3qXZhzX+o= -github.com/hyperledger-labs/fabric-smart-client v0.3.0/go.mod h1:ZmxAL+oOP3B/HEu+z9a69+PwfWKfUiMsSBpwdPwlh2g= -github.com/hyperledger-labs/fabric-token-sdk v0.3.0 h1:YE1NMmf1o8oEb4j3XI3CrtAd+bpHJdTY3rY1RqfYR28= -github.com/hyperledger-labs/fabric-token-sdk v0.3.0/go.mod h1:NcyBbgCtVohGdui/yMDirJ9tk0EolWD0WVLSk5a1A7I= -github.com/hyperledger-labs/orion-sdk-go v0.2.5 h1:HFGRTuMZgzo9EtyJeFAhVSlbrj6x3jtY0aDcghdjzRE= -github.com/hyperledger-labs/orion-sdk-go v0.2.5/go.mod h1:At8hiFATfkDXQ4AFLVbaTiC9GDhVDo8aN/supb1KBb4= -github.com/hyperledger-labs/orion-server v0.2.5 h1:aFudmB9SAnsT5v8jhazkuszEu0pdJNFqaYZF2GpvAuI= -github.com/hyperledger-labs/orion-server v0.2.5/go.mod h1:8kXVAU1wvFYGbFL1qmXwMi2i8gKV2smOdp1F1kq0HMk= -github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.3-alpha.1 h1:vBvo0PNm82ht7wpBjlYY4ZHxV3YprCfdVd3T4JG9vBw= -github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.3-alpha.1/go.mod h1:POCGO/RK9YDfgdhuyqjoD9tRNtWfK7Rh5AYYmsb1Chc= -github.com/hyperledger-labs/weaver-dlt-interoperability/sdks/fabric/go-sdk v1.2.3-alpha.1.0.20210812140206-37f430515b8c h1:pKr8VnHlduEgdInwLWykYAw+lpUizjQJaJ8I5fVoRUo= -github.com/hyperledger-labs/weaver-dlt-interoperability/sdks/fabric/go-sdk v1.2.3-alpha.1.0.20210812140206-37f430515b8c/go.mod h1:si2XAWZclHXC359OyYMpNHfonf2P7P2nzABdCA8mPqs= -github.com/hyperledger/fabric v1.4.0-rc1.0.20201118191903-ec81f3e74fa1/go.mod h1:ppiyrJ+sUSk/rAX9cTd8xwAwSQ7chEbOQMAqtQ3pLG4= -github.com/hyperledger/fabric v1.4.0-rc1.0.20230401164317-bd8e24856939 h1:+XwAnpbvmxEeRD1yT+gd77643Y1QQUv0B2HUr4CRNWE= -github.com/hyperledger/fabric v1.4.0-rc1.0.20230401164317-bd8e24856939/go.mod h1:H7BI2gsTl4fW9ARtYG7UOGjwecXHSReVaIz4p2xqUB8= -github.com/hyperledger/fabric-amcl v0.0.0-20200128223036-d1aa2665426a/go.mod h1:X+DIyUsaTmalOpmpQfIvFZjKHQedrURQ5t4YqquX7lE= -github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2 h1:B1Nt8hKb//KvgGRprk0h1t4lCnwhE9/ryb1WqfZbV+M= -github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2/go.mod h1:X+DIyUsaTmalOpmpQfIvFZjKHQedrURQ5t4YqquX7lE= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20190823162523-04390e015b85/go.mod h1:HZK6PKLWrvdD/t0oSLiyaRaUM6fZ7qjJuOlb0zrn0mo= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20200128192331-2d899240a7ed/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20201119163726-f8ef75b17719/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20220920210243-7bc6fa0dd58b h1:MGT5rdajc4zbsbU7yMzkLJmsiRwJk5gBX5OdpU117Bg= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20220920210243-7bc6fa0dd58b/go.mod h1:OxME3M0bbgoWYHpXIVMzpbXgFqrTZnFmlH0Cpml54m0= -github.com/hyperledger/fabric-config v0.0.5/go.mod h1:YpITBI/+ZayA3XWY5lF302K7PAsFYjEEPM/zr3hegA8= -github.com/hyperledger/fabric-config v0.0.7/go.mod h1:aeDZ0moG/qKvwLjddcqYr8+58/oNaJy3HE0tI01546c= -github.com/hyperledger/fabric-config v0.1.0 h1:TsR3y5xEoUmXWfp8tcDycjJhVvXEHiV5kfZIxuIte08= -github.com/hyperledger/fabric-config v0.1.0/go.mod h1:aeDZ0moG/qKvwLjddcqYr8+58/oNaJy3HE0tI01546c= -github.com/hyperledger/fabric-contract-api-go v1.1.1/go.mod h1:+39cWxbh5py3NtXpRA63rAH7NzXyED+QJx1EZr0tJPo= -github.com/hyperledger/fabric-lib-go v1.0.0 h1:UL1w7c9LvHZUSkIvHTDGklxFv2kTeva1QI2emOVc324= -github.com/hyperledger/fabric-lib-go v1.0.0/go.mod h1:H362nMlunurmHwkYqR5uHL2UDWbQdbfz74n8kbCFsqc= -github.com/hyperledger/fabric-private-chaincode v0.0.0-20210907122433-d56466264e4d h1:LR34x2vhXUuXsETE9HBhz+eZM6nTuzPiWsF5jnNI550= -github.com/hyperledger/fabric-private-chaincode v0.0.0-20210907122433-d56466264e4d/go.mod h1:CBeWypXEi4LndnexZzEEqVIIqjdrUzUUHmmFcEcGRX4= -github.com/hyperledger/fabric-protos-go v0.0.0-20190821214336-621b908d5022/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20190919234611-2a87503ac7c9/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20200707132912-fee30f3ccd23/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20201028172056-a3136dde2354/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.2.0 h1:opaGKvsYYD0abMl6ErriNc+CEgLW+ELdKKQ0QyBL7/0= -github.com/hyperledger/fabric-protos-go v0.2.0/go.mod h1:WWnyWP40P2roPmmvxsUXSvVI/CF6vwY1K1UFidnKBys= -github.com/hyperledger/fabric-samples/chaincode/marbles02/go v0.0.0-20210428060230-9db8164f049b/go.mod h1:MvJbTLiLI/KBavKkC+OAqYU1IGvbY8WOu+Qzs/jncnA= -github.com/hyperledger/fabric-sdk-go v1.0.0/go.mod h1:qWE9Syfg1KbwNjtILk70bJLilnmCvllIYFCSY/pa1RU= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd/go.mod h1:3LVOLeyx9XVvwPgrt2be44XgSqndprz1G18rSk8KD84= -github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY= -github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= -github.com/ipfs/boxo v0.8.0-rc1 h1:DL5SDbBNSS9ZNsF+UhoQ39d05/wgoJ2k/T+y7JeWRaw= -github.com/ipfs/boxo v0.8.0-rc1/go.mod h1:EgDiNox/+W/+ySwEotRrHlvdmrhbSAB4p22ELg+ZsCc= -github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= -github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= -github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= -github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= -github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= -github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= -github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= -github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= -github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= -github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= -github.com/iris-contrib/httpexpect/v2 v2.15.2 h1:T9THsdP1woyAqKHwjkEsbCnMefsAFvk8iJJKokcJ3Go= -github.com/iris-contrib/httpexpect/v2 v2.15.2/go.mod h1:JLDgIqnFy5loDSUv1OA2j0mb6p/rDhiCqigP22Uq9xE= -github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw= -github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= -github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= -github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= -github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= -github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= -github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= -github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= -github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= -github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548/go.mod h1:hGT6jSUVzF6no3QaDSMLGLEHtHSBSefs+MgcDWnmhmo= -github.com/jmoiron/sqlx v0.0.0-20180124204410-05cef0741ade/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU= -github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/kataras/blocks v0.0.7 h1:cF3RDY/vxnSRezc7vLFlQFTYXG/yAr1o7WImJuZbzC4= -github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= -github.com/kataras/golog v0.1.9 h1:vLvSDpP7kihFGKFAvBSofYo7qZNULYSHOH2D7rPTKJk= -github.com/kataras/golog v0.1.9/go.mod h1:jlpk/bOaYCyqDqH18pgDHdaJab72yBE6i0O3s30hpWY= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 h1:Vx8kDVhO2qepK8w44lBtp+RzN3ld743i+LYPzODJSpQ= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9/go.mod h1:ldkoR3iXABBeqlTibQ3MYaviA1oSlPvim6f55biwBh4= -github.com/kataras/pio v0.0.12 h1:o52SfVYauS3J5X08fNjlGS5arXHjW/ItLkyLcKjoH6w= -github.com/kataras/pio v0.0.12/go.mod h1:ODK/8XBhhQ5WqrAhKy+9lTPS7sBf6O3KcLhc9klfRcY= -github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= -github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= -github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= -github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= -github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= -github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= -github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= -github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.0.0/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28/go.mod h1:T/T7jsxVqf9k/zYOqbgNAsANsjxTd1Yq3htjDhQ1H0c= -github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4= -github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ= -github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lib/pq v0.0.0-20180201184707-88edab080323/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= -github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= -github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= -github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= -github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= -github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= -github.com/libp2p/go-libp2p-kad-dht v0.22.0 h1:cW2nGgG0hztDM42tOPyC5cVflD7EzLaHM0/Kjol6Wio= -github.com/libp2p/go-libp2p-kad-dht v0.22.0/go.mod h1:hareSo3Z/GJ7nUWPMj7XhD/56a7+rRltYCWwCuy3FQk= -github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= -github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= -github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= -github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= -github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= -github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= -github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= -github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= -github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= -github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= -github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= -github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= -github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/linkeddata/gojsonld v0.0.0-20170418210642-4f5db6791326/go.mod h1:nfqkuSNlsk1bvti/oa7TThx4KmRMBmSxf3okHI9wp3E= -github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw= -github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= -github.com/mailru/easyjson v0.0.0-20180730094502-03f2033d19d5/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= -github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/matttproud/golang_protobuf_extensions v1.0.0/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/maxbrunsfeld/counterfeiter/v6 v6.3.0/go.mod h1:fcEyUyXZXoV4Abw8DX0t7wyL8mCDxXyU4iAFZfT3IHw= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= -github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= -github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= -github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= -github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= -github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= -github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= -github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= -github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= -github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= -github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= -github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= -github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= -github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= -github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= -github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= -github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= -github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= -github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= -github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= -github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= -github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= -github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= -github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= -github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= -github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= -github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= -github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= -github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= -github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= -github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= -github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= -github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= -github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= -github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= -github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= -github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc8/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= -github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.0.0/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= -github.com/otiai10/copy v1.5.1 h1:a/cs2E1/1V0az8K5nblbl+ymEa4E11AfaOLMar8V34w= -github.com/otiai10/copy v1.5.1/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= -github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= -github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= -github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/peterh/liner v0.0.0-20170317030525-88609521dc4b/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.5.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.6.0+incompatible h1:Ix9yFKn1nSPBLFl/yZknTp8TU5G4Ps0JDmguYK6iH1A= -github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= -github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.0.0-20180518154759-7600349dcfe1/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= -github.com/prometheus/procfs v0.0.0-20180612222113-7d6f385de8be/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= -github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= -github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= -github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= -github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= -github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= -github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= -github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= -github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= -github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.3.1/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.1.1/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= -github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk= -github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU= -github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/sykesm/zap-logfmt v0.0.2/go.mod h1:TerDJT124HaO8UTpZ2wJCipJRAKQ9XONM1mzUabIh6M= -github.com/sykesm/zap-logfmt v0.0.4 h1:U2WzRvmIWG1wDLCFY3sz8UeEmsdHQjHFNlIdmroVFaI= -github.com/sykesm/zap-logfmt v0.0.4/go.mod h1:AuBd9xQjAe3URrWT1BBDk2v2onAZHkZkWRMiYZXiZWA= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/syndtr/goleveldb v1.0.1-0.20190625010220-02440ea7a285/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/tdewolff/minify/v2 v2.12.9 h1:dvn5MtmuQ/DFMwqf5j8QhEVpPX6fi3WGImhv8RUB4zA= -github.com/tdewolff/minify/v2 v2.12.9/go.mod h1:qOqdlDfL+7v0/fyymB+OP497nIxJYSvX4MQWA8OoiXU= -github.com/tdewolff/parse/v2 v2.6.8 h1:mhNZXYCx//xG7Yq2e/kVLNZw4YfYmeHbhx+Zc0OvFMA= -github.com/tdewolff/parse/v2 v2.6.8/go.mod h1:XHDhaU6IBgsryfdnpzUXBlT6leW/l25yrFBTEb4eIyM= -github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0= -github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= -github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0= -github.com/tedsuo/ifrit v0.0.0-20220120221754-dd274de71113 h1:PnxSSxsUvOqMh7nslHscii/GV/Y9ZflmkZ2oEEEIGj4= -github.com/tedsuo/ifrit v0.0.0-20220120221754-dd274de71113/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0= -github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= -github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/tylertreat/BoomFilters v0.0.0-20181028192813-611b3dbe80e8 h1:7X4KYG3guI2mPQGxm/ZNNsiu4BjKnef0KG0TblMC+Z8= -github.com/tylertreat/BoomFilters v0.0.0-20181028192813-611b3dbe80e8/go.mod h1:OYRfF6eb5wY9VRFkXJH8FFBi3plw2v+giaIu7P054pM= -github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/urfave/cli v1.18.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= -github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= -github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= -github.com/weppos/publicsuffix-go v0.5.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA= -github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= -github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= -github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= -github.com/zmap/zcrypto v0.0.0-20190729165852-9051775e6a2e/go.mod h1:w7kd3qXHh8FNaczNjslXqvFQiv5mMWRXlL9klTUAHc8= -github.com/zmap/zlint v0.0.0-20190806154020-fd021b4cfbeb/go.mod h1:29UiAJNsiVdvTBFCJW8e3q6dcDbOoPkhMgttOSCIMMY= -go.etcd.io/bbolt v1.3.1-etcd.7/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd v0.5.0-alpha.5.0.20181228115726-23731bf9ba55/go.mod h1:weASp41xM3dk0YHg1s/W8ecdGP5G4teSTMBPpYAaUgA= -go.etcd.io/etcd v0.5.0-alpha.5.0.20210226220824-aa7126864d82 h1:RCaUKN0yRYKT2JzV9kH4u+D6l9VWcJMQ449QKRriFc8= -go.etcd.io/etcd v0.5.0-alpha.5.0.20210226220824-aa7126864d82/go.mod h1:WWRiAtnzDdtuCMxtFwME/Knea11a6fJgJkwtC1QSc/k= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= -go.mongodb.org/mongo-driver v1.0.4/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= -go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.13.0 h1:pa05sNT/P8OsIQ8mPZKTIyiBuzS/xDGLVx+DCt0y6Vs= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.13.0/go.mod h1:rqbht/LlhVBgn5+k3M5QK96K5Xb0DvXpMJ5SFQpY6uw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.13.0 h1:Any/nVxaoMq1T2w0W85d6w5COlLuCCgOYKQhJJWEMwQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.13.0/go.mod h1:46vAP6RWfNn7EKov73l5KBFlNxz8kYlxR1woU+bJ4ZY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.13.0 h1:Ntu7izEOIRHEgQNjbGc7j3eNtYMAiZfElJJ4JiiRDH4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.13.0/go.mod h1:wZ9SAjm2sjw3vStBhlCfMZWZusyOQrwrHOFo00jyMC4= -go.opentelemetry.io/otel/sdk v1.13.0 h1:BHib5g8MvdqS65yo2vV1s6Le42Hm6rrw08qU6yz5JaM= -go.opentelemetry.io/otel/sdk v1.13.0/go.mod h1:YLKPx5+6Vx/o1TCUYYs+bpymtkmazOMT6zoRrC7AQ7I= -go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= -go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= -go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= -go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.12.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= -golang.org/x/crypto v0.0.0-20180608092829-8ac0e0d97ce4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201026091529-146b70c837a4/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190614160838-b47fdc937951/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191009170203-06d7bd2c5f4f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200819091447-39769834ee22/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200131233409-575de47986ce/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180608181217-32ee49c4dd80/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= -gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg= -gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= -gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= -gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= -gopkg.in/olivere/elastic.v5 v5.0.80/go.mod h1:uhHoB4o3bvX5sorxBU29rPcmBQdV2Qfg0FBrx5D6pV0= -gopkg.in/olivere/elastic.v5 v5.0.81/go.mod h1:uhHoB4o3bvX5sorxBU29rPcmBQdV2Qfg0FBrx5D6pV0= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= -lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs= -moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= -rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/token-sdk/auditor/main.go b/token-sdk/auditor/main.go deleted file mode 100644 index 5289f58b..00000000 --- a/token-sdk/auditor/main.go +++ /dev/null @@ -1,114 +0,0 @@ -package main - -import ( - "net/http" - "os" - "os/signal" - "syscall" - - "github.com/hyperledger/fabric-samples/token-sdk/auditor/routes" - "github.com/hyperledger/fabric-samples/token-sdk/auditor/service" - - "github.com/hyperledger-labs/fabric-smart-client/pkg/api" - "github.com/hyperledger-labs/fabric-smart-client/pkg/node" - fabric "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/sdk" - viewregistry "github.com/hyperledger-labs/fabric-smart-client/platform/view" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/flogging" - tokensdk "github.com/hyperledger-labs/fabric-token-sdk/token/sdk" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx" -) - -var logger = flogging.MustGetLogger("main") - -func main() { - dir := getEnv("CONF_DIR", "./conf") - port := getEnv("PORT", "9000") - - fsc := startFabricSmartClient(dir) - // Tell the service how to respond to other nodes when they initiate an action - registry := viewregistry.GetRegistry(fsc) - succeedOrPanic(registry.RegisterResponder(&service.AuditView{}, &ttx.AuditingViewInitiator{})) - - controller := routes.Controller{Service: service.TokenService{FSC: fsc}} - err := routes.StartWebServer(port, controller, logger) - if err != nil { - if err == http.ErrServerClosed { - logger.Infof("Webserver closing, exiting...", err.Error()) - fsc.Stop() - } else { - logger.Fatalf("echo error - %s", err.Error()) - fsc.Stop() - os.Exit(1) - } - } -} - -type Node interface { - api.ServiceProvider - Stop() -} - -func startFabricSmartClient(confDir string) Node { - logger.Infof("Initializing Fabric Smart Client and Token SDK...") - fsc := node.NewFromConfPath(confDir) - succeedOrPanic(fsc.InstallSDK(fabric.NewSDK(fsc))) - succeedOrPanic(fsc.InstallSDK(tokensdk.NewSDK(fsc))) - succeedOrPanic(fsc.Start()) - - // Stop gracefully - go handleSignals((map[os.Signal]func(){ - syscall.SIGINT: func() { - logger.Info("Stopping FSC node...") - fsc.Stop() - os.Exit(130) - }, - syscall.SIGTERM: func() { - logger.Info("Stopping FSC node...") - fsc.Stop() - os.Exit(143) - }, - syscall.SIGSTOP: func() { - logger.Info("Stopping FSC node...") - fsc.Stop() - os.Exit(145) - }, - syscall.SIGHUP: func() { - logger.Info("Stopping FSC node...") - fsc.Stop() - os.Exit(129) - }, - })) - logger.Infof("FSC node is ready!") - - return fsc -} - -// getEnv returns an environment variable or the fallback -func getEnv(key, fallback string) string { - if value, ok := os.LookupEnv(key); ok { - return value - } - return fallback -} - -func succeedOrPanic(err error) { - if err != nil { - logger.Fatalf("Failed initializing Token SDK - %s", err.Error()) - os.Exit(1) - } -} - -func handleSignals(handlers map[os.Signal]func()) { - var signals []os.Signal - for sig := range handlers { - signals = append(signals, sig) - } - - signalChan := make(chan os.Signal, 1) - signal.Notify(signalChan, signals...) - - for sig := range signalChan { - logger.Infof("Received signal: %d (%s)", sig, sig) - handlers[sig]() - } -} diff --git a/token-sdk/auditor/oapi-server.yaml b/token-sdk/auditor/oapi-server.yaml deleted file mode 100644 index e4eb0d35..00000000 --- a/token-sdk/auditor/oapi-server.yaml +++ /dev/null @@ -1,11 +0,0 @@ -package: routes -generate: - echo-server: true - strict-server: true - models: true - embedded-spec: true -output-options: - include-tags: - - operations - - auditor -output: auditor/routes/routes.gen.go diff --git a/token-sdk/auditor/routes/operations.go b/token-sdk/auditor/routes/operations.go deleted file mode 100644 index 04930b74..00000000 --- a/token-sdk/auditor/routes/operations.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package routes - -import ( - "context" -) - -// (GET /readyz) -func (c Controller) Readyz(ctx context.Context, request ReadyzRequestObject) (ReadyzResponseObject, error) { - // TODO: what defines readiness if the REST API is available after FSC? - return Readyz200JSONResponse{ - HealthSuccessJSONResponse: HealthSuccessJSONResponse{ - Message: "ok", - }, - }, nil -} - -// (GET /healthz) -func (c Controller) Healthz(ctx context.Context, request HealthzRequestObject) (HealthzResponseObject, error) { - // TODO: how to determine health? - return Healthz200JSONResponse{ - HealthSuccessJSONResponse: HealthSuccessJSONResponse{ - Message: "ok", - }, - }, nil -} diff --git a/token-sdk/auditor/routes/routes.gen.go b/token-sdk/auditor/routes/routes.gen.go deleted file mode 100644 index 59067555..00000000 --- a/token-sdk/auditor/routes/routes.gen.go +++ /dev/null @@ -1,579 +0,0 @@ -// Package auditor provides primitives to interact with the openapi HTTP API. -// -// Code generated by github.com/deepmap/oapi-codegen version v1.13.4 DO NOT EDIT. -package routes - -import ( - "bytes" - "compress/gzip" - "context" - "encoding/base64" - "encoding/json" - "fmt" - "net/http" - "net/url" - "path" - "strings" - "time" - - "github.com/deepmap/oapi-codegen/pkg/runtime" - "github.com/getkin/kin-openapi/openapi3" - "github.com/labstack/echo/v4" -) - -// Account Information about an account and its balance -type Account struct { - // Balance balance in base units for each currency - Balance []Amount `json:"balance"` - - // Id account id as registered at the Certificate Authority - Id string `json:"id"` -} - -// Amount The amount to issue, transfer or redeem. -type Amount struct { - // Code the code of the token - Code string `json:"code"` - - // Value value in base units (usually cents) - Value int64 `json:"value"` -} - -// Error defines model for Error. -type Error struct { - // Message High level error message - Message string `json:"message"` - - // Payload Details about the error - Payload string `json:"payload"` -} - -// TransactionRecord A transaction -type TransactionRecord struct { - // Amount The amount to issue, transfer or redeem. - Amount Amount `json:"amount"` - - // Id transaction id - Id string `json:"id"` - - // Message user provided message - Message string `json:"message"` - - // Recipient the recipient of the transaction - Recipient string `json:"recipient"` - - // Sender the sender of the transaction - Sender string `json:"sender"` - - // Status Unknown | Pending | Confirmed | Deleted - Status string `json:"status"` - - // Timestamp timestamp in the format: "2018-03-20T09:12:28Z" - Timestamp time.Time `json:"timestamp"` -} - -// Code The token code to filter on -type Code = string - -// Id account id as registered at the Certificate Authority -type Id = string - -// AccountSuccess defines model for AccountSuccess. -type AccountSuccess struct { - Message string `json:"message"` - - // Payload Information about an account and its balance - Payload Account `json:"payload"` -} - -// ErrorResponse defines model for ErrorResponse. -type ErrorResponse = Error - -// HealthSuccess defines model for HealthSuccess. -type HealthSuccess struct { - // Message ok - Message string `json:"message"` -} - -// TransactionsSuccess defines model for TransactionsSuccess. -type TransactionsSuccess struct { - Message string `json:"message"` - Payload []TransactionRecord `json:"payload"` -} - -// AuditorAccountParams defines parameters for AuditorAccount. -type AuditorAccountParams struct { - Code *Code `form:"code,omitempty" json:"code,omitempty"` -} - -// ServerInterface represents all server handlers. -type ServerInterface interface { - // Get an account and their balance of a certain type - // (GET /auditor/accounts/{id}) - AuditorAccount(ctx echo.Context, id Id, params AuditorAccountParams) error - // Get all transactions for an account - // (GET /auditor/accounts/{id}/transactions) - AuditorTransactions(ctx echo.Context, id Id) error - - // (GET /healthz) - Healthz(ctx echo.Context) error - - // (GET /readyz) - Readyz(ctx echo.Context) error -} - -// ServerInterfaceWrapper converts echo contexts to parameters. -type ServerInterfaceWrapper struct { - Handler ServerInterface -} - -// AuditorAccount converts echo context to params. -func (w *ServerInterfaceWrapper) AuditorAccount(ctx echo.Context) error { - var err error - // ------------- Path parameter "id" ------------- - var id Id - - err = runtime.BindStyledParameterWithLocation("simple", false, "id", runtime.ParamLocationPath, ctx.Param("id"), &id) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) - } - - // Parameter object where we will unmarshal all parameters from the context - var params AuditorAccountParams - // ------------- Optional query parameter "code" ------------- - - err = runtime.BindQueryParameter("form", true, false, "code", ctx.QueryParams(), ¶ms.Code) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter code: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.AuditorAccount(ctx, id, params) - return err -} - -// AuditorTransactions converts echo context to params. -func (w *ServerInterfaceWrapper) AuditorTransactions(ctx echo.Context) error { - var err error - // ------------- Path parameter "id" ------------- - var id Id - - err = runtime.BindStyledParameterWithLocation("simple", false, "id", runtime.ParamLocationPath, ctx.Param("id"), &id) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.AuditorTransactions(ctx, id) - return err -} - -// Healthz converts echo context to params. -func (w *ServerInterfaceWrapper) Healthz(ctx echo.Context) error { - var err error - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.Healthz(ctx) - return err -} - -// Readyz converts echo context to params. -func (w *ServerInterfaceWrapper) Readyz(ctx echo.Context) error { - var err error - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.Readyz(ctx) - return err -} - -// This is a simple interface which specifies echo.Route addition functions which -// are present on both echo.Echo and echo.Group, since we want to allow using -// either of them for path registration -type EchoRouter interface { - CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route -} - -// RegisterHandlers adds each server route to the EchoRouter. -func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") -} - -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. -func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { - - wrapper := ServerInterfaceWrapper{ - Handler: si, - } - - router.GET(baseURL+"/auditor/accounts/:id", wrapper.AuditorAccount) - router.GET(baseURL+"/auditor/accounts/:id/transactions", wrapper.AuditorTransactions) - router.GET(baseURL+"/healthz", wrapper.Healthz) - router.GET(baseURL+"/readyz", wrapper.Readyz) - -} - -type AccountSuccessJSONResponse struct { - Message string `json:"message"` - - // Payload Information about an account and its balance - Payload Account `json:"payload"` -} - -type ErrorResponseJSONResponse Error - -type HealthSuccessJSONResponse struct { - // Message ok - Message string `json:"message"` -} - -type TransactionsSuccessJSONResponse struct { - Message string `json:"message"` - Payload []TransactionRecord `json:"payload"` -} - -type AuditorAccountRequestObject struct { - Id Id `json:"id"` - Params AuditorAccountParams -} - -type AuditorAccountResponseObject interface { - VisitAuditorAccountResponse(w http.ResponseWriter) error -} - -type AuditorAccount200JSONResponse struct{ AccountSuccessJSONResponse } - -func (response AuditorAccount200JSONResponse) VisitAuditorAccountResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type AuditorAccountdefaultJSONResponse struct { - Body Error - StatusCode int -} - -func (response AuditorAccountdefaultJSONResponse) VisitAuditorAccountResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) -} - -type AuditorTransactionsRequestObject struct { - Id Id `json:"id"` -} - -type AuditorTransactionsResponseObject interface { - VisitAuditorTransactionsResponse(w http.ResponseWriter) error -} - -type AuditorTransactions200JSONResponse struct { - TransactionsSuccessJSONResponse -} - -func (response AuditorTransactions200JSONResponse) VisitAuditorTransactionsResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type AuditorTransactionsdefaultJSONResponse struct { - Body Error - StatusCode int -} - -func (response AuditorTransactionsdefaultJSONResponse) VisitAuditorTransactionsResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) -} - -type HealthzRequestObject struct { -} - -type HealthzResponseObject interface { - VisitHealthzResponse(w http.ResponseWriter) error -} - -type Healthz200JSONResponse struct{ HealthSuccessJSONResponse } - -func (response Healthz200JSONResponse) VisitHealthzResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type Healthz503JSONResponse struct{ ErrorResponseJSONResponse } - -func (response Healthz503JSONResponse) VisitHealthzResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(503) - - return json.NewEncoder(w).Encode(response) -} - -type ReadyzRequestObject struct { -} - -type ReadyzResponseObject interface { - VisitReadyzResponse(w http.ResponseWriter) error -} - -type Readyz200JSONResponse struct{ HealthSuccessJSONResponse } - -func (response Readyz200JSONResponse) VisitReadyzResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type Readyz503JSONResponse struct{ ErrorResponseJSONResponse } - -func (response Readyz503JSONResponse) VisitReadyzResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(503) - - return json.NewEncoder(w).Encode(response) -} - -// StrictServerInterface represents all server handlers. -type StrictServerInterface interface { - // Get an account and their balance of a certain type - // (GET /auditor/accounts/{id}) - AuditorAccount(ctx context.Context, request AuditorAccountRequestObject) (AuditorAccountResponseObject, error) - // Get all transactions for an account - // (GET /auditor/accounts/{id}/transactions) - AuditorTransactions(ctx context.Context, request AuditorTransactionsRequestObject) (AuditorTransactionsResponseObject, error) - - // (GET /healthz) - Healthz(ctx context.Context, request HealthzRequestObject) (HealthzResponseObject, error) - - // (GET /readyz) - Readyz(ctx context.Context, request ReadyzRequestObject) (ReadyzResponseObject, error) -} - -type StrictHandlerFunc = runtime.StrictEchoHandlerFunc -type StrictMiddlewareFunc = runtime.StrictEchoMiddlewareFunc - -func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { - return &strictHandler{ssi: ssi, middlewares: middlewares} -} - -type strictHandler struct { - ssi StrictServerInterface - middlewares []StrictMiddlewareFunc -} - -// AuditorAccount operation middleware -func (sh *strictHandler) AuditorAccount(ctx echo.Context, id Id, params AuditorAccountParams) error { - var request AuditorAccountRequestObject - - request.Id = id - request.Params = params - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.AuditorAccount(ctx.Request().Context(), request.(AuditorAccountRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "AuditorAccount") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(AuditorAccountResponseObject); ok { - return validResponse.VisitAuditorAccountResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// AuditorTransactions operation middleware -func (sh *strictHandler) AuditorTransactions(ctx echo.Context, id Id) error { - var request AuditorTransactionsRequestObject - - request.Id = id - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.AuditorTransactions(ctx.Request().Context(), request.(AuditorTransactionsRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "AuditorTransactions") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(AuditorTransactionsResponseObject); ok { - return validResponse.VisitAuditorTransactionsResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// Healthz operation middleware -func (sh *strictHandler) Healthz(ctx echo.Context) error { - var request HealthzRequestObject - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.Healthz(ctx.Request().Context(), request.(HealthzRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "Healthz") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(HealthzResponseObject); ok { - return validResponse.VisitHealthzResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// Readyz operation middleware -func (sh *strictHandler) Readyz(ctx echo.Context) error { - var request ReadyzRequestObject - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.Readyz(ctx.Request().Context(), request.(ReadyzRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "Readyz") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(ReadyzResponseObject); ok { - return validResponse.VisitReadyzResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// Base64 encoded, gzipped, json marshaled Swagger object -var swaggerSpec = []string{ - - "H4sIAAAAAAAC/9RZUW/bNhD+KwduDy2gRrKzDa3esrZYi70UaQoMbfNwls4WG4pUScqZl/q/DyQlWbJk", - "J826onlKJFLH7767++4I37BMlZWSJK1h6Q2rUGNJlrR/ylRO7i+XLGWfa9IbFjGJJbE0rEXMZAWV6Dbl", - "ZDLNK8uV231REFh1RRLcRrAKllxY0qAkixj9jWUlnJmX787/YhGzm8o9Gau5XLHtNmI8706u0Ba7g3nO", - "Iqbpc8015Sy1uqbDMDDLVC0t8BzQgKYVN5Y05YAWbEHwnLTlS56hJTirbaE0t5sBQBQ8owmEWwfCVEoa", - "8lydhZPe1llGpmFPWpLW/YtVJdwhXMn4k3HIbnqQK60qhyMYKskYXHne986MWIUbodAz87OmJUvZT/Eu", - "gHEwaeIGCwsgW6Y+dKZ3hi47x9TiE2U2ODbksHEJWncdkJdaK33evvgaZ4/h9lanIPiFAYBXhMIW92G7", - "C22PaqauPL2HAjFEo64mM3aK6fvye6FRGszcDvNNU2qX2LZ3BGiymtOa8rFng6zjlkpzWxh74M8pUzp3", - "RhqrqDVu/rfE3LZK0C/JcQBfy6XSpecOcKFqCyihlQqUOXBrYIECpS/9Xsa0L9MPrTq2CrZGURNLZ0mS", - "JNuoW3339kVvdZ4k28ugbY2wjLKuO2EfdLMAXMICDUEtHcql0kCYFZDVWpPMnHjdKUhnZZCI/ci0yvu9", - "dHSYCF7cWwrGORCxBvZkv0G/5noNN6amCHyKL13TceKRE5Unw3AeCuEoKm0nzGmJtbC7b4YoHBW+36ml", - "p8V3wKmSao7a98K/3ovwo9rUKMQGMhe/xyxiIXldK5T2t19YxEoueVmXLE26o7i0tCI9Irhp2+H8KYKD", - "Bh/SSfJCPC7XlH2Ffr7iqwIErUnAvr1j2jM08oIscmGa+nVke1t3VuZjUjPQ30bCRgDOoKegw7TCLkmP", - "JJgrs9n8NOqx6webjFfcazxbqIWbsEjmpHsVZCza2rCUPVdyyXUZRJuXZCyWFUvZPJk9fZKcPpknF8mz", - "dDZP50/fj8OzA3k3mZiShR4DwCd7x8EkqA1pqLRa85zyYxnQY+Rmoty65a7mBlEZmWvpnLIV1u5qqAnD", - "vqF38kqqawlf4A3JnMsVfIEuUvAFXpAgO91oe0EcwWuXnDo4dEEEUvg4Ge6PrK8TOVp64izcTX8bivrU", - "R2269EF2HES3zDtcLtVEFw4iXSiR96Tatd+g1UE9zQn8jtkV5bDYAELOHfJFbSkHQfmKdPRRVpoM6bXj", - "utJ8jdkGauOe3pNW8KdU134rvNFKLc2Jd8L6rnThj3ClSdoEWLOTxMVCVSSx4ixlpyfJyanXC1v4eMdY", - "59wqHTdd0cQ3PN+6lRX5LHVl5qeL104Zz8LudhqJBpesD9Plt9sSczc+3brLC42bLQaXknmSHCrwbl+8", - "d3PxY1bT5W77dHgN8OMX6XXr2N4IEWhgEau1YCkrrK3SOBYqQ1EoY9NnSZLEWPF4PYu9K6YuS9QblrI/", - "aDSi2YK4boc0V7IIGWmLrjxcBkbM4srh6A6+/KbwttGBPIj7g/VtSdGf8++VGfeK+NTt4ocNuxAwuKq4", - "iXeXC98lzoW/bP5zMJivmvX7xGJ4kd1G7Nfk9D4RaFnokJlAREfmOdlaSwPzJAEeOpwXTXelMBBc9PN/", - "7KdnHf74a+VBMsPOI1zODsbWq38j8W5k74XUYVDXknaFdRyFH4y8KISJ6RCYeR9MtG8lQy2U8WZylEfM", - "nI7yYwi26wYPC3Ecuu4PDHyYzX5EeLSotXzcpBE75Nm+Ij+wwLSz0QMJzUU7yvWLW9nCDXe9CteE+eaw", - "pp6H5Qcsqd5B732WUWUhQyHMt+2W0X8T5OgHy6GG8NFNu+n8uEYucCH8zwk7pprfBdoXYzyT33dMtT8r", - "hOc7fu3LFK5RCLJmZ8S/nrDxtsmK0GWbOw7mXLoE3X29y7Pt5fbfAAAA///PKdGnmxkAAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode -func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) - if err != nil { - return nil, fmt.Errorf("error base64 decoding spec: %w", err) - } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } - var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } - - return buf.Bytes(), nil -} - -var rawSpec = decodeSpecCached() - -// a naive cached of a decoded swagger spec -func decodeSpecCached() func() ([]byte, error) { - data, err := decodeSpec() - return func() ([]byte, error) { - return data, err - } -} - -// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. -func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { - res := make(map[string]func() ([]byte, error)) - if len(pathToFile) > 0 { - res[pathToFile] = rawSpec - } - - return res -} - -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { - resolvePath := PathToRawSpec("") - - loader := openapi3.NewLoader() - loader.IsExternalRefsAllowed = true - loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { - pathToFile := url.String() - pathToFile = path.Clean(pathToFile) - getSpec, ok := resolvePath[pathToFile] - if !ok { - err1 := fmt.Errorf("path not found: %s", pathToFile) - return nil, err1 - } - return getSpec() - } - var specData []byte - specData, err = rawSpec() - if err != nil { - return - } - swagger, err = loader.LoadFromData(specData) - if err != nil { - return - } - return -} diff --git a/token-sdk/auditor/routes/routes.go b/token-sdk/auditor/routes/routes.go deleted file mode 100644 index 4e77de88..00000000 --- a/token-sdk/auditor/routes/routes.go +++ /dev/null @@ -1,100 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package routes - -import ( - "context" - "fmt" - - "github.com/hyperledger/fabric-samples/token-sdk/auditor/service" -) - -type Controller struct { - Service service.TokenService -} - -// Get an account and their balance of a certain type -// (GET /auditor/accounts/{id}) -func (c Controller) AuditorAccount(ctx context.Context, request AuditorAccountRequestObject) (AuditorAccountResponseObject, error) { - if request.Params.Code == nil { - return AuditorAccountdefaultJSONResponse{ - Body: Error{ - Message: "code is required", - Payload: "", - }, - StatusCode: 400, - }, nil - } - - balance, err := c.Service.GetBalance(request.Id, *request.Params.Code) - if err != nil { - return AuditorAccountdefaultJSONResponse{ - Body: Error{ - Message: "can't get account", - Payload: err.Error(), - }, - StatusCode: 500, - }, nil - } - - amounts := []Amount{} - for typ, val := range balance { - amounts = append(amounts, Amount{ - Code: typ, - Value: val, - }) - } - return AuditorAccount200JSONResponse{ - AccountSuccessJSONResponse: AccountSuccessJSONResponse{ - Message: fmt.Sprintf("got %s's %s", request.Id, *request.Params.Code), - Payload: Account{ - Id: request.Id, - Balance: amounts, - }, - }, - }, nil -} - -// Get all transactions for an account -// (GET /owner/accounts/{id}/transactions) -func (c Controller) AuditorTransactions(ctx context.Context, request AuditorTransactionsRequestObject) (AuditorTransactionsResponseObject, error) { - var history []service.TransactionHistoryItem - var err error - - history, err = c.Service.GetHistory(request.Id) - if err != nil { - return AuditorTransactionsdefaultJSONResponse{ - Body: Error{ - Message: "can't get history", - Payload: err.Error(), - }, - StatusCode: 500, - }, nil - } - - pl := []TransactionRecord{} - for _, tx := range history { - pl = append(pl, TransactionRecord{ - Amount: Amount{ - Code: tx.TokenType, - Value: tx.Amount, - }, - Id: tx.TxID, - Recipient: tx.Recipient, - Sender: tx.Sender, - Status: tx.Status, - Timestamp: tx.Timestamp, - Message: tx.Message, - }) - } - return AuditorTransactions200JSONResponse{ - TransactionsSuccessJSONResponse: TransactionsSuccessJSONResponse{ - Message: fmt.Sprintf("got %d transactions for %s", len(pl), request.Id), - Payload: pl, - }, - }, nil -} diff --git a/token-sdk/auditor/routes/server.go b/token-sdk/auditor/routes/server.go deleted file mode 100644 index f3e639b2..00000000 --- a/token-sdk/auditor/routes/server.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package routes - -import ( - "fmt" - "log" - "os" - - oapimiddleware "github.com/deepmap/oapi-codegen/pkg/middleware" - "github.com/labstack/echo/v4" - middleware "github.com/labstack/echo/v4/middleware" -) - -type Logger interface { - Infof(template string, args ...interface{}) - Debugf(template string, args ...interface{}) - Warnf(template string, args ...interface{}) - Errorf(template string, args ...interface{}) - Fatalf(template string, args ...interface{}) -} - -// Start web server on the main thread. It exits the application if it fails setting up. -func StartWebServer(port string, routesImplementation StrictServerInterface, logger Logger) error { - e := echo.New() - baseURL := "/api/v1" - - handler := NewStrictHandler(routesImplementation, nil) - RegisterHandlersWithBaseURL(e, handler, baseURL) - - // Request validator - swagger, err := GetSwagger() - if err != nil { - log.Fatalf("Error loading swagger spec\n: %s", err) - os.Exit(1) - } - swagger.Servers = nil - e.Group(baseURL).Use(oapimiddleware.OapiRequestValidator(swagger)) - - e.Use(middleware.CORS()) - e.Use(middleware.RequestID()) - e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{ - Skipper: func(c echo.Context) bool { - return c.Path() == "/api/v1/healthz" || c.Path() == "/api/v1/readyz" - }, - LogRequestID: true, LogMethod: true, LogURI: true, LogStatus: true, LogLatency: true, - LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error { - if v.Status < 400 { - logger.Infof("%d %s %s %s [%s]", v.Status, v.Method, v.URI, v.Latency.String(), v.RequestID) - } else if v.Status >= 400 && v.Status < 500 { - logger.Warnf("%d %s %s %s [%s]", v.Status, v.Method, v.URI, v.Latency.String(), v.RequestID) - } else { - logger.Errorf("%d %s %s %s [%s]", v.Status, v.Method, v.URI, v.Latency.String(), v.RequestID) - } - return nil - }, - })) - - // Start REST API server - return e.Start(fmt.Sprintf("0.0.0.0:%s", port)) -} diff --git a/token-sdk/auditor/service/audit.go b/token-sdk/auditor/service/audit.go deleted file mode 100644 index d59317a4..00000000 --- a/token-sdk/auditor/service/audit.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package service - -import ( - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/flogging" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx" - "github.com/pkg/errors" -) - -var logger = flogging.MustGetLogger("service") - -// VIEW - -// Auditing is initiated as a response to an audit request from another -// FSC node (not via an internal service or API). - -type AuditView struct{} - -func (v *AuditView) Call(context view.Context) (interface{}, error) { - logger.Infof("incoming session from [%s]", context.Session().Info().Endpoint) - tx, err := ttx.ReceiveTransaction(context) - if err != nil { - err = errors.Wrap(err, "failed receiving transaction") - logger.Error(err.Error()) - return "", err - } - // get auditor wallet - w := ttx.MyAuditorWallet(context) - if w == nil { - err = errors.New("failed getting default auditor wallet") - logger.Error(err.Error()) - return "", err - } - auditor := ttx.NewAuditor(context, w) - - // Validate - err = auditor.Validate(tx) - if err != nil { - err = errors.Wrapf(err, "transaction invalid: [%s]", tx.ID()) - logger.Error(err.Error()) - return "", err - } - // See https://github.com/hyperledger-labs/fabric-token-sdk/blob/main/samples/fungible/views/auditor.go for examples of auditor checks - - logger.Infof("transaction valid: [%s]", tx.ID()) - res, err := context.RunView(ttx.NewAuditApproveView(w, tx)) - if err != nil { - logger.Error(err.Error()) - return "", err - } - logger.Infof("transaction committed: [%s]", tx.ID()) - - return res, err -} - -type RegisterAuditorView struct{} - -func (r *RegisterAuditorView) Call(context view.Context) (interface{}, error) { - return context.RunView(ttx.NewRegisterAuditorView( - &AuditView{}, - )) -} diff --git a/token-sdk/auditor/service/balance.go b/token-sdk/auditor/service/balance.go deleted file mode 100644 index 1a9a4e28..00000000 --- a/token-sdk/auditor/service/balance.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package service - -import ( - "github.com/hyperledger-labs/fabric-smart-client/pkg/api" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx" - "github.com/pkg/errors" -) - -type TokenService struct { - FSC api.ServiceProvider -} - -// SERVICE -type ValueByTokenType map[string]int64 - -// GetBalance returns the balances per token type of a wallet -func (s TokenService) GetBalance(wallet string, tokenType string) (typeVal ValueByTokenType, err error) { - typeVal = make(ValueByTokenType) - - // get auditor wallet - w := ttx.MyAuditorWallet(s.FSC) - if w == nil { - err = errors.New("failed getting default auditor wallet") - logger.Error(err.Error()) - return - } - auditor := ttx.NewAuditor(s.FSC, w) - - aqe := auditor.NewQueryExecutor() - defer aqe.Done() - - // TODO: how to get all TokenTypes separately? - filter, err := aqe.NewHoldingsFilter().ByEnrollmentId(wallet).ByType(tokenType).Execute() - if err != nil { - err = errors.Wrapf(err, "failed retrieving holding for [%s][%s]", wallet, tokenType) - logger.Error(err.Error()) - return - } - currentHolding := filter.Sum() - - typeVal[tokenType] = currentHolding.Int64() - logger.Debugf("Current Holding: [%s][%s][%d]", wallet, tokenType, typeVal[tokenType]) - - return -} diff --git a/token-sdk/auditor/service/history.go b/token-sdk/auditor/service/history.go deleted file mode 100644 index 509cfae4..00000000 --- a/token-sdk/auditor/service/history.go +++ /dev/null @@ -1,105 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package service - -import ( - "time" - - "github.com/hyperledger-labs/fabric-token-sdk/token" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/ttxdb" - "github.com/pkg/errors" -) - -// SERVICE - -type TransactionHistoryItem struct { - // TxID is the transaction ID - TxID string - // ActionType is the type of action performed by this transaction record - ActionType int - // SenderEID is the enrollment ID of the account that is sending tokens - Sender string - // RecipientEID is the enrollment ID of the account that is receiving tokens - Recipient string - // TokenType is the type of token - TokenType string - // Amount is positive if tokens are received. Negative otherwise - Amount int64 - // Timestamp is the time the transaction was submitted to the db - Timestamp time.Time - // Status is the status of the transaction - Status string - // Message is the user message sent with the transaction. It comes from - // the ApplicationMetadata and is sent in the transient field - Message string -} - -// GetHistory returns the full transaction history for an auditor. -func (s TokenService) GetHistory(wallet string) (txs []TransactionHistoryItem, err error) { - // get auditor wallet - w := ttx.MyAuditorWallet(s.FSC) - if w == nil { - err = errors.New("failed getting default auditor wallet") - logger.Error(err.Error()) - return txs, err - } - auditor := ttx.NewAuditor(s.FSC, w) - - // Get query executor - aqe := auditor.NewQueryExecutor() - defer aqe.Done() - - // This retrieves all transactions to *or* from the provided wallet. - // See QueryTransactionsParams interface for additional filters. - it, err := aqe.Transactions(ttxdb.QueryTransactionsParams{ - SenderWallet: wallet, - RecipientWallet: wallet, - }) - if err != nil { - return txs, errors.New("failed querying transactions") - } - defer it.Close() - - // we need transaction info to get the transient field (application metadata) - tip := ttx.NewTransactionInfoProvider(s.FSC, token.GetManagementService(s.FSC)) - if tip == nil { - return txs, errors.New("failed to get transactionInfoProvider") - } - - // Return the list of audited transactions - for { - tx, err := it.Next() - if tx == nil { - break - } - transaction := TransactionHistoryItem{ - TxID: tx.TxID, - ActionType: int(tx.ActionType), - Sender: tx.SenderEID, - Recipient: tx.RecipientEID, - TokenType: tx.TokenType, - Amount: tx.Amount.Int64(), - Timestamp: tx.Timestamp.UTC(), - Status: string(tx.Status), - } - if err != nil { - return txs, errors.New("failed iterating over transactions") - } - - // set user provided message from transient field - ti, err := tip.TransactionInfo(transaction.TxID) - if err != nil { - return txs, err - } - if ti.ApplicationMetadata != nil && string(ti.ApplicationMetadata["message"]) != "" { - transaction.Message = string(ti.ApplicationMetadata["message"]) - } - txs = append(txs, transaction) - } - return -} diff --git a/token-sdk/components.png b/token-sdk/components.png deleted file mode 100644 index 85a4a413..00000000 Binary files a/token-sdk/components.png and /dev/null differ diff --git a/token-sdk/compose-ca.yaml b/token-sdk/compose-ca.yaml deleted file mode 100644 index 89063e91..00000000 --- a/token-sdk/compose-ca.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright IBM Corp. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -# - -version: '3.7' - -services: - ca_token_network: - image: hyperledger/fabric-ca:1.5.7 - labels: - service: hyperledger-fabric - environment: - - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server - - FABRIC_CA_SERVER_CA_NAME=ca-token-network - - FABRIC_CA_SERVER_TLS_ENABLED=false - - FABRIC_CA_SERVER_PORT=27054 - ports: - - "27054:27054" - command: sh -c 'fabric-ca-server start -b admin:adminpw --idemix.curve gurvy.Bn254 -d' - volumes: - - ${PWD}/keys/ca:/etc/hyperledger/fabric-ca-server - container_name: ca_token_network diff --git a/token-sdk/dependencies.png b/token-sdk/dependencies.png deleted file mode 100644 index 9916a0a5..00000000 Binary files a/token-sdk/dependencies.png and /dev/null differ diff --git a/token-sdk/docker-compose.yaml b/token-sdk/docker-compose.yaml deleted file mode 100644 index e1497667..00000000 --- a/token-sdk/docker-compose.yaml +++ /dev/null @@ -1,101 +0,0 @@ -version: '3.7' - -# fabric_test is the name of the fabric-samples test network. -# By connecting to it, we can reach the peers at their DNS names -# (e.g. peer0.org1.example.com). -networks: - test: - name: fabric_test - external: true - -services: - auditor: - hostname: auditor.example.com - restart: always - build: - context: ./auditor - dockerfile: ../Dockerfile - volumes: - - ./data/auditor:/var/fsc/data/auditor - - ./auditor/conf:/conf:ro - - ./keys:/var/fsc/keys:ro - ports: - - 9000:9000 - expose: - - 9001 - networks: - - test - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9000/api/v1/readyz"] - interval: "5s" - timeout: "1s" - retries: 20 - - issuer: - hostname: issuer.example.com - restart: always - build: - context: ./issuer - dockerfile: ../Dockerfile - volumes: - - ./data/issuer:/var/fsc/data/issuer - - ./issuer/conf:/conf:ro - - ./keys:/var/fsc/keys:ro - ports: - - 9100:9000 - expose: - - 9101 - networks: - - test - depends_on: - auditor: - condition: service_healthy - - owner1: - hostname: owner1.example.com - restart: always - build: - context: ./owner - dockerfile: ../Dockerfile - volumes: - - ./data/owner1:/var/fsc/data/owner1 - - ./owner/conf/owner1:/conf:ro - - ./keys:/var/fsc/keys:ro - ports: - - 9200:9000 - expose: - - 9201 - networks: - - test - depends_on: - auditor: - condition: service_healthy - - owner2: - hostname: owner2.example.com - restart: always - build: - context: ./owner - dockerfile: ../Dockerfile - volumes: - - ./data/owner2:/var/fsc/data/owner2 - - ./owner/conf/owner2:/conf:ro - - ./keys:/var/fsc/keys:ro - ports: - - 9300:9000 - expose: - - 9301 - networks: - - test - depends_on: - auditor: - condition: service_healthy - - swagger-ui: - image: swaggerapi/swagger-ui - ports: - - '8080:8080' - environment: - - URL=/swagger.yaml - volumes: - - ./swagger.yaml:/usr/share/nginx/html/swagger.yaml diff --git a/token-sdk/e2e/client.gen.go b/token-sdk/e2e/client.gen.go deleted file mode 100644 index b6b8039e..00000000 --- a/token-sdk/e2e/client.gen.go +++ /dev/null @@ -1,1591 +0,0 @@ -// Package e2e provides primitives to interact with the openapi HTTP API. -// -// Code generated by github.com/deepmap/oapi-codegen version v1.13.4 DO NOT EDIT. -package e2e - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "net/url" - "strings" - "time" - - "github.com/deepmap/oapi-codegen/pkg/runtime" -) - -// Account Information about an account and its balance -type Account struct { - // Balance balance in base units for each currency - Balance []Amount `json:"balance"` - - // Id account id as registered at the Certificate Authority - Id string `json:"id"` -} - -// Amount The amount to issue, transfer or redeem. -type Amount struct { - // Code the code of the token - Code string `json:"code"` - - // Value value in base units (usually cents) - Value int64 `json:"value"` -} - -// Counterparty The counterparty in a Transfer or Issuance transaction. -type Counterparty struct { - Account string `json:"account"` - - // Node The node that holds the recipient account - Node string `json:"node"` -} - -// Error defines model for Error. -type Error struct { - // Message High level error message - Message string `json:"message"` - - // Payload Details about the error - Payload string `json:"payload"` -} - -// RedeemRequest Instructions to redeem tokens from an account -type RedeemRequest struct { - // Amount The amount to issue, transfer or redeem. - Amount Amount `json:"amount"` - - // Message optional message that will be visible to the auditor - Message *string `json:"message,omitempty"` -} - -// TransactionRecord A transaction -type TransactionRecord struct { - // Amount The amount to issue, transfer or redeem. - Amount Amount `json:"amount"` - - // Id transaction id - Id string `json:"id"` - - // Message user provided message - Message string `json:"message"` - - // Recipient the recipient of the transaction - Recipient string `json:"recipient"` - - // Sender the sender of the transaction - Sender string `json:"sender"` - - // Status Unknown | Pending | Confirmed | Deleted - Status string `json:"status"` - - // Timestamp timestamp in the format: "2018-03-20T09:12:28Z" - Timestamp time.Time `json:"timestamp"` -} - -// TransferRequest Instructions to issue or transfer tokens to an account -type TransferRequest struct { - // Amount The amount to issue, transfer or redeem. - Amount Amount `json:"amount"` - - // Counterparty The counterparty in a Transfer or Issuance transaction. - Counterparty Counterparty `json:"counterparty"` - - // Message optional message that will be sent and stored with the transfer transaction - Message *string `json:"message,omitempty"` -} - -// Code The token code to filter on -type Code = string - -// Id account id as registered at the Certificate Authority -type Id = string - -// AccountSuccess defines model for AccountSuccess. -type AccountSuccess struct { - Message string `json:"message"` - - // Payload Information about an account and its balance - Payload Account `json:"payload"` -} - -// AccountsSuccess defines model for AccountsSuccess. -type AccountsSuccess struct { - Message string `json:"message"` - Payload []Account `json:"payload"` -} - -// ErrorResponse defines model for ErrorResponse. -type ErrorResponse = Error - -// HealthSuccess defines model for HealthSuccess. -type HealthSuccess struct { - // Message ok - Message string `json:"message"` -} - -// IssueSuccess defines model for IssueSuccess. -type IssueSuccess struct { - Message string `json:"message"` - - // Payload Transaction id - Payload string `json:"payload"` -} - -// RedeemSuccess defines model for RedeemSuccess. -type RedeemSuccess struct { - Message string `json:"message"` - - // Payload Transaction id - Payload string `json:"payload"` -} - -// TransactionsSuccess defines model for TransactionsSuccess. -type TransactionsSuccess struct { - Message string `json:"message"` - Payload []TransactionRecord `json:"payload"` -} - -// TransferSuccess defines model for TransferSuccess. -type TransferSuccess struct { - Message string `json:"message"` - - // Payload Transaction id - Payload string `json:"payload"` -} - -// AuditorAccountParams defines parameters for AuditorAccount. -type AuditorAccountParams struct { - Code *Code `form:"code,omitempty" json:"code,omitempty"` -} - -// OwnerAccountParams defines parameters for OwnerAccount. -type OwnerAccountParams struct { - Code *Code `form:"code,omitempty" json:"code,omitempty"` -} - -// IssueJSONRequestBody defines body for Issue for application/json ContentType. -type IssueJSONRequestBody = TransferRequest - -// RedeemJSONRequestBody defines body for Redeem for application/json ContentType. -type RedeemJSONRequestBody = RedeemRequest - -// TransferJSONRequestBody defines body for Transfer for application/json ContentType. -type TransferJSONRequestBody = TransferRequest - -// RequestEditorFn is the function signature for the RequestEditor callback function -type RequestEditorFn func(ctx context.Context, req *http.Request) error - -// Doer performs HTTP requests. -// -// The standard http.Client implements this interface. -type HttpRequestDoer interface { - Do(req *http.Request) (*http.Response, error) -} - -// Client which conforms to the OpenAPI3 specification for this service. -type Client struct { - // The endpoint of the server conforming to this interface, with scheme, - // https://api.deepmap.com for example. This can contain a path relative - // to the server, such as https://api.deepmap.com/dev-test, and all the - // paths in the swagger spec will be appended to the server. - Server string - - // Doer for performing requests, typically a *http.Client with any - // customized settings, such as certificate chains. - Client HttpRequestDoer - - // A list of callbacks for modifying requests which are generated before sending over - // the network. - RequestEditors []RequestEditorFn -} - -// ClientOption allows setting custom parameters during construction -type ClientOption func(*Client) error - -// Creates a new Client, with reasonable defaults -func NewClient(server string, opts ...ClientOption) (*Client, error) { - // create a client with sane default values - client := Client{ - Server: server, - } - // mutate client and add all optional params - for _, o := range opts { - if err := o(&client); err != nil { - return nil, err - } - } - // ensure the server URL always has a trailing slash - if !strings.HasSuffix(client.Server, "/") { - client.Server += "/" - } - // create httpClient, if not already present - if client.Client == nil { - client.Client = &http.Client{} - } - return &client, nil -} - -// WithHTTPClient allows overriding the default Doer, which is -// automatically created using http.Client. This is useful for tests. -func WithHTTPClient(doer HttpRequestDoer) ClientOption { - return func(c *Client) error { - c.Client = doer - return nil - } -} - -// WithRequestEditorFn allows setting up a callback function, which will be -// called right before sending the request. This can be used to mutate the request. -func WithRequestEditorFn(fn RequestEditorFn) ClientOption { - return func(c *Client) error { - c.RequestEditors = append(c.RequestEditors, fn) - return nil - } -} - -// The interface specification for the client above. -type ClientInterface interface { - // AuditorAccount request - AuditorAccount(ctx context.Context, id Id, params *AuditorAccountParams, reqEditors ...RequestEditorFn) (*http.Response, error) - - // AuditorTransactions request - AuditorTransactions(ctx context.Context, id Id, reqEditors ...RequestEditorFn) (*http.Response, error) - - // Healthz request - Healthz(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) - - // IssueWithBody request with any body - IssueWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - Issue(ctx context.Context, body IssueJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - - // OwnerAccounts request - OwnerAccounts(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) - - // OwnerAccount request - OwnerAccount(ctx context.Context, id Id, params *OwnerAccountParams, reqEditors ...RequestEditorFn) (*http.Response, error) - - // RedeemWithBody request with any body - RedeemWithBody(ctx context.Context, id Id, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - Redeem(ctx context.Context, id Id, body RedeemJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - - // OwnerTransactions request - OwnerTransactions(ctx context.Context, id Id, reqEditors ...RequestEditorFn) (*http.Response, error) - - // TransferWithBody request with any body - TransferWithBody(ctx context.Context, id Id, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - Transfer(ctx context.Context, id Id, body TransferJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - - // Readyz request - Readyz(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) -} - -func (c *Client) AuditorAccount(ctx context.Context, id Id, params *AuditorAccountParams, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewAuditorAccountRequest(c.Server, id, params) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) AuditorTransactions(ctx context.Context, id Id, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewAuditorTransactionsRequest(c.Server, id) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) Healthz(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewHealthzRequest(c.Server) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) IssueWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewIssueRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) Issue(ctx context.Context, body IssueJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewIssueRequest(c.Server, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) OwnerAccounts(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewOwnerAccountsRequest(c.Server) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) OwnerAccount(ctx context.Context, id Id, params *OwnerAccountParams, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewOwnerAccountRequest(c.Server, id, params) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) RedeemWithBody(ctx context.Context, id Id, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewRedeemRequestWithBody(c.Server, id, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) Redeem(ctx context.Context, id Id, body RedeemJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewRedeemRequest(c.Server, id, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) OwnerTransactions(ctx context.Context, id Id, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewOwnerTransactionsRequest(c.Server, id) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) TransferWithBody(ctx context.Context, id Id, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewTransferRequestWithBody(c.Server, id, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) Transfer(ctx context.Context, id Id, body TransferJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewTransferRequest(c.Server, id, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) Readyz(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewReadyzRequest(c.Server) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -// NewAuditorAccountRequest generates requests for AuditorAccount -func NewAuditorAccountRequest(server string, id Id, params *AuditorAccountParams) (*http.Request, error) { - var err error - - var pathParam0 string - - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "id", runtime.ParamLocationPath, id) - if err != nil { - return nil, err - } - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/auditor/accounts/%s", pathParam0) - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - if params != nil { - queryValues := queryURL.Query() - - if params.Code != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "code", runtime.ParamLocationQuery, *params.Code); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - } - - queryURL.RawQuery = queryValues.Encode() - } - - req, err := http.NewRequest("GET", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewAuditorTransactionsRequest generates requests for AuditorTransactions -func NewAuditorTransactionsRequest(server string, id Id) (*http.Request, error) { - var err error - - var pathParam0 string - - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "id", runtime.ParamLocationPath, id) - if err != nil { - return nil, err - } - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/auditor/accounts/%s/transactions", pathParam0) - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("GET", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewHealthzRequest generates requests for Healthz -func NewHealthzRequest(server string) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/healthz") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("GET", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewIssueRequest calls the generic Issue builder with application/json body -func NewIssueRequest(server string, body IssueJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewIssueRequestWithBody(server, "application/json", bodyReader) -} - -// NewIssueRequestWithBody generates requests for Issue with any type of body -func NewIssueRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/issuer/issue") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewOwnerAccountsRequest generates requests for OwnerAccounts -func NewOwnerAccountsRequest(server string) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/owner/accounts") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("GET", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewOwnerAccountRequest generates requests for OwnerAccount -func NewOwnerAccountRequest(server string, id Id, params *OwnerAccountParams) (*http.Request, error) { - var err error - - var pathParam0 string - - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "id", runtime.ParamLocationPath, id) - if err != nil { - return nil, err - } - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/owner/accounts/%s", pathParam0) - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - if params != nil { - queryValues := queryURL.Query() - - if params.Code != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "code", runtime.ParamLocationQuery, *params.Code); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - } - - queryURL.RawQuery = queryValues.Encode() - } - - req, err := http.NewRequest("GET", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewRedeemRequest calls the generic Redeem builder with application/json body -func NewRedeemRequest(server string, id Id, body RedeemJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewRedeemRequestWithBody(server, id, "application/json", bodyReader) -} - -// NewRedeemRequestWithBody generates requests for Redeem with any type of body -func NewRedeemRequestWithBody(server string, id Id, contentType string, body io.Reader) (*http.Request, error) { - var err error - - var pathParam0 string - - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "id", runtime.ParamLocationPath, id) - if err != nil { - return nil, err - } - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/owner/accounts/%s/redeem", pathParam0) - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewOwnerTransactionsRequest generates requests for OwnerTransactions -func NewOwnerTransactionsRequest(server string, id Id) (*http.Request, error) { - var err error - - var pathParam0 string - - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "id", runtime.ParamLocationPath, id) - if err != nil { - return nil, err - } - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/owner/accounts/%s/transactions", pathParam0) - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("GET", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewTransferRequest calls the generic Transfer builder with application/json body -func NewTransferRequest(server string, id Id, body TransferJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewTransferRequestWithBody(server, id, "application/json", bodyReader) -} - -// NewTransferRequestWithBody generates requests for Transfer with any type of body -func NewTransferRequestWithBody(server string, id Id, contentType string, body io.Reader) (*http.Request, error) { - var err error - - var pathParam0 string - - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "id", runtime.ParamLocationPath, id) - if err != nil { - return nil, err - } - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/owner/accounts/%s/transfer", pathParam0) - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewReadyzRequest generates requests for Readyz -func NewReadyzRequest(server string) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/readyz") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("GET", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { - for _, r := range c.RequestEditors { - if err := r(ctx, req); err != nil { - return err - } - } - for _, r := range additionalEditors { - if err := r(ctx, req); err != nil { - return err - } - } - return nil -} - -// ClientWithResponses builds on ClientInterface to offer response payloads -type ClientWithResponses struct { - ClientInterface -} - -// NewClientWithResponses creates a new ClientWithResponses, which wraps -// Client with return type handling -func NewClientWithResponses(server string, opts ...ClientOption) (*ClientWithResponses, error) { - client, err := NewClient(server, opts...) - if err != nil { - return nil, err - } - return &ClientWithResponses{client}, nil -} - -// WithBaseURL overrides the baseURL. -func WithBaseURL(baseURL string) ClientOption { - return func(c *Client) error { - newBaseURL, err := url.Parse(baseURL) - if err != nil { - return err - } - c.Server = newBaseURL.String() - return nil - } -} - -// ClientWithResponsesInterface is the interface specification for the client with responses above. -type ClientWithResponsesInterface interface { - // AuditorAccountWithResponse request - AuditorAccountWithResponse(ctx context.Context, id Id, params *AuditorAccountParams, reqEditors ...RequestEditorFn) (*AuditorAccountResponse, error) - - // AuditorTransactionsWithResponse request - AuditorTransactionsWithResponse(ctx context.Context, id Id, reqEditors ...RequestEditorFn) (*AuditorTransactionsResponse, error) - - // HealthzWithResponse request - HealthzWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*HealthzResponse, error) - - // IssueWithBodyWithResponse request with any body - IssueWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*IssueResponse, error) - - IssueWithResponse(ctx context.Context, body IssueJSONRequestBody, reqEditors ...RequestEditorFn) (*IssueResponse, error) - - // OwnerAccountsWithResponse request - OwnerAccountsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*OwnerAccountsResponse, error) - - // OwnerAccountWithResponse request - OwnerAccountWithResponse(ctx context.Context, id Id, params *OwnerAccountParams, reqEditors ...RequestEditorFn) (*OwnerAccountResponse, error) - - // RedeemWithBodyWithResponse request with any body - RedeemWithBodyWithResponse(ctx context.Context, id Id, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RedeemResponse, error) - - RedeemWithResponse(ctx context.Context, id Id, body RedeemJSONRequestBody, reqEditors ...RequestEditorFn) (*RedeemResponse, error) - - // OwnerTransactionsWithResponse request - OwnerTransactionsWithResponse(ctx context.Context, id Id, reqEditors ...RequestEditorFn) (*OwnerTransactionsResponse, error) - - // TransferWithBodyWithResponse request with any body - TransferWithBodyWithResponse(ctx context.Context, id Id, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*TransferResponse, error) - - TransferWithResponse(ctx context.Context, id Id, body TransferJSONRequestBody, reqEditors ...RequestEditorFn) (*TransferResponse, error) - - // ReadyzWithResponse request - ReadyzWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ReadyzResponse, error) -} - -type AuditorAccountResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *AccountSuccess - JSONDefault *ErrorResponse -} - -// Status returns HTTPResponse.Status -func (r AuditorAccountResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r AuditorAccountResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type AuditorTransactionsResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *TransactionsSuccess - JSONDefault *ErrorResponse -} - -// Status returns HTTPResponse.Status -func (r AuditorTransactionsResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r AuditorTransactionsResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type HealthzResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *HealthSuccess - JSON503 *ErrorResponse -} - -// Status returns HTTPResponse.Status -func (r HealthzResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r HealthzResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type IssueResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *IssueSuccess - JSONDefault *ErrorResponse -} - -// Status returns HTTPResponse.Status -func (r IssueResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r IssueResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type OwnerAccountsResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *AccountsSuccess - JSONDefault *ErrorResponse -} - -// Status returns HTTPResponse.Status -func (r OwnerAccountsResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r OwnerAccountsResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type OwnerAccountResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *AccountSuccess - JSONDefault *ErrorResponse -} - -// Status returns HTTPResponse.Status -func (r OwnerAccountResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r OwnerAccountResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type RedeemResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *RedeemSuccess - JSONDefault *ErrorResponse -} - -// Status returns HTTPResponse.Status -func (r RedeemResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r RedeemResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type OwnerTransactionsResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *TransactionsSuccess - JSONDefault *ErrorResponse -} - -// Status returns HTTPResponse.Status -func (r OwnerTransactionsResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r OwnerTransactionsResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type TransferResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *TransferSuccess - JSONDefault *ErrorResponse -} - -// Status returns HTTPResponse.Status -func (r TransferResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r TransferResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type ReadyzResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *HealthSuccess - JSON503 *ErrorResponse -} - -// Status returns HTTPResponse.Status -func (r ReadyzResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r ReadyzResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -// AuditorAccountWithResponse request returning *AuditorAccountResponse -func (c *ClientWithResponses) AuditorAccountWithResponse(ctx context.Context, id Id, params *AuditorAccountParams, reqEditors ...RequestEditorFn) (*AuditorAccountResponse, error) { - rsp, err := c.AuditorAccount(ctx, id, params, reqEditors...) - if err != nil { - return nil, err - } - return ParseAuditorAccountResponse(rsp) -} - -// AuditorTransactionsWithResponse request returning *AuditorTransactionsResponse -func (c *ClientWithResponses) AuditorTransactionsWithResponse(ctx context.Context, id Id, reqEditors ...RequestEditorFn) (*AuditorTransactionsResponse, error) { - rsp, err := c.AuditorTransactions(ctx, id, reqEditors...) - if err != nil { - return nil, err - } - return ParseAuditorTransactionsResponse(rsp) -} - -// HealthzWithResponse request returning *HealthzResponse -func (c *ClientWithResponses) HealthzWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*HealthzResponse, error) { - rsp, err := c.Healthz(ctx, reqEditors...) - if err != nil { - return nil, err - } - return ParseHealthzResponse(rsp) -} - -// IssueWithBodyWithResponse request with arbitrary body returning *IssueResponse -func (c *ClientWithResponses) IssueWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*IssueResponse, error) { - rsp, err := c.IssueWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseIssueResponse(rsp) -} - -func (c *ClientWithResponses) IssueWithResponse(ctx context.Context, body IssueJSONRequestBody, reqEditors ...RequestEditorFn) (*IssueResponse, error) { - rsp, err := c.Issue(ctx, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseIssueResponse(rsp) -} - -// OwnerAccountsWithResponse request returning *OwnerAccountsResponse -func (c *ClientWithResponses) OwnerAccountsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*OwnerAccountsResponse, error) { - rsp, err := c.OwnerAccounts(ctx, reqEditors...) - if err != nil { - return nil, err - } - return ParseOwnerAccountsResponse(rsp) -} - -// OwnerAccountWithResponse request returning *OwnerAccountResponse -func (c *ClientWithResponses) OwnerAccountWithResponse(ctx context.Context, id Id, params *OwnerAccountParams, reqEditors ...RequestEditorFn) (*OwnerAccountResponse, error) { - rsp, err := c.OwnerAccount(ctx, id, params, reqEditors...) - if err != nil { - return nil, err - } - return ParseOwnerAccountResponse(rsp) -} - -// RedeemWithBodyWithResponse request with arbitrary body returning *RedeemResponse -func (c *ClientWithResponses) RedeemWithBodyWithResponse(ctx context.Context, id Id, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RedeemResponse, error) { - rsp, err := c.RedeemWithBody(ctx, id, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseRedeemResponse(rsp) -} - -func (c *ClientWithResponses) RedeemWithResponse(ctx context.Context, id Id, body RedeemJSONRequestBody, reqEditors ...RequestEditorFn) (*RedeemResponse, error) { - rsp, err := c.Redeem(ctx, id, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseRedeemResponse(rsp) -} - -// OwnerTransactionsWithResponse request returning *OwnerTransactionsResponse -func (c *ClientWithResponses) OwnerTransactionsWithResponse(ctx context.Context, id Id, reqEditors ...RequestEditorFn) (*OwnerTransactionsResponse, error) { - rsp, err := c.OwnerTransactions(ctx, id, reqEditors...) - if err != nil { - return nil, err - } - return ParseOwnerTransactionsResponse(rsp) -} - -// TransferWithBodyWithResponse request with arbitrary body returning *TransferResponse -func (c *ClientWithResponses) TransferWithBodyWithResponse(ctx context.Context, id Id, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*TransferResponse, error) { - rsp, err := c.TransferWithBody(ctx, id, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseTransferResponse(rsp) -} - -func (c *ClientWithResponses) TransferWithResponse(ctx context.Context, id Id, body TransferJSONRequestBody, reqEditors ...RequestEditorFn) (*TransferResponse, error) { - rsp, err := c.Transfer(ctx, id, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseTransferResponse(rsp) -} - -// ReadyzWithResponse request returning *ReadyzResponse -func (c *ClientWithResponses) ReadyzWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ReadyzResponse, error) { - rsp, err := c.Readyz(ctx, reqEditors...) - if err != nil { - return nil, err - } - return ParseReadyzResponse(rsp) -} - -// ParseAuditorAccountResponse parses an HTTP response from a AuditorAccountWithResponse call -func ParseAuditorAccountResponse(rsp *http.Response) (*AuditorAccountResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &AuditorAccountResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest AccountSuccess - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest ErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSONDefault = &dest - - } - - return response, nil -} - -// ParseAuditorTransactionsResponse parses an HTTP response from a AuditorTransactionsWithResponse call -func ParseAuditorTransactionsResponse(rsp *http.Response) (*AuditorTransactionsResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &AuditorTransactionsResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest TransactionsSuccess - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest ErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSONDefault = &dest - - } - - return response, nil -} - -// ParseHealthzResponse parses an HTTP response from a HealthzWithResponse call -func ParseHealthzResponse(rsp *http.Response) (*HealthzResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &HealthzResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest HealthSuccess - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: - var dest ErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON503 = &dest - - } - - return response, nil -} - -// ParseIssueResponse parses an HTTP response from a IssueWithResponse call -func ParseIssueResponse(rsp *http.Response) (*IssueResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &IssueResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest IssueSuccess - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest ErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSONDefault = &dest - - } - - return response, nil -} - -// ParseOwnerAccountsResponse parses an HTTP response from a OwnerAccountsWithResponse call -func ParseOwnerAccountsResponse(rsp *http.Response) (*OwnerAccountsResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &OwnerAccountsResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest AccountsSuccess - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest ErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSONDefault = &dest - - } - - return response, nil -} - -// ParseOwnerAccountResponse parses an HTTP response from a OwnerAccountWithResponse call -func ParseOwnerAccountResponse(rsp *http.Response) (*OwnerAccountResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &OwnerAccountResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest AccountSuccess - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest ErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSONDefault = &dest - - } - - return response, nil -} - -// ParseRedeemResponse parses an HTTP response from a RedeemWithResponse call -func ParseRedeemResponse(rsp *http.Response) (*RedeemResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &RedeemResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest RedeemSuccess - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest ErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSONDefault = &dest - - } - - return response, nil -} - -// ParseOwnerTransactionsResponse parses an HTTP response from a OwnerTransactionsWithResponse call -func ParseOwnerTransactionsResponse(rsp *http.Response) (*OwnerTransactionsResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &OwnerTransactionsResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest TransactionsSuccess - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest ErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSONDefault = &dest - - } - - return response, nil -} - -// ParseTransferResponse parses an HTTP response from a TransferWithResponse call -func ParseTransferResponse(rsp *http.Response) (*TransferResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &TransferResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest TransferSuccess - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: - var dest ErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSONDefault = &dest - - } - - return response, nil -} - -// ParseReadyzResponse parses an HTTP response from a ReadyzWithResponse call -func ParseReadyzResponse(rsp *http.Response) (*ReadyzResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &ReadyzResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest HealthSuccess - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: - var dest ErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON503 = &dest - - } - - return response, nil -} diff --git a/token-sdk/e2e/e2e_test.go b/token-sdk/e2e/e2e_test.go deleted file mode 100644 index 8198ad05..00000000 --- a/token-sdk/e2e/e2e_test.go +++ /dev/null @@ -1,249 +0,0 @@ -package e2e - -import ( - "context" - "os" - "testing" - "time" - - "github.com/stretchr/testify/assert" -) - -var auditor *ClientWithResponses -var issuer *ClientWithResponses - -var err error -var CODE string = "TEST" -var alice = Counterparty{ - Account: "alice", - Node: "owner1", -} -var bob = Counterparty{ - Account: "bob", - Node: "owner1", -} -var dan = Counterparty{ - Account: "dan", - Node: "owner2", -} - -type ownerAPI struct { - client *ClientWithResponses -} - -var owner1 ownerAPI -var owner2 ownerAPI - -func TestMain(t *testing.T) { - auditor, err = NewClientWithResponses(getEnv("AUDITOR_URL", "http://localhost:9000/api/v1")) - assert.NoError(t, err, "failed creating client") - issuer, err = NewClientWithResponses(getEnv("ISSUER_URL", "http://localhost:9100/api/v1")) - assert.NoError(t, err, "failed creating client") - - client1, err := NewClientWithResponses(getEnv("OWNER1_URL", "http://localhost:9200/api/v1")) - assert.NoError(t, err, "failed creating client") - owner1 = ownerAPI{client: client1} - - client2, err := NewClientWithResponses(getEnv("OWNER2_URL", "http://localhost:9300/api/v1")) - assert.NoError(t, err, "failed creating client") - owner2 = ownerAPI{client: client2} - - // we have to issue funds to alice first to be able to do the other tests - testIssuance(t) -} - -func testIssuance(t *testing.T) { - accBefore := owner1.getAccounts(t) - txBefore := owner1.getTransactions(t, "alice") - - id := issue(t, alice, 1000) - acc2 := owner1.getAccounts(t) - - txAfter := owner1.getTransactions(t, "alice") - assert.Equal(t, len(txBefore)+1, len(txAfter), "should have 1 issue transaction more", txAfter) - assert.Equal(t, getValue(t, accBefore, "alice")+1000, getValue(t, acc2, "alice"), acc2) - - lastTx := txAfter[len(txAfter)-1] - assert.Equal(t, id, lastTx.Id) - assert.Equal(t, int64(1000), lastTx.Amount.Value) - assert.Equal(t, "alice", lastTx.Recipient) -} - -func TestTransfer(t *testing.T) { - accBefore := owner1.getAccounts(t) - txBefore := owner1.getTransactions(t, "alice") - id := owner1.transfer(t, "alice", bob, 100) - accAfter := owner1.getAccounts(t) - txAfter := owner1.getTransactions(t, "alice") - - assert.Equal(t, getValue(t, accBefore, "alice")-100, getValue(t, accAfter, "alice"), accAfter) - assert.Equal(t, getValue(t, accBefore, "bob")+100, getValue(t, accAfter, "bob"), accAfter) - assert.Greater(t, len(txAfter), len(txBefore)) - - // on the sender side there may be several transactions, so we check the recipient - txBob := owner1.getTransactions(t, "bob") - lastTx := txBob[len(txBob)-1] - assert.Equal(t, id, lastTx.Id, txBob) - assert.Equal(t, lastTx.Amount.Value, int64(100)) -} - -func TestTransferToSecondNode(t *testing.T) { - // current state - acc1Before := owner1.getAccounts(t) - tx1Before := owner1.getTransactions(t, "alice") - acc2Before := owner2.getAccounts(t) - tx2Before := owner2.getTransactions(t, "dan") - - // transfer 100 from alice to dan - id := owner1.transfer(t, "alice", dan, 100) - - // after: alice - acc1After := owner1.getAccounts(t) - assert.Equal(t, getValue(t, acc1Before, "alice")-100, getValue(t, acc1After, "alice"), acc1After) // -100 TEST - tx1After := owner1.getTransactions(t, "alice") - assert.Greater(t, len(tx1After), len(tx1Before)) // +1 tx - - // after: dan - acc2After := owner2.getAccounts(t) - assert.Equal(t, getValue(t, acc2Before, "dan")+100, getValue(t, acc2After, "dan"), acc2After) // +100 TEST - tx2After := owner2.getTransactions(t, "dan") - assert.Greater(t, len(tx2After), len(tx2Before)) // + 1 tx - - // on the sender side there may be several transactions, so we check the recipient - txDan := owner2.getTransactions(t, "dan") - lastTx := txDan[len(txDan)-1] - assert.Equal(t, id, lastTx.Id, txDan) - assert.Equal(t, lastTx.Amount.Value, int64(100)) - owner2.testIfAuditorMatchesOwnerHistory(t, []string{"dan"}) -} - -func TestRedeem(t *testing.T) { - accBefore := owner1.getAccounts(t) - id := owner1.redeem(t, "alice", 10, "test redeem") - accAfter := owner1.getAccounts(t) - - transactions := owner1.getTransactions(t, "alice") - assert.Equal(t, getValue(t, accBefore, "alice")-10, getValue(t, accAfter, "alice"), accAfter) - lastTx := transactions[len(transactions)-1] - assert.Equal(t, id, lastTx.Id, transactions) - assert.Equal(t, lastTx.Amount.Value, int64(10)) - assert.Equal(t, "alice", lastTx.Sender) - assert.Equal(t, "test redeem", lastTx.Message) -} - -func TestIfAuditorMatchesOwnerHistory(t *testing.T) { - owner1.testIfAuditorMatchesOwnerHistory(t, []string{"alice", "bob"}) - owner2.testIfAuditorMatchesOwnerHistory(t, []string{"carlos", "dan"}) -} - -func issue(t *testing.T, counterparty Counterparty, value int64) string { - res, err := issuer.IssueWithResponse(context.TODO(), IssueJSONRequestBody{ - Amount: Amount{ - Code: CODE, - Value: value, - }, - Counterparty: alice, - Message: new(string), - }) - assert.NoError(t, err) - assert.Nil(t, res.JSONDefault) - assert.NotNil(t, res.JSON200) - t.Logf(res.JSON200.Message) - return res.JSON200.Payload -} - -func getAuditorTransactions(t *testing.T, wallet string) []TransactionRecord { - res, err := auditor.AuditorTransactionsWithResponse(context.TODO(), wallet) - assert.NoError(t, err) - assert.Nil(t, res.JSONDefault) - assert.NotNil(t, res.JSON200) - t.Logf(res.JSON200.Message) - return res.JSON200.Payload -} - -func (o *ownerAPI) testIfAuditorMatchesOwnerHistory(t *testing.T, accounts []string) { - for _, w := range accounts { - tx := o.getTransactions(t, w) - audittx := getAuditorTransactions(t, w) - assert.Equal(t, len(tx), len(audittx), w) - - // Timestamp is the time of storing the tx in the database - // so it's not the same on both sides. - for i := 0; i < len(tx); i++ { - tx[i].Timestamp = time.Time{} - audittx[i].Timestamp = time.Time{} - } - assert.Equal(t, tx, audittx) - } -} - -func (o *ownerAPI) getTransactions(t *testing.T, wallet string) []TransactionRecord { - res, err := o.client.OwnerTransactionsWithResponse(context.TODO(), wallet) - assert.NoError(t, err) - assert.Nil(t, res.JSONDefault) - assert.NotNil(t, res.JSON200) - t.Logf(res.JSON200.Message) - return res.JSON200.Payload -} - -func (o *ownerAPI) transfer(t *testing.T, sender string, counterparty Counterparty, value int64) string { - res, err := o.client.TransferWithResponse(context.TODO(), sender, TransferJSONRequestBody{ - Amount: Amount{ - Code: CODE, - Value: value, - }, - Counterparty: counterparty, - Message: new(string), - }) - assert.NoError(t, err) - assert.Nil(t, res.JSONDefault) - assert.NotNil(t, res.JSON200) - t.Logf(res.JSON200.Message) - return res.JSON200.Payload -} - -func (o *ownerAPI) redeem(t *testing.T, wallet string, value int64, message string) string { - res, err := o.client.RedeemWithResponse(context.TODO(), wallet, RedeemJSONRequestBody{ - Amount: Amount{ - Code: CODE, - Value: value, - }, - Message: &message, - }) - assert.NoError(t, err) - assert.Nil(t, res.JSONDefault) - assert.NotNil(t, res.JSON200) - t.Logf(res.JSON200.Message) - return res.JSON200.Payload -} - -func (o *ownerAPI) getAccounts(t *testing.T) []Account { - res, err := o.client.OwnerAccountsWithResponse(context.TODO()) - assert.NoError(t, err) - assert.Nil(t, res.JSONDefault) - assert.NotNil(t, res.JSON200) - t.Logf(res.JSON200.Message) - return res.JSON200.Payload -} - -func getValue(t *testing.T, acc []Account, wallet string) int64 { - for _, a := range acc { - if a.Id == wallet { - for _, b := range a.Balance { - if b.Code == CODE { - return b.Value - } - } - } - } - t.Logf("%s value not found for wallet %s in %v", CODE, wallet, acc) - return 0 -} - -// getEnv returns an environment variable or the fallback -func getEnv(key, fallback string) string { - if value, ok := os.LookupEnv(key); ok { - return value - } - return fallback -} diff --git a/token-sdk/e2e/go.mod b/token-sdk/e2e/go.mod deleted file mode 100644 index d70b4780..00000000 --- a/token-sdk/e2e/go.mod +++ /dev/null @@ -1,79 +0,0 @@ -module github.com/hyperledger/fabric-samples/token-sdk/e2e - -go 1.22.0 - -require ( - github.com/deepmap/oapi-codegen v1.16.3 - github.com/stretchr/testify v1.9.0 -) - -require ( - github.com/BurntSushi/toml v1.3.2 // indirect - github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect - github.com/CloudyKit/jet/v6 v6.2.0 // indirect - github.com/Joker/jade v1.1.3 // indirect - github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect - github.com/andybalholm/brotli v1.0.5 // indirect - github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/aymerick/douceur v0.2.0 // indirect - github.com/bytedance/sonic v1.9.1 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fatih/structs v1.1.0 // indirect - github.com/flosch/pongo2/v4 v4.0.2 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-gonic/gin v1.9.1 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12 // indirect - github.com/google/uuid v1.3.1 // indirect - github.com/gorilla/css v1.0.0 // indirect - github.com/iris-contrib/schema v0.0.6 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/kataras/blocks v0.0.7 // indirect - github.com/kataras/golog v0.1.9 // indirect - github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 // indirect - github.com/kataras/pio v0.0.12 // indirect - github.com/kataras/sitemap v0.0.6 // indirect - github.com/kataras/tunnel v0.0.4 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/klauspost/cpuid/v2 v2.2.4 // indirect - github.com/labstack/echo/v4 v4.11.1 // indirect - github.com/labstack/gommon v0.4.0 // indirect - github.com/leodido/go-urn v1.2.4 // indirect - github.com/mailgun/raymond/v2 v2.0.48 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/microcosm-cc/bluemonday v1.0.25 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/schollz/closestmatch v2.1.0+incompatible // indirect - github.com/sirupsen/logrus v1.8.1 // indirect - github.com/tdewolff/minify/v2 v2.12.9 // indirect - github.com/tdewolff/parse/v2 v2.6.8 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.2 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect - github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/yosssi/ace v0.0.5 // indirect - golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.13.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sys v0.12.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/token-sdk/e2e/go.sum b/token-sdk/e2e/go.sum deleted file mode 100644 index 36321c45..00000000 --- a/token-sdk/e2e/go.sum +++ /dev/null @@ -1,258 +0,0 @@ -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME= -github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4= -github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk= -github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= -github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 h1:KkH3I3sJuOLP3TjA/dfr4NAY8bghDwnXiU7cTKxQqo0= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= -github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= -github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= -github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= -github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deepmap/oapi-codegen v1.16.3 h1:GT9G86SbQtT1r8ZB+4Cybi9VGdu1P5ieNvNdEoCSbrA= -github.com/deepmap/oapi-codegen v1.16.3/go.mod h1:JD6ErqeX0nYnhdciLc61Konj3NBASREMlkHOgHn8WAM= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= -github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12 h1:uK3X/2mt4tbSGoHvbLBHUny7CKiuwUip3MArtukol4E= -github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= -github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/iris-contrib/httpexpect/v2 v2.15.2 h1:T9THsdP1woyAqKHwjkEsbCnMefsAFvk8iJJKokcJ3Go= -github.com/iris-contrib/httpexpect/v2 v2.15.2/go.mod h1:JLDgIqnFy5loDSUv1OA2j0mb6p/rDhiCqigP22Uq9xE= -github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw= -github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/kataras/blocks v0.0.7 h1:cF3RDY/vxnSRezc7vLFlQFTYXG/yAr1o7WImJuZbzC4= -github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= -github.com/kataras/golog v0.1.9 h1:vLvSDpP7kihFGKFAvBSofYo7qZNULYSHOH2D7rPTKJk= -github.com/kataras/golog v0.1.9/go.mod h1:jlpk/bOaYCyqDqH18pgDHdaJab72yBE6i0O3s30hpWY= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 h1:Vx8kDVhO2qepK8w44lBtp+RzN3ld743i+LYPzODJSpQ= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9/go.mod h1:ldkoR3iXABBeqlTibQ3MYaviA1oSlPvim6f55biwBh4= -github.com/kataras/pio v0.0.12 h1:o52SfVYauS3J5X08fNjlGS5arXHjW/ItLkyLcKjoH6w= -github.com/kataras/pio v0.0.12/go.mod h1:ODK/8XBhhQ5WqrAhKy+9lTPS7sBf6O3KcLhc9klfRcY= -github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= -github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= -github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= -github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4= -github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ= -github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw= -github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= -github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= -github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= -github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= -github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= -github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tdewolff/minify/v2 v2.12.9 h1:dvn5MtmuQ/DFMwqf5j8QhEVpPX6fi3WGImhv8RUB4zA= -github.com/tdewolff/minify/v2 v2.12.9/go.mod h1:qOqdlDfL+7v0/fyymB+OP497nIxJYSvX4MQWA8OoiXU= -github.com/tdewolff/parse/v2 v2.6.8 h1:mhNZXYCx//xG7Yq2e/kVLNZw4YfYmeHbhx+Zc0OvFMA= -github.com/tdewolff/parse/v2 v2.6.8/go.mod h1:XHDhaU6IBgsryfdnpzUXBlT6leW/l25yrFBTEb4eIyM= -github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0= -github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA= -github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= -github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs= -moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/token-sdk/e2e/oapi-client.yaml b/token-sdk/e2e/oapi-client.yaml deleted file mode 100644 index f6dd43b3..00000000 --- a/token-sdk/e2e/oapi-client.yaml +++ /dev/null @@ -1,5 +0,0 @@ -package: e2e -generate: - client: true - models: true -output: e2e/client.gen.go diff --git a/token-sdk/explorer/.env b/token-sdk/explorer/.env deleted file mode 100644 index 9150c094..00000000 --- a/token-sdk/explorer/.env +++ /dev/null @@ -1,4 +0,0 @@ -PORT=8081 -EXPLORER_CONFIG_FILE_PATH=./config.json -EXPLORER_PROFILE_DIR_PATH=./connection-profile -FABRIC_CRYPTO_PATH=../../test-network/organizations \ No newline at end of file diff --git a/token-sdk/explorer/config.json b/token-sdk/explorer/config.json deleted file mode 100644 index f99d37b5..00000000 --- a/token-sdk/explorer/config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "network-configs": { - "test-network": { - "name": "Test Network", - "profile": "./connection-profile/test-network.json" - } - }, - "license": "Apache-2.0" -} diff --git a/token-sdk/explorer/connection-profile/test-network.json b/token-sdk/explorer/connection-profile/test-network.json deleted file mode 100644 index 44eb3dc9..00000000 --- a/token-sdk/explorer/connection-profile/test-network.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "test-network", - "version": "1.0.0", - "client": { - "tlsEnable": true, - "adminCredential": { - "id": "exploreradmin", - "password": "exploreradminpw" - }, - "enableAuthentication": true, - "organization": "Org1MSP", - "connection": { - "timeout": { - "peer": { - "endorser": "300" - }, - "orderer": "300" - } - } - }, - "channels": { - "mychannel": { - "peers": { - "peer0.org1.example.com": {} - } - } - }, - "organizations": { - "Org1MSP": { - "mspid": "Org1MSP", - "adminPrivateKey": { - "path": "/tmp/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/priv_sk" - }, - "peers": ["peer0.org1.example.com"], - "signedCert": { - "path": "/tmp/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/User1@org1.example.com-cert.pem" - } - } - }, - "peers": { - "peer0.org1.example.com": { - "tlsCACerts": { - "path": "/tmp/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" - }, - "url": "grpcs://peer0.org1.example.com:7051" - } - } -} diff --git a/token-sdk/explorer/docker-compose.yaml b/token-sdk/explorer/docker-compose.yaml deleted file mode 100644 index 1254cdba..00000000 --- a/token-sdk/explorer/docker-compose.yaml +++ /dev/null @@ -1,63 +0,0 @@ - -# SPDX-License-Identifier: Apache-2.0 - -# see https://github.com/hyperledger-labs/blockchain-explorer - -version: '2.1' - -volumes: - pgdata: - walletstore: - -networks: - test: - name: fabric_test - external: true - -services: - - explorerdb.mynetwork.com: - image: ghcr.io/hyperledger-labs/explorer-db:latest - container_name: explorerdb.mynetwork.com - hostname: explorerdb.mynetwork.com - environment: - - DATABASE_DATABASE=fabricexplorer - - DATABASE_USERNAME=hppoc - - DATABASE_PASSWORD=password - healthcheck: - test: "pg_isready -h localhost -p 5432 -q -U postgres" - interval: 30s - timeout: 10s - retries: 5 - volumes: - - pgdata:/var/lib/postgresql/data - networks: - - test - - explorer.mynetwork.com: - image: ghcr.io/hyperledger-labs/explorer:latest - container_name: explorer.mynetwork.com - hostname: explorer.mynetwork.com - environment: - - DATABASE_HOST=explorerdb.mynetwork.com - - DATABASE_DATABASE=fabricexplorer - - DATABASE_USERNAME=hppoc - - DATABASE_PASSWD=password - - LOG_LEVEL_APP=info - - LOG_LEVEL_DB=info - - LOG_LEVEL_CONSOLE=debug - - LOG_CONSOLE_STDOUT=true - - DISCOVERY_AS_LOCALHOST=false - - PORT=${PORT:-8080} - volumes: - - ${EXPLORER_CONFIG_FILE_PATH}:/opt/explorer/app/platform/fabric/config.json - - ${EXPLORER_PROFILE_DIR_PATH}:/opt/explorer/app/platform/fabric/connection-profile - - ${FABRIC_CRYPTO_PATH}:/tmp/crypto - - walletstore:/opt/explorer/wallet - ports: - - ${PORT:-8080}:${PORT:-8080} - depends_on: - explorerdb.mynetwork.com: - condition: service_healthy - networks: - - test diff --git a/token-sdk/go.work b/token-sdk/go.work deleted file mode 100644 index 684b6568..00000000 --- a/token-sdk/go.work +++ /dev/null @@ -1,8 +0,0 @@ -go 1.22.0 - -use ( - ./auditor - ./e2e - ./issuer - ./owner -) diff --git a/token-sdk/go.work.sum b/token-sdk/go.work.sum deleted file mode 100644 index 5f5e37ce..00000000 --- a/token-sdk/go.work.sum +++ /dev/null @@ -1,285 +0,0 @@ -cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= -cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= -cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= -cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= -cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= -cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= -cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= -cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= -cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= -cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= -cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= -cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= -cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= -cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= -cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= -cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= -cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= -cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= -cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= -cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= -cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= -cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= -cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= -cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= -cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= -cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= -cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= -cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= -cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= -cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= -cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= -cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= -cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= -cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= -cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= -cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= -cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= -cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= -cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= -cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= -cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= -cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= -cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= -cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= -cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= -cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= -cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= -cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= -cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= -cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= -cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= -cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= -cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= -cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= -cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= -cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= -cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= -cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= -cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= -cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= -cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= -cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= -cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= -cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= -cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= -cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= -cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= -cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= -cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= -cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= -cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= -cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= -cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= -cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= -cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= -cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= -cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= -cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= -cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= -cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= -cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= -cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= -cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= -cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= -cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= -cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= -cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= -cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= -cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= -cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= -cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= -cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= -cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= -cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= -cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= -cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= -cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= -cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= -cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= -cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= -cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= -cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= -cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= -cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= -cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= -cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= -cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= -cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= -cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= -cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= -cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= -cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= -cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= -cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= -cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= -cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= -cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= -github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/hcsshim v0.8.25/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= -github.com/VictoriaMetrics/fastcache v1.9.0/go.mod h1:otoTS3xu+6IzF/qByjqzjp3rTuzM3Qf0ScU1UTj97iU= -github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/bits-and-blooms/bitset v1.2.1 h1:M+/hrU9xlMp7t4TyTDQW97d3tRPVuKFC6zBEK16QnXY= -github.com/bits-and-blooms/bitset v1.2.1/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bluele/gcache v0.0.0-20190518031135-bc40bd653833/go.mod h1:8c4/i2VlovMO2gBnHGQPN5EJw+H0lx1u/5p+cgsXtCk= -github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= -github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= -github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U= -github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= -github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= -github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs= -github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= -github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= -github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/containerd/containerd v1.5.18/go.mod h1:7IN9MtIzTZH4WPEmD1gNH8bbTQXVX68yd3ZXxSHYCis= -github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= -github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= -github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= -github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= -github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v20.10.24+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= -github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fsouza/go-dockerclient v1.7.3/go.mod h1:8xfZB8o9SptLNJ13VoV5pMiRbZGWkU/Omu5VOu/KC9Y= -github.com/getkin/kin-openapi v0.118.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc= -github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-jose/go-jose/v3 v3.0.1-0.20221117193127-916db76e8214/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= -github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.3.0/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= -github.com/gofiber/fiber/v2 v2.49.1/go.mod h1:nPUeEBUeeYGgwbDm59Gp7vS8MDyScL6ezr/Np9A13WU= -github.com/google/tink/go v1.7.0/go.mod h1:GAUOd+QE3pgj9q8VKIGTCP33c/B7eb4NhxLcgTJZStM= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= -github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU= -github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/hyperledger/aries-framework-go/component/log v0.0.0-20230417184158-344a7f82c4c2/go.mod h1:CvYs4l8X2NrrF93weLOu5RTOIJeVdoZITtjEflyuTyM= -github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20230427134832-0c9969493bd3/go.mod h1:aSG2dWjYVzu2PVBtOqsYghaChA5+UUXnBbL+MfVceYQ= -github.com/hyperledger/aries-framework-go/spi v0.0.0-20230417184158-344a7f82c4c2/go.mod h1:oryUyWb23l/a3tAP9KW+GBbfcfqp9tZD4y5hSkFrkqI= -github.com/hyperledger/ursa-wrapper-go v0.3.1/go.mod h1:nPSAuMasIzSVciQo22PedBk4Opph6bJ6ia3ms7BH/mk= -github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= -github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= -github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= -github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= -github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= -github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek= -github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= -github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= -github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= -github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= -github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= -github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= -github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= -github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= -github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= -github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= -github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= -github.com/ipfs/go-unixfsnode v1.6.0/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= -github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d/go.mod h1:SH2pi/NgfGBsV/CGBAQPxMfghIgwzbh5lQ2N+6dNRI8= -github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= -github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kataras/jwt v0.1.10/go.mod h1:xkimAtDhU/aGlQqjwvgtg+VyuPwMiyZHaY8LJRh0mYo= -github.com/kataras/neffos v0.0.22/go.mod h1:IIJZcUDvwBxJGlDj942dqQgyznVKYDti91f8Ez+RRxE= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/libp2p/go-libp2p-routing-helpers v0.4.0/go.mod h1:dYEAgkVhqho3/YKxfOEGdFMIcWfAFNlZX8iAIihYA2E= -github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= -github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= -github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= -github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs= -github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mediocregopher/radix/v3 v3.8.1/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= -github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= -github.com/miracl/conflate v1.2.1/go.mod h1:F85f+vrE7SwfRoL31EpLZFa1sub0SDxzcwxDBxFvy7k= -github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7sxOougM= -github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt/v2 v2.5.0/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI= -github.com/nats-io/nats.go v1.28.0/go.mod h1:XpbWUlOElGwTYbMR7imivs7jJj9GtK7ypv321Wp6pjc= -github.com/nats-io/nkeys v0.4.4/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64= -github.com/oapi-codegen/testutil v1.0.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= -github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= -github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc= -github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= -github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= -github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= -github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= -github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M= -github.com/thedevsaddam/gojsonq v2.3.0+incompatible/go.mod h1:RBcQaITThgJAAYKH7FNp2onYodRz8URfsuEGpAch0NA= -github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= -github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= -github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb/go.mod h1:ikPs9bRWicNw3S7XpJ8sK/smGwU9WcSVU3dy9qahYBM= -github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= -github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= -github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU= -github.com/valyala/fasthttp v1.49.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/warpfork/go-testmark v0.11.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= -github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= -github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= -github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= -github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= -github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= -github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.etcd.io/etcd/pkg/v3 v3.5.1/go.mod h1:Qb9MvSx6rlo+Es8pOvkCQjGf7L8GA+NxrkRcyZ7eGXo= -go.etcd.io/etcd/raft/v3 v3.5.1/go.mod h1:WIlKzH/rjc54LDZ8SOa7GObrrdX3z96MkP1WDfODBeA= -go.etcd.io/etcd/server/v3 v3.5.1/go.mod h1:yBKYw++NWu6ciuWoKuL7UXgGKDP7ICBCuVQrIcYbPdw= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= -gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= diff --git a/token-sdk/issuer/conf/core.yaml b/token-sdk/issuer/conf/core.yaml deleted file mode 100644 index 7517e777..00000000 --- a/token-sdk/issuer/conf/core.yaml +++ /dev/null @@ -1,116 +0,0 @@ -logging: - spec: info - format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' - -# ------------------- FSC Node Configuration ------------------------- -# The FSC node is responsible for the peer to peer communication with other token services. -fsc: - identity: - cert: - file: /var/fsc/keys/issuer/fsc/msp/signcerts/cert.pem - key: - file: /var/fsc/keys/issuer/fsc/msp/keystore/priv_sk - tls: - enabled: false # TODO - p2p: - listenAddress: /ip4/0.0.0.0/tcp/9101 - # If empty, this is a P2P boostrap node. Otherwise, it contains the name of the FSC node that is a bootstrap node. - # The name of the FSC node that is a bootstrap node must be set under fsc.endpoint.resolvers - bootstrapNode: auditor - kvs: # key-value-store - persistence: - type: badger # badger or memory - opts: - path: /var/fsc/data/issuer/kvs - - # The endpoint section tells how to reach other FSC node in the network. - # For each node, the name, the domain, the identity of the node, and its addresses must be specified. - endpoint: - resolvers: - - name: auditor - identity: - id: auditor - path: /var/fsc/keys/auditor/fsc/msp/signcerts/cert.pem - addresses: - P2P: auditor.example.com:9001 - - name: owner1 - identity: - id: owner1 - path: /var/fsc/keys/owner1/fsc/msp/signcerts/cert.pem - addresses: - P2P: owner1.example.com:9201 - aliases: - - owner1 - - name: owner2 - identity: - id: owner2 - path: /var/fsc/keys/owner2/fsc/msp/signcerts/cert.pem - addresses: - P2P: owner2.example.com:9301 - aliases: - - owner2 - -# ------------------- Fabric Configuration ------------------------- -fabric: - enabled: true - mynetwork: - default: true - mspConfigPath: /var/fsc/keys/fabric/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp - defaultMSP: Org1MSP - msps: - - id: Org1MSP - mspType: bccsp - mspID: Org1MSP - path: /var/fsc/keys/fabric/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp - tls: - enabled: true - # If the keepalive values are too low, Fabric peers will complain with: ENHANCE_YOUR_CALM, debug data: "too_many_pings" - keepalive: - interval: 300s - timeout: 600s - # List of orderer nodes this node can connect to. There must be at least one orderer node. Others are discovered. - orderers: - - address: orderer.example.com:7050 - connectionTimeout: 10s - tlsEnabled: true - tlsRootCertFile: /var/fsc/keys/fabric/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt - serverNameOverride: orderer.example.com - # List of trusted peers this node can connect to. There must be at least one trusted peer. Others are discovered. - peers: - - address: peer0.org1.example.com:7051 - connectionTimeout: 10s - tlsEnabled: true - tlsRootCertFile: /var/fsc/keys/fabric/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt - serverNameOverride: peer0.org1.example.com - # Channel where the token chaincode is deployed - channels: - - name: mychannel - default: true - # Configuration of the vault used to store the RW sets assembled by this node - vault: - persistence: - type: badger - opts: - path: /var/fsc/data/issuer/vault - -# ------------------- Token SDK Configuration ------------------------- -token: - enabled: true - tms: - mytms: # unique name of this token management system - network: mynetwork # the name of the fabric network as configured above - channel: mychannel # the name of the network's channel this TMS refers to, if applicable - namespace: tokenchaincode # chaincode name - driver: zkatdlog # privacy preserving driver (zero knowledge asset transfer) - wallets: - issuers: - - id: issuer # the unique identifier of this wallet. Here is an example of use: `ttx.GetIssuerWallet(context, "issuer)` - default: true # is this the default issuer wallet - path: /var/fsc/keys/issuer/iss/msp - # Internal database to keep track of token transactions. - # It is used by auditors and token owners to track history - ttxdb: - persistence: - type: badger - opts: - path: /var/fsc/data/issuer/txdb diff --git a/token-sdk/issuer/go.mod b/token-sdk/issuer/go.mod deleted file mode 100644 index e817137d..00000000 --- a/token-sdk/issuer/go.mod +++ /dev/null @@ -1,245 +0,0 @@ -module github.com/hyperledger/fabric-samples/token-sdk/issuer - -go 1.22.0 - -replace github.com/ugorji/go v1.1.4 => github.com/ugorji/go/codec v1.2.9 - -require ( - github.com/deepmap/oapi-codegen v1.15.0 - github.com/getkin/kin-openapi v0.120.0 - github.com/hyperledger-labs/fabric-smart-client v0.3.0 - github.com/hyperledger-labs/fabric-token-sdk v0.3.0 - github.com/labstack/echo/v4 v4.11.1 - github.com/pkg/errors v0.9.1 -) - -require ( - github.com/BurntSushi/toml v1.3.2 // indirect - github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect - github.com/CloudyKit/jet/v6 v6.2.0 // indirect - github.com/IBM/idemix v0.0.2-0.20230831093709-b7a940638990 // indirect - github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20230831093709-b7a940638990 // indirect - github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20230831093709-b7a940638990 // indirect - github.com/IBM/idemix/bccsp/types v0.0.0-20230831093709-b7a940638990 // indirect - github.com/IBM/mathlib v0.0.3-0.20230831091907-c532c4d3b65c // indirect - github.com/Joker/jade v1.1.3 // indirect - github.com/ReneKroon/ttlcache/v2 v2.11.0 // indirect - github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect - github.com/ale-linux/aries-framework-go/component/kmscrypto v0.0.0-20230817163708-4b3de6d91874 // indirect - github.com/andybalholm/brotli v1.0.5 // indirect - github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/aymerick/douceur v0.2.0 // indirect - github.com/benbjohnson/clock v1.3.5 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/bytedance/sonic v1.9.1 // indirect - github.com/cenkalti/backoff/v4 v4.2.0 // indirect - github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/consensys/bavard v0.1.13 // indirect - github.com/consensys/gnark-crypto v0.9.1 // indirect - github.com/containerd/cgroups v1.1.0 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect - github.com/dgraph-io/badger/v3 v3.2103.2 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/elastic/gosigar v0.14.2 // indirect - github.com/fatih/structs v1.1.0 // indirect - github.com/flosch/pongo2/v4 v4.0.2 // indirect - github.com/flynn/noise v1.0.0 // indirect - github.com/francoispqt/gojay v1.2.13 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-gonic/gin v1.9.1 // indirect - github.com/go-kit/kit v0.10.0 // indirect - github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-logr/logr v1.2.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/swag v0.22.4 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/godbus/dbus/v5 v5.1.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang/glog v1.0.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12 // indirect - github.com/google/flatbuffers v1.12.1 // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect - github.com/google/uuid v1.3.1 // indirect - github.com/gorilla/css v1.0.0 // indirect - github.com/gorilla/mux v1.8.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-uuid v1.0.2 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/huin/goupnp v1.2.0 // indirect - github.com/hyperledger-labs/orion-sdk-go v0.2.5 // indirect - github.com/hyperledger-labs/orion-server v0.2.5 // indirect - github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.3-alpha.1 // indirect - github.com/hyperledger-labs/weaver-dlt-interoperability/sdks/fabric/go-sdk v1.2.3-alpha.1.0.20210812140206-37f430515b8c // indirect - github.com/hyperledger/fabric v1.4.0-rc1.0.20230401164317-bd8e24856939 // indirect - github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2 // indirect - github.com/hyperledger/fabric-chaincode-go v0.0.0-20220920210243-7bc6fa0dd58b // indirect - github.com/hyperledger/fabric-lib-go v1.0.0 // indirect - github.com/hyperledger/fabric-private-chaincode v0.0.0-20210907122433-d56466264e4d // indirect - github.com/hyperledger/fabric-protos-go v0.2.0 // indirect - github.com/invopop/yaml v0.2.0 // indirect - github.com/ipfs/boxo v0.8.0-rc1 // indirect - github.com/ipfs/go-cid v0.4.1 // indirect - github.com/ipfs/go-datastore v0.6.0 // indirect - github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-log v1.0.5 // indirect - github.com/ipfs/go-log/v2 v2.5.1 // indirect - github.com/ipld/go-ipld-prime v0.20.0 // indirect - github.com/iris-contrib/schema v0.0.6 // indirect - github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect - github.com/jbenet/goprocess v0.1.4 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/kataras/blocks v0.0.7 // indirect - github.com/kataras/golog v0.1.9 // indirect - github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 // indirect - github.com/kataras/pio v0.0.12 // indirect - github.com/kataras/sitemap v0.0.6 // indirect - github.com/kataras/tunnel v0.0.4 // indirect - github.com/kilic/bls12-381 v0.1.0 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect - github.com/koron/go-ssdp v0.0.4 // indirect - github.com/labstack/gommon v0.4.0 // indirect - github.com/leodido/go-urn v1.2.4 // indirect - github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p v0.31.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.22.0 // indirect - github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect - github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-msgio v0.3.0 // indirect - github.com/libp2p/go-nat v0.2.0 // indirect - github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.4.0 // indirect - github.com/libp2p/go-yamux/v4 v4.0.1 // indirect - github.com/magiconair/properties v1.8.5 // indirect - github.com/mailgun/raymond/v2 v2.0.48 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/microcosm-cc/bluemonday v1.0.25 // indirect - github.com/miekg/dns v1.1.55 // indirect - github.com/miekg/pkcs11 v1.1.1 // indirect - github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect - github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect - github.com/minio/sha256-simd v1.0.1 // indirect - github.com/mitchellh/mapstructure v1.4.3 // indirect - github.com/mmcloughlin/addchain v0.4.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/mr-tron/base58 v1.2.0 // indirect - github.com/multiformats/go-base32 v0.1.0 // indirect - github.com/multiformats/go-base36 v0.2.0 // indirect - github.com/multiformats/go-multiaddr v0.11.0 // indirect - github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect - github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect - github.com/multiformats/go-multibase v0.2.0 // indirect - github.com/multiformats/go-multicodec v0.9.0 // indirect - github.com/multiformats/go-multihash v0.2.3 // indirect - github.com/multiformats/go-multistream v0.4.1 // indirect - github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.11.0 // indirect - github.com/opencontainers/runtime-spec v1.1.0 // indirect - github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect - github.com/pelletier/go-toml v1.9.4 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect - github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.1 // indirect - github.com/quic-go/webtransport-go v0.5.3 // indirect - github.com/raulk/go-watchdog v1.3.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/schollz/closestmatch v2.1.0+incompatible // indirect - github.com/sirupsen/logrus v1.9.0 // indirect - github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/spf13/afero v1.6.0 // indirect - github.com/spf13/cast v1.4.1 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.10.1 // indirect - github.com/stretchr/testify v1.8.4 // indirect - github.com/subosito/gotenv v1.2.0 // indirect - github.com/sykesm/zap-logfmt v0.0.4 // indirect - github.com/tdewolff/minify/v2 v2.12.9 // indirect - github.com/tdewolff/parse/v2 v2.6.8 // indirect - github.com/test-go/testify v1.1.4 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.2 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect - github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - github.com/yosssi/ace v0.0.5 // indirect - go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.13.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.13.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.13.0 // indirect - go.opentelemetry.io/otel/sdk v1.13.0 // indirect - go.opentelemetry.io/otel/trace v1.14.0 // indirect - go.opentelemetry.io/proto/otlp v0.19.0 // indirect - go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.20.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.25.0 // indirect - golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.13.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.12.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.53.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.2.1 // indirect - rsc.io/tmplfunc v0.0.3 // indirect -) diff --git a/token-sdk/issuer/go.sum b/token-sdk/issuer/go.sum deleted file mode 100644 index 60388580..00000000 --- a/token-sdk/issuer/go.sum +++ /dev/null @@ -1,2020 +0,0 @@ -bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c/go.mod h1:hSVuE3qU7grINVSwrmzHfpg9k87ALBk+XaualNyUzI4= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= -cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -code.cloudfoundry.org/clock v1.0.0/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME= -github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4= -github.com/DATA-DOG/go-txdb v0.1.3/go.mod h1:DhAhxMXZpUJVGnT+p9IbzJoRKvlArO2pkHjnGX7o0n0= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= -github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= -github.com/IBM/idemix v0.0.2-0.20230831093709-b7a940638990 h1:hEZKSPmBJddcapbHqCSogIMTIzUXQhL/vTWzbngnRjw= -github.com/IBM/idemix v0.0.2-0.20230831093709-b7a940638990/go.mod h1:A9w6lDhpXujKBck1rcw6unxAzJtx+QsuT5qd1CS7BKc= -github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20230831093709-b7a940638990 h1:2h+Ou3S30pkBlkukOfprO5wGD4A13NBnyQx/gDQVzaQ= -github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20230831093709-b7a940638990/go.mod h1:sgvrLB3a8mKr4rX+aBDXPCZBgSRRmQxlyxA3jmwq/Sk= -github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20230831093709-b7a940638990 h1:crSJPccrt4hk0dqbmBUc+T1w91oTkauADD/UQvRRB10= -github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20230831093709-b7a940638990/go.mod h1:EPAfwEciT+Yke9xTooqJUcEuf2R8pmIA0QjPG6df1xM= -github.com/IBM/idemix/bccsp/types v0.0.0-20230831093709-b7a940638990 h1:UkW/eqL8hlqaGLLsY9oZsv1iwEMJOuNbAomK07C30/8= -github.com/IBM/idemix/bccsp/types v0.0.0-20230831093709-b7a940638990/go.mod h1:2lO6nmsoSH3WDJdat4kIicU+WTs4qDntGZkF8XdgHm8= -github.com/IBM/mathlib v0.0.3-0.20230831091907-c532c4d3b65c h1:QVrlfdfx7MslApfSdSLiLIOFmYlLhP6wY4LyRBVed4I= -github.com/IBM/mathlib v0.0.3-0.20230831091907-c532c4d3b65c/go.mod h1:k0NBSWMYVgaZ2keDuI8DSwdIEhUNhp8XnlVmm6Xwyuk= -github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk= -github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= -github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI= -github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= -github.com/ReneKroon/ttlcache/v2 v2.11.0 h1:OvlcYFYi941SBN3v9dsDcC2N8vRxyHcCmJb3Vl4QMoM= -github.com/ReneKroon/ttlcache/v2 v2.11.0/go.mod h1:mBxvsNY+BT8qLLd6CuAJubbKo6r0jh3nb5et22bbfGY= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 h1:KkH3I3sJuOLP3TjA/dfr4NAY8bghDwnXiU7cTKxQqo0= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/sarama v1.20.1/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/sarama v1.26.3 h1:wSN3FpDXLe3e2z47OzGii5VAK693oVkyHFwh240jWjg= -github.com/Shopify/sarama v1.26.3/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= -github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/ale-linux/aries-framework-go/component/kmscrypto v0.0.0-20230817163708-4b3de6d91874 h1:O08ZCyb1f7UeyOmTeItAw7eSZOlyM0fBnrPgaYgKEiA= -github.com/ale-linux/aries-framework-go/component/kmscrypto v0.0.0-20230817163708-4b3de6d91874/go.mod h1:4sHtFlGI84SVjaSW7u1pCfC0bjijd9ZeqbKptU/Qljs= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= -github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= -github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= -github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/badgerodon/peg v0.0.0-20130729175151-9e5f7f4d07ca/go.mod h1:TWe0N2hv5qvpLHT+K16gYcGBllld4h65dQ/5CNuirmk= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= -github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cayleygraph/cayley v0.7.7 h1:z+7xkAbg6bKiXJOtOkEG3zCm2K084sr/aGwFV7xcQNs= -github.com/cayleygraph/cayley v0.7.7/go.mod h1:VUd+PInYf94/VY41ePeFtFyP99BAs953kFT4N+6F7Ko= -github.com/cayleygraph/quad v1.1.0 h1:w1nXAmn+nz07+qlw89dke9LwWkYpeX+OcvfTvGQRBpM= -github.com/cayleygraph/quad v1.1.0/go.mod h1:maWODEekEhrO0mdc9h5n/oP7cH1h/OTgqQ2qWbuI9M4= -github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= -github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a/go.mod h1:rzgs2ZOiguV6/NpiDgADjRLPNyZlApIWxKpkT+X8SdY= -github.com/cloudflare/cfssl v1.4.1/go.mod h1:KManx/OJPb5QY+y0+o/898AMcM128sF0bURvoVUSjTo= -github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4= -github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= -github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.9.1 h1:mru55qKdWl3E035hAoh1jj9d7hVnYY5pfb6tmovSmII= -github.com/consensys/gnark-crypto v0.9.1/go.mod h1:a2DQL4+5ywF6safEeZFEPGRiiGbjzGFRUN2sg06VuU4= -github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= -github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a h1:W8b4lQ4tFF21aspRGoBuCNV6V2fFJBF+pm1J6OY8Lys= -github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cucumber/godog v0.8.0/go.mod h1:Cp3tEV1LRAyH/RuCThcxHS/+9ORZ+FMzPva2AZ5Ki+A= -github.com/cznic/mathutil v0.0.0-20170313102836-1447ad269d64/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= -github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= -github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= -github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= -github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/deepmap/oapi-codegen v1.15.0 h1:SQqViaeb4k2vMul8gx12oDOIadEtoRqTdLkxjzqtQ90= -github.com/deepmap/oapi-codegen v1.15.0/go.mod h1:a6KoHV7lMRwsPoEg2C6NDHiXYV3EQfiFocOlJ8dgJQE= -github.com/dennwc/base v1.0.0 h1:xlBzvBNRvkQ1LFI/jom7rr0vZsvYDKtvMM6lIpjFb3M= -github.com/dennwc/base v1.0.0/go.mod h1:zaTDIiAcg2oKW9XhjIaRc1kJVteCFXSSW6jwmCedUaI= -github.com/dennwc/graphql v0.0.0-20180603144102-12cfed44bc5d/go.mod h1:lg9KQn0BgRCSCGNpcGvJp/0Ljf1Yxk8TZq9HSYc43fk= -github.com/dgraph-io/badger v1.5.4/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= -github.com/dgraph-io/badger v1.5.5/go.mod h1:QgCntgIUPsjnp7cMLhUybJHb7iIoQWAHT6tF8ngCjWk= -github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= -github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= -github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= -github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-farm v0.0.0-20190416075124-e1214b5e05dc/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.1.4/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.7.3-0.20180412203414-a422774e593b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v0.7.3-0.20190309235953-33c3200e0d16/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v17.12.0-ce-rc1.0.20190628135806-70f67c6240bb+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dop251/goja v0.0.0-20190105122144-6d5bf35058fa/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= -github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/flimzy/diff v0.1.5/go.mod h1:lFJtC7SPsK0EroDmGTSrdtWKAxOk3rO+q+e04LL05Hs= -github.com/flimzy/diff v0.1.6/go.mod h1:lFJtC7SPsK0EroDmGTSrdtWKAxOk3rO+q+e04LL05Hs= -github.com/flimzy/kivik v1.8.1/go.mod h1:S2aPycbG0eDFll4wgXt9uacSNkXISPufutnc9sv+mdA= -github.com/flimzy/testy v0.1.16/go.mod h1:3szguN8NXqgq9bt9Gu8TQVj698PJWmyx/VY1frwwKrM= -github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= -github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= -github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= -github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= -github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/frankban/quicktest v1.9.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/fsouza/go-dockerclient v1.2.2/go.mod h1:KpcjM623fQYE9MZiTGzKhjfxXAV9wbyX2C1cyRHfhl0= -github.com/fsouza/go-dockerclient v1.4.1/go.mod h1:PUNHxbowDqRXfRgZqMz1OeGtbWC6VKyZvJ99hDjB0qs= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/getkin/kin-openapi v0.120.0 h1:MqJcNJFrMDFNc07iwE8iFC5eT2k/NPUFDIpNeiZv8Jg= -github.com/getkin/kin-openapi v0.120.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw= -github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-kivik/couchdb v1.8.1/go.mod h1:5XJRkAMpBlEVA4q0ktIZjUPYBjoBmRoiWvwUBzP3BOQ= -github.com/go-kivik/kivik v1.8.1/go.mod h1:nIuJ8z4ikBrVUSk3Ua8NoDqYKULPNjuddjqRvlSUyyQ= -github.com/go-kivik/kiviktest v1.1.2/go.mod h1:JdhVyzixoYhoIDUt6hRf1yAfYyaDa5/u9SDOindDkfQ= -github.com/go-kivik/pouchdb v1.3.5/go.mod h1:U+siUrqLCVxeMU3QjQTYIC3/F/e6EUKm+o5buJb7vpw= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= -github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.1 h1:OQl5ys5MBea7OGCdvPbBJWRgnhC/fGona6QKfvFeau8= -github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= -github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/logger v1.0.7 h1:LTLwWelETXDYyqF/ASf0nxaIcdEOIJNxRokPcfI/xbU= -github.com/gobuffalo/logger v1.0.7/go.mod h1:u40u6Bq3VVvaMcy5sRBclD8SXhBYPS0Qk95ubt+1xJM= -github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= -github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= -github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= -github.com/gobuffalo/packr/v2 v2.7.1 h1:n3CIW5T17T8v4GGK5sWXLVWJhCz7b5aNLSxW6gYim4o= -github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12 h1:uK3X/2mt4tbSGoHvbLBHUny7CKiuwUip3MArtukol4E= -github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= -github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/jsbuiltin v0.0.0-20180426082241-50091555e127/go.mod h1:7X1acUyFRf+oVFTU6SWw9mnb57Vxn+Nbh8iPbKg95hs= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= -github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= -github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.4.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= -github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4= -github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hidal-go/hidalgo v0.0.0-20190814174001-42e03f3b5eaa/go.mod h1:bPkrxDlroXxigw8BMWTEPTv4W5/rQwNgg2BECXsgyX0= -github.com/hidal-go/hidalgo v0.0.0-20201109092204-05749a6d73df h1:bvz3e467dv98bVHQ9F5QbGKtGvyQO3rPD8lwu6fZ/D4= -github.com/hidal-go/hidalgo v0.0.0-20201109092204-05749a6d73df/go.mod h1:bPkrxDlroXxigw8BMWTEPTv4W5/rQwNgg2BECXsgyX0= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/hyperledger-labs/fabric-smart-client v0.3.0 h1:CNSFdHfhlvAjD4OrOojvtsZBEN50sl6uSl3qXZhzX+o= -github.com/hyperledger-labs/fabric-smart-client v0.3.0/go.mod h1:ZmxAL+oOP3B/HEu+z9a69+PwfWKfUiMsSBpwdPwlh2g= -github.com/hyperledger-labs/fabric-token-sdk v0.3.0 h1:YE1NMmf1o8oEb4j3XI3CrtAd+bpHJdTY3rY1RqfYR28= -github.com/hyperledger-labs/fabric-token-sdk v0.3.0/go.mod h1:NcyBbgCtVohGdui/yMDirJ9tk0EolWD0WVLSk5a1A7I= -github.com/hyperledger-labs/orion-sdk-go v0.2.5 h1:HFGRTuMZgzo9EtyJeFAhVSlbrj6x3jtY0aDcghdjzRE= -github.com/hyperledger-labs/orion-sdk-go v0.2.5/go.mod h1:At8hiFATfkDXQ4AFLVbaTiC9GDhVDo8aN/supb1KBb4= -github.com/hyperledger-labs/orion-server v0.2.5 h1:aFudmB9SAnsT5v8jhazkuszEu0pdJNFqaYZF2GpvAuI= -github.com/hyperledger-labs/orion-server v0.2.5/go.mod h1:8kXVAU1wvFYGbFL1qmXwMi2i8gKV2smOdp1F1kq0HMk= -github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.3-alpha.1 h1:vBvo0PNm82ht7wpBjlYY4ZHxV3YprCfdVd3T4JG9vBw= -github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.3-alpha.1/go.mod h1:POCGO/RK9YDfgdhuyqjoD9tRNtWfK7Rh5AYYmsb1Chc= -github.com/hyperledger-labs/weaver-dlt-interoperability/sdks/fabric/go-sdk v1.2.3-alpha.1.0.20210812140206-37f430515b8c h1:pKr8VnHlduEgdInwLWykYAw+lpUizjQJaJ8I5fVoRUo= -github.com/hyperledger-labs/weaver-dlt-interoperability/sdks/fabric/go-sdk v1.2.3-alpha.1.0.20210812140206-37f430515b8c/go.mod h1:si2XAWZclHXC359OyYMpNHfonf2P7P2nzABdCA8mPqs= -github.com/hyperledger/fabric v1.4.0-rc1.0.20201118191903-ec81f3e74fa1/go.mod h1:ppiyrJ+sUSk/rAX9cTd8xwAwSQ7chEbOQMAqtQ3pLG4= -github.com/hyperledger/fabric v1.4.0-rc1.0.20230401164317-bd8e24856939 h1:+XwAnpbvmxEeRD1yT+gd77643Y1QQUv0B2HUr4CRNWE= -github.com/hyperledger/fabric v1.4.0-rc1.0.20230401164317-bd8e24856939/go.mod h1:H7BI2gsTl4fW9ARtYG7UOGjwecXHSReVaIz4p2xqUB8= -github.com/hyperledger/fabric-amcl v0.0.0-20200128223036-d1aa2665426a/go.mod h1:X+DIyUsaTmalOpmpQfIvFZjKHQedrURQ5t4YqquX7lE= -github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2 h1:B1Nt8hKb//KvgGRprk0h1t4lCnwhE9/ryb1WqfZbV+M= -github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2/go.mod h1:X+DIyUsaTmalOpmpQfIvFZjKHQedrURQ5t4YqquX7lE= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20190823162523-04390e015b85/go.mod h1:HZK6PKLWrvdD/t0oSLiyaRaUM6fZ7qjJuOlb0zrn0mo= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20200128192331-2d899240a7ed/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20201119163726-f8ef75b17719/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20220920210243-7bc6fa0dd58b h1:MGT5rdajc4zbsbU7yMzkLJmsiRwJk5gBX5OdpU117Bg= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20220920210243-7bc6fa0dd58b/go.mod h1:OxME3M0bbgoWYHpXIVMzpbXgFqrTZnFmlH0Cpml54m0= -github.com/hyperledger/fabric-config v0.0.5/go.mod h1:YpITBI/+ZayA3XWY5lF302K7PAsFYjEEPM/zr3hegA8= -github.com/hyperledger/fabric-config v0.0.7/go.mod h1:aeDZ0moG/qKvwLjddcqYr8+58/oNaJy3HE0tI01546c= -github.com/hyperledger/fabric-config v0.1.0 h1:TsR3y5xEoUmXWfp8tcDycjJhVvXEHiV5kfZIxuIte08= -github.com/hyperledger/fabric-config v0.1.0/go.mod h1:aeDZ0moG/qKvwLjddcqYr8+58/oNaJy3HE0tI01546c= -github.com/hyperledger/fabric-contract-api-go v1.1.1/go.mod h1:+39cWxbh5py3NtXpRA63rAH7NzXyED+QJx1EZr0tJPo= -github.com/hyperledger/fabric-lib-go v1.0.0 h1:UL1w7c9LvHZUSkIvHTDGklxFv2kTeva1QI2emOVc324= -github.com/hyperledger/fabric-lib-go v1.0.0/go.mod h1:H362nMlunurmHwkYqR5uHL2UDWbQdbfz74n8kbCFsqc= -github.com/hyperledger/fabric-private-chaincode v0.0.0-20210907122433-d56466264e4d h1:LR34x2vhXUuXsETE9HBhz+eZM6nTuzPiWsF5jnNI550= -github.com/hyperledger/fabric-private-chaincode v0.0.0-20210907122433-d56466264e4d/go.mod h1:CBeWypXEi4LndnexZzEEqVIIqjdrUzUUHmmFcEcGRX4= -github.com/hyperledger/fabric-protos-go v0.0.0-20190821214336-621b908d5022/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20190919234611-2a87503ac7c9/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20200707132912-fee30f3ccd23/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20201028172056-a3136dde2354/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.2.0 h1:opaGKvsYYD0abMl6ErriNc+CEgLW+ELdKKQ0QyBL7/0= -github.com/hyperledger/fabric-protos-go v0.2.0/go.mod h1:WWnyWP40P2roPmmvxsUXSvVI/CF6vwY1K1UFidnKBys= -github.com/hyperledger/fabric-samples/chaincode/marbles02/go v0.0.0-20210428060230-9db8164f049b/go.mod h1:MvJbTLiLI/KBavKkC+OAqYU1IGvbY8WOu+Qzs/jncnA= -github.com/hyperledger/fabric-sdk-go v1.0.0/go.mod h1:qWE9Syfg1KbwNjtILk70bJLilnmCvllIYFCSY/pa1RU= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd/go.mod h1:3LVOLeyx9XVvwPgrt2be44XgSqndprz1G18rSk8KD84= -github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY= -github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= -github.com/ipfs/boxo v0.8.0-rc1 h1:DL5SDbBNSS9ZNsF+UhoQ39d05/wgoJ2k/T+y7JeWRaw= -github.com/ipfs/boxo v0.8.0-rc1/go.mod h1:EgDiNox/+W/+ySwEotRrHlvdmrhbSAB4p22ELg+ZsCc= -github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= -github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= -github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= -github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= -github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= -github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= -github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= -github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= -github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= -github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= -github.com/iris-contrib/httpexpect/v2 v2.15.2 h1:T9THsdP1woyAqKHwjkEsbCnMefsAFvk8iJJKokcJ3Go= -github.com/iris-contrib/httpexpect/v2 v2.15.2/go.mod h1:JLDgIqnFy5loDSUv1OA2j0mb6p/rDhiCqigP22Uq9xE= -github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw= -github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= -github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= -github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= -github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= -github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= -github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= -github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= -github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= -github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548/go.mod h1:hGT6jSUVzF6no3QaDSMLGLEHtHSBSefs+MgcDWnmhmo= -github.com/jmoiron/sqlx v0.0.0-20180124204410-05cef0741ade/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU= -github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/kataras/blocks v0.0.7 h1:cF3RDY/vxnSRezc7vLFlQFTYXG/yAr1o7WImJuZbzC4= -github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= -github.com/kataras/golog v0.1.9 h1:vLvSDpP7kihFGKFAvBSofYo7qZNULYSHOH2D7rPTKJk= -github.com/kataras/golog v0.1.9/go.mod h1:jlpk/bOaYCyqDqH18pgDHdaJab72yBE6i0O3s30hpWY= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 h1:Vx8kDVhO2qepK8w44lBtp+RzN3ld743i+LYPzODJSpQ= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9/go.mod h1:ldkoR3iXABBeqlTibQ3MYaviA1oSlPvim6f55biwBh4= -github.com/kataras/pio v0.0.12 h1:o52SfVYauS3J5X08fNjlGS5arXHjW/ItLkyLcKjoH6w= -github.com/kataras/pio v0.0.12/go.mod h1:ODK/8XBhhQ5WqrAhKy+9lTPS7sBf6O3KcLhc9klfRcY= -github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= -github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= -github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= -github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= -github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= -github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= -github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= -github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.0.0/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28/go.mod h1:T/T7jsxVqf9k/zYOqbgNAsANsjxTd1Yq3htjDhQ1H0c= -github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4= -github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ= -github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lib/pq v0.0.0-20180201184707-88edab080323/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= -github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= -github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= -github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= -github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= -github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= -github.com/libp2p/go-libp2p-kad-dht v0.22.0 h1:cW2nGgG0hztDM42tOPyC5cVflD7EzLaHM0/Kjol6Wio= -github.com/libp2p/go-libp2p-kad-dht v0.22.0/go.mod h1:hareSo3Z/GJ7nUWPMj7XhD/56a7+rRltYCWwCuy3FQk= -github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= -github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= -github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= -github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= -github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= -github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= -github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= -github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= -github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= -github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= -github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= -github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= -github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/linkeddata/gojsonld v0.0.0-20170418210642-4f5db6791326/go.mod h1:nfqkuSNlsk1bvti/oa7TThx4KmRMBmSxf3okHI9wp3E= -github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw= -github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= -github.com/mailru/easyjson v0.0.0-20180730094502-03f2033d19d5/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= -github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/matttproud/golang_protobuf_extensions v1.0.0/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/maxbrunsfeld/counterfeiter/v6 v6.3.0/go.mod h1:fcEyUyXZXoV4Abw8DX0t7wyL8mCDxXyU4iAFZfT3IHw= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= -github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= -github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= -github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= -github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= -github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= -github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= -github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= -github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= -github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= -github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= -github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= -github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= -github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= -github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= -github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= -github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= -github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= -github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= -github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= -github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= -github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= -github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= -github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= -github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= -github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= -github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= -github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= -github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= -github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= -github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= -github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= -github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= -github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= -github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= -github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= -github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc8/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= -github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.0.0/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= -github.com/otiai10/copy v1.5.1 h1:a/cs2E1/1V0az8K5nblbl+ymEa4E11AfaOLMar8V34w= -github.com/otiai10/copy v1.5.1/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= -github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= -github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= -github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/peterh/liner v0.0.0-20170317030525-88609521dc4b/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.5.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.6.0+incompatible h1:Ix9yFKn1nSPBLFl/yZknTp8TU5G4Ps0JDmguYK6iH1A= -github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= -github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.0.0-20180518154759-7600349dcfe1/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= -github.com/prometheus/procfs v0.0.0-20180612222113-7d6f385de8be/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= -github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= -github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= -github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= -github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= -github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= -github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= -github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= -github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= -github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.3.1/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.1.1/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= -github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk= -github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU= -github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/sykesm/zap-logfmt v0.0.2/go.mod h1:TerDJT124HaO8UTpZ2wJCipJRAKQ9XONM1mzUabIh6M= -github.com/sykesm/zap-logfmt v0.0.4 h1:U2WzRvmIWG1wDLCFY3sz8UeEmsdHQjHFNlIdmroVFaI= -github.com/sykesm/zap-logfmt v0.0.4/go.mod h1:AuBd9xQjAe3URrWT1BBDk2v2onAZHkZkWRMiYZXiZWA= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/syndtr/goleveldb v1.0.1-0.20190625010220-02440ea7a285/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/tdewolff/minify/v2 v2.12.9 h1:dvn5MtmuQ/DFMwqf5j8QhEVpPX6fi3WGImhv8RUB4zA= -github.com/tdewolff/minify/v2 v2.12.9/go.mod h1:qOqdlDfL+7v0/fyymB+OP497nIxJYSvX4MQWA8OoiXU= -github.com/tdewolff/parse/v2 v2.6.8 h1:mhNZXYCx//xG7Yq2e/kVLNZw4YfYmeHbhx+Zc0OvFMA= -github.com/tdewolff/parse/v2 v2.6.8/go.mod h1:XHDhaU6IBgsryfdnpzUXBlT6leW/l25yrFBTEb4eIyM= -github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0= -github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= -github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0= -github.com/tedsuo/ifrit v0.0.0-20220120221754-dd274de71113 h1:PnxSSxsUvOqMh7nslHscii/GV/Y9ZflmkZ2oEEEIGj4= -github.com/tedsuo/ifrit v0.0.0-20220120221754-dd274de71113/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0= -github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= -github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/tylertreat/BoomFilters v0.0.0-20181028192813-611b3dbe80e8 h1:7X4KYG3guI2mPQGxm/ZNNsiu4BjKnef0KG0TblMC+Z8= -github.com/tylertreat/BoomFilters v0.0.0-20181028192813-611b3dbe80e8/go.mod h1:OYRfF6eb5wY9VRFkXJH8FFBi3plw2v+giaIu7P054pM= -github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/urfave/cli v1.18.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= -github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= -github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= -github.com/weppos/publicsuffix-go v0.5.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA= -github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= -github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= -github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= -github.com/zmap/zcrypto v0.0.0-20190729165852-9051775e6a2e/go.mod h1:w7kd3qXHh8FNaczNjslXqvFQiv5mMWRXlL9klTUAHc8= -github.com/zmap/zlint v0.0.0-20190806154020-fd021b4cfbeb/go.mod h1:29UiAJNsiVdvTBFCJW8e3q6dcDbOoPkhMgttOSCIMMY= -go.etcd.io/bbolt v1.3.1-etcd.7/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd v0.5.0-alpha.5.0.20181228115726-23731bf9ba55/go.mod h1:weASp41xM3dk0YHg1s/W8ecdGP5G4teSTMBPpYAaUgA= -go.etcd.io/etcd v0.5.0-alpha.5.0.20210226220824-aa7126864d82 h1:RCaUKN0yRYKT2JzV9kH4u+D6l9VWcJMQ449QKRriFc8= -go.etcd.io/etcd v0.5.0-alpha.5.0.20210226220824-aa7126864d82/go.mod h1:WWRiAtnzDdtuCMxtFwME/Knea11a6fJgJkwtC1QSc/k= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= -go.mongodb.org/mongo-driver v1.0.4/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= -go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.13.0 h1:pa05sNT/P8OsIQ8mPZKTIyiBuzS/xDGLVx+DCt0y6Vs= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.13.0/go.mod h1:rqbht/LlhVBgn5+k3M5QK96K5Xb0DvXpMJ5SFQpY6uw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.13.0 h1:Any/nVxaoMq1T2w0W85d6w5COlLuCCgOYKQhJJWEMwQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.13.0/go.mod h1:46vAP6RWfNn7EKov73l5KBFlNxz8kYlxR1woU+bJ4ZY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.13.0 h1:Ntu7izEOIRHEgQNjbGc7j3eNtYMAiZfElJJ4JiiRDH4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.13.0/go.mod h1:wZ9SAjm2sjw3vStBhlCfMZWZusyOQrwrHOFo00jyMC4= -go.opentelemetry.io/otel/sdk v1.13.0 h1:BHib5g8MvdqS65yo2vV1s6Le42Hm6rrw08qU6yz5JaM= -go.opentelemetry.io/otel/sdk v1.13.0/go.mod h1:YLKPx5+6Vx/o1TCUYYs+bpymtkmazOMT6zoRrC7AQ7I= -go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= -go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= -go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= -go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.12.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= -golang.org/x/crypto v0.0.0-20180608092829-8ac0e0d97ce4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201026091529-146b70c837a4/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190614160838-b47fdc937951/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191009170203-06d7bd2c5f4f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200819091447-39769834ee22/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200131233409-575de47986ce/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180608181217-32ee49c4dd80/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= -gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg= -gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= -gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= -gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= -gopkg.in/olivere/elastic.v5 v5.0.80/go.mod h1:uhHoB4o3bvX5sorxBU29rPcmBQdV2Qfg0FBrx5D6pV0= -gopkg.in/olivere/elastic.v5 v5.0.81/go.mod h1:uhHoB4o3bvX5sorxBU29rPcmBQdV2Qfg0FBrx5D6pV0= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= -lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs= -moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= -rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/token-sdk/issuer/main.go b/token-sdk/issuer/main.go deleted file mode 100644 index 67c32086..00000000 --- a/token-sdk/issuer/main.go +++ /dev/null @@ -1,108 +0,0 @@ -package main - -import ( - "net/http" - "os" - "os/signal" - "syscall" - - "github.com/hyperledger/fabric-samples/token-sdk/issuer/routes" - "github.com/hyperledger/fabric-samples/token-sdk/issuer/service" - - "github.com/hyperledger-labs/fabric-smart-client/pkg/api" - "github.com/hyperledger-labs/fabric-smart-client/pkg/node" - fabric "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/sdk" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/flogging" - tokensdk "github.com/hyperledger-labs/fabric-token-sdk/token/sdk" -) - -var logger = flogging.MustGetLogger("main") - -func main() { - dir := getEnv("CONF_DIR", "./conf") - port := getEnv("PORT", "9100") - - fsc := startFabricSmartClient(dir) - controller := routes.Controller{Service: service.TokenService{FSC: fsc}} - err := routes.StartWebServer(port, controller, logger) - if err != nil { - if err == http.ErrServerClosed { - logger.Infof("Webserver closing, exiting...", err.Error()) - fsc.Stop() - } else { - logger.Fatalf("echo error - %s", err.Error()) - fsc.Stop() - os.Exit(1) - } - } -} - -type Node interface { - api.ServiceProvider - Stop() -} - -func startFabricSmartClient(confDir string) Node { - logger.Infof("Initializing Fabric Smart Client and Token SDK...") - fsc := node.NewFromConfPath(confDir) - succeedOrPanic(fsc.InstallSDK(fabric.NewSDK(fsc))) - succeedOrPanic(fsc.InstallSDK(tokensdk.NewSDK(fsc))) - succeedOrPanic(fsc.Start()) - - // Stop gracefully - go handleSignals((map[os.Signal]func(){ - syscall.SIGINT: func() { - logger.Info("Stopping FSC node...") - fsc.Stop() - os.Exit(130) - }, - syscall.SIGTERM: func() { - logger.Info("Stopping FSC node...") - fsc.Stop() - os.Exit(143) - }, - syscall.SIGSTOP: func() { - logger.Info("Stopping FSC node...") - fsc.Stop() - os.Exit(145) - }, - syscall.SIGHUP: func() { - logger.Info("Stopping FSC node...") - fsc.Stop() - os.Exit(129) - }, - })) - logger.Infof("FSC node is ready!") - - return fsc -} - -// getEnv returns an environment variable or the fallback -func getEnv(key, fallback string) string { - if value, ok := os.LookupEnv(key); ok { - return value - } - return fallback -} - -func succeedOrPanic(err error) { - if err != nil { - logger.Fatalf("Failed initializing Token SDK - %s", err.Error()) - os.Exit(1) - } -} - -func handleSignals(handlers map[os.Signal]func()) { - var signals []os.Signal - for sig := range handlers { - signals = append(signals, sig) - } - - signalChan := make(chan os.Signal, 1) - signal.Notify(signalChan, signals...) - - for sig := range signalChan { - logger.Infof("Received signal: %d (%s)", sig, sig) - handlers[sig]() - } -} diff --git a/token-sdk/issuer/oapi-server.yaml b/token-sdk/issuer/oapi-server.yaml deleted file mode 100644 index 33927fe9..00000000 --- a/token-sdk/issuer/oapi-server.yaml +++ /dev/null @@ -1,11 +0,0 @@ -package: routes -generate: - echo-server: true - strict-server: true - models: true - embedded-spec: true -output-options: - include-tags: - - operations - - issuer -output: issuer/routes/routes.gen.go diff --git a/token-sdk/issuer/routes/operations.go b/token-sdk/issuer/routes/operations.go deleted file mode 100644 index 04930b74..00000000 --- a/token-sdk/issuer/routes/operations.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package routes - -import ( - "context" -) - -// (GET /readyz) -func (c Controller) Readyz(ctx context.Context, request ReadyzRequestObject) (ReadyzResponseObject, error) { - // TODO: what defines readiness if the REST API is available after FSC? - return Readyz200JSONResponse{ - HealthSuccessJSONResponse: HealthSuccessJSONResponse{ - Message: "ok", - }, - }, nil -} - -// (GET /healthz) -func (c Controller) Healthz(ctx context.Context, request HealthzRequestObject) (HealthzResponseObject, error) { - // TODO: how to determine health? - return Healthz200JSONResponse{ - HealthSuccessJSONResponse: HealthSuccessJSONResponse{ - Message: "ok", - }, - }, nil -} diff --git a/token-sdk/issuer/routes/routes.gen.go b/token-sdk/issuer/routes/routes.gen.go deleted file mode 100644 index 648cd429..00000000 --- a/token-sdk/issuer/routes/routes.gen.go +++ /dev/null @@ -1,448 +0,0 @@ -// Package routes provides primitives to interact with the openapi HTTP API. -// -// Code generated by github.com/deepmap/oapi-codegen version v1.13.4 DO NOT EDIT. -package routes - -import ( - "bytes" - "compress/gzip" - "context" - "encoding/base64" - "encoding/json" - "fmt" - "net/http" - "net/url" - "path" - "strings" - - "github.com/deepmap/oapi-codegen/pkg/runtime" - "github.com/getkin/kin-openapi/openapi3" - "github.com/labstack/echo/v4" -) - -// Amount The amount to issue, transfer or redeem. -type Amount struct { - // Code the code of the token - Code string `json:"code"` - - // Value value in base units (usually cents) - Value int64 `json:"value"` -} - -// Counterparty The counterparty in a Transfer or Issuance transaction. -type Counterparty struct { - Account string `json:"account"` - - // Node The node that holds the recipient account - Node string `json:"node"` -} - -// Error defines model for Error. -type Error struct { - // Message High level error message - Message string `json:"message"` - - // Payload Details about the error - Payload string `json:"payload"` -} - -// TransferRequest Instructions to issue or transfer tokens to an account -type TransferRequest struct { - // Amount The amount to issue, transfer or redeem. - Amount Amount `json:"amount"` - - // Counterparty The counterparty in a Transfer or Issuance transaction. - Counterparty Counterparty `json:"counterparty"` - - // Message optional message that will be sent and stored with the transfer transaction - Message *string `json:"message,omitempty"` -} - -// ErrorResponse defines model for ErrorResponse. -type ErrorResponse = Error - -// HealthSuccess defines model for HealthSuccess. -type HealthSuccess struct { - // Message ok - Message string `json:"message"` -} - -// IssueSuccess defines model for IssueSuccess. -type IssueSuccess struct { - Message string `json:"message"` - - // Payload Transaction id - Payload string `json:"payload"` -} - -// IssueJSONRequestBody defines body for Issue for application/json ContentType. -type IssueJSONRequestBody = TransferRequest - -// ServerInterface represents all server handlers. -type ServerInterface interface { - - // (GET /healthz) - Healthz(ctx echo.Context) error - // Issue tokens to an account - // (POST /issuer/issue) - Issue(ctx echo.Context) error - - // (GET /readyz) - Readyz(ctx echo.Context) error -} - -// ServerInterfaceWrapper converts echo contexts to parameters. -type ServerInterfaceWrapper struct { - Handler ServerInterface -} - -// Healthz converts echo context to params. -func (w *ServerInterfaceWrapper) Healthz(ctx echo.Context) error { - var err error - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.Healthz(ctx) - return err -} - -// Issue converts echo context to params. -func (w *ServerInterfaceWrapper) Issue(ctx echo.Context) error { - var err error - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.Issue(ctx) - return err -} - -// Readyz converts echo context to params. -func (w *ServerInterfaceWrapper) Readyz(ctx echo.Context) error { - var err error - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.Readyz(ctx) - return err -} - -// This is a simple interface which specifies echo.Route addition functions which -// are present on both echo.Echo and echo.Group, since we want to allow using -// either of them for path registration -type EchoRouter interface { - CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route -} - -// RegisterHandlers adds each server route to the EchoRouter. -func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") -} - -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. -func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { - - wrapper := ServerInterfaceWrapper{ - Handler: si, - } - - router.GET(baseURL+"/healthz", wrapper.Healthz) - router.POST(baseURL+"/issuer/issue", wrapper.Issue) - router.GET(baseURL+"/readyz", wrapper.Readyz) - -} - -type ErrorResponseJSONResponse Error - -type HealthSuccessJSONResponse struct { - // Message ok - Message string `json:"message"` -} - -type IssueSuccessJSONResponse struct { - Message string `json:"message"` - - // Payload Transaction id - Payload string `json:"payload"` -} - -type HealthzRequestObject struct { -} - -type HealthzResponseObject interface { - VisitHealthzResponse(w http.ResponseWriter) error -} - -type Healthz200JSONResponse struct{ HealthSuccessJSONResponse } - -func (response Healthz200JSONResponse) VisitHealthzResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type Healthz503JSONResponse struct{ ErrorResponseJSONResponse } - -func (response Healthz503JSONResponse) VisitHealthzResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(503) - - return json.NewEncoder(w).Encode(response) -} - -type IssueRequestObject struct { - Body *IssueJSONRequestBody -} - -type IssueResponseObject interface { - VisitIssueResponse(w http.ResponseWriter) error -} - -type Issue200JSONResponse struct{ IssueSuccessJSONResponse } - -func (response Issue200JSONResponse) VisitIssueResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type IssuedefaultJSONResponse struct { - Body Error - StatusCode int -} - -func (response IssuedefaultJSONResponse) VisitIssueResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) -} - -type ReadyzRequestObject struct { -} - -type ReadyzResponseObject interface { - VisitReadyzResponse(w http.ResponseWriter) error -} - -type Readyz200JSONResponse struct{ HealthSuccessJSONResponse } - -func (response Readyz200JSONResponse) VisitReadyzResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type Readyz503JSONResponse struct{ ErrorResponseJSONResponse } - -func (response Readyz503JSONResponse) VisitReadyzResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(503) - - return json.NewEncoder(w).Encode(response) -} - -// StrictServerInterface represents all server handlers. -type StrictServerInterface interface { - - // (GET /healthz) - Healthz(ctx context.Context, request HealthzRequestObject) (HealthzResponseObject, error) - // Issue tokens to an account - // (POST /issuer/issue) - Issue(ctx context.Context, request IssueRequestObject) (IssueResponseObject, error) - - // (GET /readyz) - Readyz(ctx context.Context, request ReadyzRequestObject) (ReadyzResponseObject, error) -} - -type StrictHandlerFunc = runtime.StrictEchoHandlerFunc -type StrictMiddlewareFunc = runtime.StrictEchoMiddlewareFunc - -func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { - return &strictHandler{ssi: ssi, middlewares: middlewares} -} - -type strictHandler struct { - ssi StrictServerInterface - middlewares []StrictMiddlewareFunc -} - -// Healthz operation middleware -func (sh *strictHandler) Healthz(ctx echo.Context) error { - var request HealthzRequestObject - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.Healthz(ctx.Request().Context(), request.(HealthzRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "Healthz") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(HealthzResponseObject); ok { - return validResponse.VisitHealthzResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// Issue operation middleware -func (sh *strictHandler) Issue(ctx echo.Context) error { - var request IssueRequestObject - - var body IssueJSONRequestBody - if err := ctx.Bind(&body); err != nil { - return err - } - request.Body = &body - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.Issue(ctx.Request().Context(), request.(IssueRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "Issue") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(IssueResponseObject); ok { - return validResponse.VisitIssueResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// Readyz operation middleware -func (sh *strictHandler) Readyz(ctx echo.Context) error { - var request ReadyzRequestObject - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.Readyz(ctx.Request().Context(), request.(ReadyzRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "Readyz") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(ReadyzResponseObject); ok { - return validResponse.VisitReadyzResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// Base64 encoded, gzipped, json marshaled Swagger object -var swaggerSpec = []string{ - - "H4sIAAAAAAAC/9RWQW/jNhP9K8R832EXICIlaQtUt912gQS9FNkUKLrNYUyNLW4oUktSTt1A/70gKcu2", - "LDvxNkCzJ1sSOXxv5s3jPIIwdWM0ae+geARLrjHaUXz4YK2xN/2b8EIY7Un78BebRkmBXhqdfXZGh3dO", - "VFRj+Pd/S3Mo4H/ZJnqWvrosRoWu6ziU5ISVTQgCRTqOrRFAx+GKUPnqYysEOXcSAPoL60ZF0DU5hwuC", - "Asx9CNpY05D1MnEcvj6O0Jh74OBXTdjovJV6AQGypS+ttFRC8WnYezcsNLPPJPwUuZ7EDr1r51r6GnYH", - "KYzwcmhwpQyW+/RuLWqHIjwxWT6b6ibiKaSNZTQqbsd7PpHCu9q0ifgIZUUM4zfmDZMhX5z5AH1OlsWA", - "JVF9Bny74sKUAdeH325+Bw5LVC1BcZ7ne8VPC8Ohc2yV3+zZReErYmEpM3MW/ntzT3o/ZcNRYxbxNZOa", - "zdARa7X0jr1pXYtKrZgIzfEWOMyNrTFgkNr/8B1wqKWWdVtDkQ9HSe1pQXavPJHI+vz9ynD4KeSQbIPW", - "r6bTLLZWBKzIbrfyHKSKWlBKftLNKOsoRCoioJIiwNGpDuZBkz3fb71hw4Ru9VCZMc7whfkKPauMKl0s", - "iCUhG0nas3XMp/SsU8LWy6dSlnzqkJckPe+3RQEneMyVXFRM0ZIUG8d7fif/TB6lcgxnpvUxHTHWi7Q0", - "h7UIbuhLS26iRa+187aNgnBDkwbJDG0a2yV+Q71VoJEYBgc4dnf0PtFxECNBH9u1I/6OH/H8+AfVug5J", - "Zw9SKTYj5qLAdMmcN5ZK9iB9lfxgYLppjifTv0OAr/lPu6rUczOR+WSHoQ22TDEATK7YJ/6MvUdxTyWb", - "rRiyUgY8s9ZTyRSVC7L8T91YcmSXUi9YY+USxYq1Ljz9QdawX7R5iEvZr9aYuQt976UPHQG38YhgPWRd", - "gnV+lockm4Y0NhIKuDzLzy6jzHwVa51hW0pvbNaLwWWPsuziFUc2BILi05hsvwU4tFZBAZX3TZFlyghU", - "lXG++DHP8wwbmS3PM+juOn7gmGyrSO7lz6ziyPJ3CLygqOeg8niRXwd3uOq/891R6yLPD6l4WJftjkMd", - "h+/zy6d37U5xQU4eF4HuBpmDgN21dY12BQXckG+tduwiz5lMd17UhyAmHUsUYydlsdtt+omTiXETpKNS", - "IemfnH9vytWLjZNjg5oYQ6Ytat7qct+VNi3qbUvd15RpZ6yLYPrp4vRKHdZmSvwRaZ7vSHO7uhHfIVde", - "a6OPf/cfgAi6ijPD0LhPtGkYN6LvzczsCJiLbTB8HEWgVcbFMCXqI2Eu93p+F+xzzOwVIs7SpfGKge86", - "VLzh3sxaq9/2MoJDzE5w/NdYmPXV/o2U5nZq7jO+CrPJVodbwnJ1+J68SZ+/4WsyEozshaDGM4FKuSdc", - "/cSJg/87Q+avTEN9wsfx3vU3Ny5RKpwpikkdMqWxpq3U7eOZ3D9kqt/ePz9zd2xT9oBKkXebIPH1RIyP", - "vSrS5NSP6FhKHQS62b3RWXfX/RMAAP//uoh3hJoTAAA=", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode -func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) - if err != nil { - return nil, fmt.Errorf("error base64 decoding spec: %w", err) - } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } - var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } - - return buf.Bytes(), nil -} - -var rawSpec = decodeSpecCached() - -// a naive cached of a decoded swagger spec -func decodeSpecCached() func() ([]byte, error) { - data, err := decodeSpec() - return func() ([]byte, error) { - return data, err - } -} - -// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. -func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { - res := make(map[string]func() ([]byte, error)) - if len(pathToFile) > 0 { - res[pathToFile] = rawSpec - } - - return res -} - -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { - resolvePath := PathToRawSpec("") - - loader := openapi3.NewLoader() - loader.IsExternalRefsAllowed = true - loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { - pathToFile := url.String() - pathToFile = path.Clean(pathToFile) - getSpec, ok := resolvePath[pathToFile] - if !ok { - err1 := fmt.Errorf("path not found: %s", pathToFile) - return nil, err1 - } - return getSpec() - } - var specData []byte - specData, err = rawSpec() - if err != nil { - return - } - swagger, err = loader.LoadFromData(specData) - if err != nil { - return - } - return -} diff --git a/token-sdk/issuer/routes/routes.go b/token-sdk/issuer/routes/routes.go deleted file mode 100644 index 428113bf..00000000 --- a/token-sdk/issuer/routes/routes.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package routes - -import ( - "context" - "fmt" - - "github.com/hyperledger/fabric-samples/token-sdk/issuer/service" -) - -type Controller struct { - Service service.TokenService -} - -// Issue tokens to an account -// (POST /issue) -func (c Controller) Issue(ctx context.Context, request IssueRequestObject) (IssueResponseObject, error) { - code := request.Body.Amount.Code - value := uint64(request.Body.Amount.Value) - recipient := request.Body.Counterparty.Account - recipientNode := request.Body.Counterparty.Node - var message string - if request.Body.Message != nil { - message = *request.Body.Message - } - - txID, err := c.Service.Issue(code, value, recipient, recipientNode, message) - if err != nil { - return IssuedefaultJSONResponse{ - Body: Error{ - Message: "can't issue tokens", - Payload: err.Error(), - }, - StatusCode: 500, - }, nil - } - - return Issue200JSONResponse{ - IssueSuccessJSONResponse: IssueSuccessJSONResponse{ - Message: fmt.Sprintf("issued %d %s to %s on %s", value, code, recipient, recipientNode), - Payload: txID, - }, - }, nil -} diff --git a/token-sdk/issuer/routes/server.go b/token-sdk/issuer/routes/server.go deleted file mode 100644 index f3e639b2..00000000 --- a/token-sdk/issuer/routes/server.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package routes - -import ( - "fmt" - "log" - "os" - - oapimiddleware "github.com/deepmap/oapi-codegen/pkg/middleware" - "github.com/labstack/echo/v4" - middleware "github.com/labstack/echo/v4/middleware" -) - -type Logger interface { - Infof(template string, args ...interface{}) - Debugf(template string, args ...interface{}) - Warnf(template string, args ...interface{}) - Errorf(template string, args ...interface{}) - Fatalf(template string, args ...interface{}) -} - -// Start web server on the main thread. It exits the application if it fails setting up. -func StartWebServer(port string, routesImplementation StrictServerInterface, logger Logger) error { - e := echo.New() - baseURL := "/api/v1" - - handler := NewStrictHandler(routesImplementation, nil) - RegisterHandlersWithBaseURL(e, handler, baseURL) - - // Request validator - swagger, err := GetSwagger() - if err != nil { - log.Fatalf("Error loading swagger spec\n: %s", err) - os.Exit(1) - } - swagger.Servers = nil - e.Group(baseURL).Use(oapimiddleware.OapiRequestValidator(swagger)) - - e.Use(middleware.CORS()) - e.Use(middleware.RequestID()) - e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{ - Skipper: func(c echo.Context) bool { - return c.Path() == "/api/v1/healthz" || c.Path() == "/api/v1/readyz" - }, - LogRequestID: true, LogMethod: true, LogURI: true, LogStatus: true, LogLatency: true, - LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error { - if v.Status < 400 { - logger.Infof("%d %s %s %s [%s]", v.Status, v.Method, v.URI, v.Latency.String(), v.RequestID) - } else if v.Status >= 400 && v.Status < 500 { - logger.Warnf("%d %s %s %s [%s]", v.Status, v.Method, v.URI, v.Latency.String(), v.RequestID) - } else { - logger.Errorf("%d %s %s %s [%s]", v.Status, v.Method, v.URI, v.Latency.String(), v.RequestID) - } - return nil - }, - })) - - // Start REST API server - return e.Start(fmt.Sprintf("0.0.0.0:%s", port)) -} diff --git a/token-sdk/issuer/service/issue.go b/token-sdk/issuer/service/issue.go deleted file mode 100644 index f5a88d42..00000000 --- a/token-sdk/issuer/service/issue.go +++ /dev/null @@ -1,158 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package service - -import ( - "github.com/hyperledger-labs/fabric-smart-client/pkg/api" - viewregistry "github.com/hyperledger-labs/fabric-smart-client/platform/view" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/flogging" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx" - "github.com/pkg/errors" -) - -var logger = flogging.MustGetLogger("service") - -// SERVICE - -type TokenService struct { - FSC api.ServiceProvider -} - -// Issue issues an amount of tokens to a wallet. It connects to the other node, prepares the transaction, -// gets it approved by the auditor and sends it to the blockchain for endorsement and commit. -func (s TokenService) Issue(tokenType string, quantity uint64, recipient string, recipientNode string, message string) (txID string, err error) { - logger.Infof("going to issue %d %s to [%s] on [%s] with message [%s]", quantity, tokenType, recipient, recipientNode, message) - res, err := viewregistry.GetManager(s.FSC).InitiateView(&IssueCashView{ - IssueCash: &IssueCash{ - TokenType: tokenType, - Quantity: quantity, - Recipient: recipient, - RecipientNode: recipientNode, - Message: message, - }, - }) - if err != nil { - logger.Errorf("error issuing: %s", err.Error()) - return - } - txID, ok := res.(string) - if !ok { - return "", errors.New("cannot parse issue response") - } - logger.Infof("issued %d %s to [%s] on [%s] with message [%s]. ID: [%s]", quantity, tokenType, recipient, recipientNode, message, txID) - return -} - -// VIEW - -// IssueCash contains the input information to issue a token -type IssueCash struct { - // TokenType is the type of token to issue - TokenType string - // Quantity represent the number of units of a certain token type stored in the token - Quantity uint64 - // Recipient is an identifier of the recipient identity - Recipient string - // RecipientNode is the identifier of the node of the recipient - RecipientNode string - // Message is the message that will be visible to the recipient and the auditor - Message string -} - -type IssueCashView struct { - *IssueCash -} - -func (v *IssueCashView) Call(context view.Context) (interface{}, error) { - // Is the wallet on our node? - // tms := token.GetManagementService(context) - // if w := tms.WalletManager().OwnerWalletByIdentity(view.Identity(v.Recipient)); w != nil { - // logger.Infof("%s", v.Recipient) - // } - - node := view.Identity(v.RecipientNode) - rec := view.Identity(v.Recipient) - eps := viewregistry.GetEndpointService(context) - if !eps.IsBoundTo(node, rec) { - logger.Infof("binding [%s] to node [%s]", v.Recipient, v.RecipientNode) - eps.Bind(node, rec) // TODO: it doesn't forget a wrong binding - } - // // Debug information - // epr, err := eps.Endpoint(rec) - // if err != nil { - // logger.Errorf(err.Error()) - // } - // logger.Infof("recipient node: %s", epr["P2P"]) - - // As a first step operation, the issuer contacts the recipient's FSC node - // to ask for the identity to use to assign ownership of the freshly created token. - // Notice that, this step would not be required if the issuer knew already which - // identity the recipient wants to use. - logger.Infof("requesting [%s] identity from [%s]", v.Recipient, v.RecipientNode) - recipient, err := ttx.RequestRecipientIdentity(context, rec) - if err != nil { - return "", errors.Wrapf(err, "failed getting recipient identity from %s", v.RecipientNode) - } - - // Prepare the transaction and specify the auditor that will approve it. - logger.Debug("getting identity of auditor") - auditor := viewregistry.GetIdentityProvider(context).Identity("auditor") - if auditor == nil { - return "", errors.New("auditor identity not found") - } - tx, err := ttx.NewTransaction(context, nil, ttx.WithAuditor(auditor)) - if err != nil { - return "", errors.Wrap(err, "failed creating transaction") - } - - // You can set any metadata you want. It is shared with the recipient and - // auditor but not committed to the ledger. We used 'message' here to let - // the user share messages that will be shown in the transaction history. - if v.Message != "" { - tx.SetApplicationMetadata("message", []byte(v.Message)) - } - - // Get issuer wallet - logger.Debug("loading issuer wallet") - wallet := ttx.MyIssuerWallet(context) - if wallet == nil { - return "", errors.Errorf("issuer wallet not found") - } - - // The issuer adds a new issue operation to the transaction to issue - // the amount to the recipient id recieved from the owner's node. - err = tx.Issue( - wallet, - recipient, - v.TokenType, - v.Quantity, - ) - if err != nil { - return "", errors.Wrap(err, "failed adding new issued token") - } - - // The issuer is ready to collect all the required signatures. - // In this case, the issuer's and the auditor's signatures. - // Invoke the Token Chaincode to collect endorsements on the Token Request and prepare the relative transaction. - // This is all done in one shot running the following view. - // Before completing, all recipients receive the approved transaction. - // Depending on the token driver implementation, the recipient's signature might or might not be needed to make - // the token transaction valid. - logger.Infof("collecting signatures and submitting transaction to chaincode: [%s]", tx.ID()) - _, err = context.RunView(ttx.NewCollectEndorsementsView(tx)) - if err != nil { - return "", errors.Wrap(err, "failed to sign transaction") - } - // Last but not least, the issuer sends the transaction for ordering and waits for transaction finality. - logger.Infof("submitting fabric transaction to orderer for final settlemement: [%s]", tx.ID()) - _, err = context.RunView(ttx.NewOrderingAndFinalityView(tx)) - if err != nil { - return "", errors.Wrap(err, "failed to order or commit transaction") - } - return tx.ID(), nil -} diff --git a/token-sdk/owner/conf/owner1/core.yaml b/token-sdk/owner/conf/owner1/core.yaml deleted file mode 100644 index 01f1ac56..00000000 --- a/token-sdk/owner/conf/owner1/core.yaml +++ /dev/null @@ -1,119 +0,0 @@ -logging: - spec: info - format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' - -# ------------------- FSC Node Configuration ------------------------- -# The FSC node is responsible for the peer to peer communication with other token services. -fsc: - identity: - cert: - file: /var/fsc/keys/owner1/fsc/msp/signcerts/cert.pem - key: - file: /var/fsc/keys/owner1/fsc/msp/keystore/priv_sk - tls: - enabled: false # TODO - p2p: - listenAddress: /ip4/0.0.0.0/tcp/9201 - # If empty, this is a P2P boostrap node. Otherwise, it contains the name of the FSC node that is a bootstrap node. - # The name of the FSC node that is a bootstrap node must be set under fsc.endpoint.resolvers - bootstrapNode: auditor - kvs: # key-value-store - persistence: - type: badger # badger or memory - opts: - path: /var/fsc/data/owner1/kvs - - # The endpoint section tells how to reach other FSC node in the network. - # For each node, the name, the domain, the identity of the node, and its addresses must be specified. - endpoint: - resolvers: - - name: auditor - identity: - id: auditor - path: /var/fsc/keys/auditor/fsc/msp/signcerts/cert.pem - addresses: - P2P: auditor.example.com:9001 - - name: issuer - identity: - id: issuer - path: /var/fsc/keys/issuer/fsc/msp/signcerts/cert.pem - addresses: - P2P: issuer.example.com:9101 - - name: owner2 - identity: - id: owner2 - path: /var/fsc/keys/owner2/fsc/msp/signcerts/cert.pem - addresses: - P2P: owner2.example.com:9201 - aliases: - - owner2 - -# ------------------- Fabric Configuration ------------------------- -fabric: - enabled: true - mynetwork: - default: true - mspConfigPath: /var/fsc/keys/fabric/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp - defaultMSP: Org1MSP - msps: - - id: Org1MSP - mspType: bccsp - mspID: Org1MSP - path: /var/fsc/keys/fabric/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp - tls: - enabled: true - # If the keepalive values are too low, Fabric peers will complain with: ENHANCE_YOUR_CALM, debug data: "too_many_pings" - keepalive: - interval: 300s - timeout: 600s - # List of orderer nodes this node can connect to. There must be at least one orderer node. Others are discovered. - orderers: - - address: orderer.example.com:7050 - connectionTimeout: 10s - tlsEnabled: true - tlsRootCertFile: /var/fsc/keys/fabric/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt - serverNameOverride: orderer.example.com - # List of trusted peers this node can connect to. There must be at least one trusted peer. Others are discovered. - peers: - - address: peer0.org1.example.com:7051 - connectionTimeout: 10s - tlsEnabled: true - tlsRootCertFile: /var/fsc/keys/fabric/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt - serverNameOverride: peer0.org1.example.com - # Channel where the token chaincode is deployed - channels: - - name: mychannel - default: true - # Configuration of the vault used to store the RW sets assembled by this node - vault: - persistence: - type: badger - opts: - path: /var/fsc/data/owner1/vault - -# ------------------- Token SDK Configuration ------------------------- -token: - enabled: true - tms: - mytms: # unique name of this token management system - network: mynetwork # the name of the fabric network as configured above - channel: mychannel # the name of the network's channel this TMS refers to, if applicable - namespace: tokenchaincode # chaincode name - driver: zkatdlog # privacy preserving driver (zero knowledge asset transfer) - wallets: - defaultCacheSize: 3 # how many idemix keys to pre-generate - owners: - - id: alice # the unique identifier of this wallet. Here is an example of use: `ttx.GetWallet(context, "alice")` - # default: true # is this the default owner wallet - path: /var/fsc/keys/owner1/wallet/alice/msp - - id: bob - path: /var/fsc/keys/owner1/wallet/bob/msp - - # Internal database to keep track of token transactions. - # It is used by auditors and token owners to track history - ttxdb: - persistence: - # type can be badger (disk) or memory - type: badger - opts: - path: /var/fsc/data/owner1/txdb diff --git a/token-sdk/owner/conf/owner2/core.yaml b/token-sdk/owner/conf/owner2/core.yaml deleted file mode 100644 index 8b5a5b95..00000000 --- a/token-sdk/owner/conf/owner2/core.yaml +++ /dev/null @@ -1,119 +0,0 @@ -logging: - spec: info - format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' - -# ------------------- FSC Node Configuration ------------------------- -# The FSC node is responsible for the peer to peer communication with other token services. -fsc: - identity: - cert: - file: /var/fsc/keys/owner2/fsc/msp/signcerts/cert.pem - key: - file: /var/fsc/keys/owner2/fsc/msp/keystore/priv_sk - tls: - enabled: false # TODO - p2p: - listenAddress: /ip4/0.0.0.0/tcp/9301 - # If empty, this is a P2P boostrap node. Otherwise, it contains the name of the FSC node that is a bootstrap node. - # The name of the FSC node that is a bootstrap node must be set under fsc.endpoint.resolvers - bootstrapNode: auditor - kvs: # key-value-store - persistence: - type: badger # badger or memory - opts: - path: /var/fsc/data/owner2/kvs - - # The endpoint section tells how to reach other FSC node in the network. - # For each node, the name, the domain, the identity of the node, and its addresses must be specified. - endpoint: - resolvers: - - name: auditor - identity: - id: auditor - path: /var/fsc/keys/auditor/fsc/msp/signcerts/cert.pem - addresses: - P2P: auditor.example.com:9001 - - name: issuer - identity: - id: issuer - path: /var/fsc/keys/issuer/fsc/msp/signcerts/cert.pem - addresses: - P2P: issuer.example.com:9101 - - name: owner1 - identity: - id: owner1 - path: /var/fsc/keys/owner1/fsc/msp/signcerts/cert.pem - addresses: - P2P: owner1.example.com:9201 - aliases: - - owner1 - -# ------------------- Fabric Configuration ------------------------- -fabric: - enabled: true - mynetwork: - default: true - mspConfigPath: /var/fsc/keys/fabric/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp - defaultMSP: Org1MSP - msps: - - id: Org1MSP - mspType: bccsp - mspID: Org1MSP - path: /var/fsc/keys/fabric/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp - tls: - enabled: true - # If the keepalive values are too low, Fabric peers will complain with: ENHANCE_YOUR_CALM, debug data: "too_many_pings" - keepalive: - interval: 300s - timeout: 600s - # List of orderer nodes this node can connect to. There must be at least one orderer node. Others are discovered. - orderers: - - address: orderer.example.com:7050 - connectionTimeout: 10s - tlsEnabled: true - tlsRootCertFile: /var/fsc/keys/fabric/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt - serverNameOverride: orderer.example.com - # List of trusted peers this node can connect to. There must be at least one trusted peer. Others are discovered. - peers: - - address: peer0.org1.example.com:7051 - connectionTimeout: 10s - tlsEnabled: true - tlsRootCertFile: /var/fsc/keys/fabric/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt - serverNameOverride: peer0.org1.example.com - # Channel where the token chaincode is deployed - channels: - - name: mychannel - default: true - # Configuration of the vault used to store the RW sets assembled by this node - vault: - persistence: - type: badger - opts: - path: /var/fsc/data/owner2/vault - -# ------------------- Token SDK Configuration ------------------------- -token: - enabled: true - tms: - mytms: # unique name of this token management system - network: mynetwork # the name of the fabric network as configured above - channel: mychannel # the name of the network's channel this TMS refers to, if applicable - namespace: tokenchaincode # chaincode name - driver: zkatdlog # privacy preserving driver (zero knowledge asset transfer) - wallets: - defaultCacheSize: 3 # how many idemix keys to pre-generate - owners: - - id: carlos # the unique identifier of this wallet. Here is an example of use: `ttx.GetWallet(context, "alice")` - # default: true # is this the default owner wallet - path: /var/fsc/keys/owner2/wallet/carlos/msp - - id: dan - path: /var/fsc/keys/owner2/wallet/dan/msp - - # Internal database to keep track of token transactions. - # It is used by auditors and token owners to track history - ttxdb: - persistence: - # type can be badger (disk) or memory - type: badger - opts: - path: /var/fsc/data/owner2/txdb diff --git a/token-sdk/owner/go.mod b/token-sdk/owner/go.mod deleted file mode 100644 index 07942f30..00000000 --- a/token-sdk/owner/go.mod +++ /dev/null @@ -1,245 +0,0 @@ -module github.com/hyperledger/fabric-samples/token-sdk/owner - -go 1.22.0 - -replace github.com/ugorji/go v1.1.4 => github.com/ugorji/go/codec v1.2.9 - -require ( - github.com/deepmap/oapi-codegen v1.15.0 - github.com/getkin/kin-openapi v0.120.0 - github.com/hyperledger-labs/fabric-smart-client v0.3.0 - github.com/hyperledger-labs/fabric-token-sdk v0.3.0 - github.com/labstack/echo/v4 v4.11.1 - github.com/pkg/errors v0.9.1 -) - -require ( - github.com/BurntSushi/toml v1.3.2 // indirect - github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect - github.com/CloudyKit/jet/v6 v6.2.0 // indirect - github.com/IBM/idemix v0.0.2-0.20230831093709-b7a940638990 // indirect - github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20230831093709-b7a940638990 // indirect - github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20230831093709-b7a940638990 // indirect - github.com/IBM/idemix/bccsp/types v0.0.0-20230831093709-b7a940638990 // indirect - github.com/IBM/mathlib v0.0.3-0.20230831091907-c532c4d3b65c // indirect - github.com/Joker/jade v1.1.3 // indirect - github.com/ReneKroon/ttlcache/v2 v2.11.0 // indirect - github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect - github.com/ale-linux/aries-framework-go/component/kmscrypto v0.0.0-20230817163708-4b3de6d91874 // indirect - github.com/andybalholm/brotli v1.0.5 // indirect - github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/aymerick/douceur v0.2.0 // indirect - github.com/benbjohnson/clock v1.3.5 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/bytedance/sonic v1.9.1 // indirect - github.com/cenkalti/backoff/v4 v4.2.0 // indirect - github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/consensys/bavard v0.1.13 // indirect - github.com/consensys/gnark-crypto v0.9.1 // indirect - github.com/containerd/cgroups v1.1.0 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect - github.com/dgraph-io/badger/v3 v3.2103.2 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/elastic/gosigar v0.14.2 // indirect - github.com/fatih/structs v1.1.0 // indirect - github.com/flosch/pongo2/v4 v4.0.2 // indirect - github.com/flynn/noise v1.0.0 // indirect - github.com/francoispqt/gojay v1.2.13 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-gonic/gin v1.9.1 // indirect - github.com/go-kit/kit v0.10.0 // indirect - github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-logr/logr v1.2.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/swag v0.22.4 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/godbus/dbus/v5 v5.1.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang/glog v1.0.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12 // indirect - github.com/google/flatbuffers v1.12.1 // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect - github.com/google/uuid v1.3.1 // indirect - github.com/gorilla/css v1.0.0 // indirect - github.com/gorilla/mux v1.8.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-uuid v1.0.2 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/huin/goupnp v1.2.0 // indirect - github.com/hyperledger-labs/orion-sdk-go v0.2.5 // indirect - github.com/hyperledger-labs/orion-server v0.2.5 // indirect - github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.3-alpha.1 // indirect - github.com/hyperledger-labs/weaver-dlt-interoperability/sdks/fabric/go-sdk v1.2.3-alpha.1.0.20210812140206-37f430515b8c // indirect - github.com/hyperledger/fabric v1.4.0-rc1.0.20230401164317-bd8e24856939 // indirect - github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2 // indirect - github.com/hyperledger/fabric-chaincode-go v0.0.0-20220920210243-7bc6fa0dd58b // indirect - github.com/hyperledger/fabric-lib-go v1.0.0 // indirect - github.com/hyperledger/fabric-private-chaincode v0.0.0-20210907122433-d56466264e4d // indirect - github.com/hyperledger/fabric-protos-go v0.2.0 // indirect - github.com/invopop/yaml v0.2.0 // indirect - github.com/ipfs/boxo v0.8.0-rc1 // indirect - github.com/ipfs/go-cid v0.4.1 // indirect - github.com/ipfs/go-datastore v0.6.0 // indirect - github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-log v1.0.5 // indirect - github.com/ipfs/go-log/v2 v2.5.1 // indirect - github.com/ipld/go-ipld-prime v0.20.0 // indirect - github.com/iris-contrib/schema v0.0.6 // indirect - github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect - github.com/jbenet/goprocess v0.1.4 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/kataras/blocks v0.0.7 // indirect - github.com/kataras/golog v0.1.9 // indirect - github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 // indirect - github.com/kataras/pio v0.0.12 // indirect - github.com/kataras/sitemap v0.0.6 // indirect - github.com/kataras/tunnel v0.0.4 // indirect - github.com/kilic/bls12-381 v0.1.0 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect - github.com/koron/go-ssdp v0.0.4 // indirect - github.com/labstack/gommon v0.4.0 // indirect - github.com/leodido/go-urn v1.2.4 // indirect - github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p v0.31.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.22.0 // indirect - github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect - github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-msgio v0.3.0 // indirect - github.com/libp2p/go-nat v0.2.0 // indirect - github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.4.0 // indirect - github.com/libp2p/go-yamux/v4 v4.0.1 // indirect - github.com/magiconair/properties v1.8.5 // indirect - github.com/mailgun/raymond/v2 v2.0.48 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/microcosm-cc/bluemonday v1.0.25 // indirect - github.com/miekg/dns v1.1.55 // indirect - github.com/miekg/pkcs11 v1.1.1 // indirect - github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect - github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect - github.com/minio/sha256-simd v1.0.1 // indirect - github.com/mitchellh/mapstructure v1.4.3 // indirect - github.com/mmcloughlin/addchain v0.4.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/mr-tron/base58 v1.2.0 // indirect - github.com/multiformats/go-base32 v0.1.0 // indirect - github.com/multiformats/go-base36 v0.2.0 // indirect - github.com/multiformats/go-multiaddr v0.11.0 // indirect - github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect - github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect - github.com/multiformats/go-multibase v0.2.0 // indirect - github.com/multiformats/go-multicodec v0.9.0 // indirect - github.com/multiformats/go-multihash v0.2.3 // indirect - github.com/multiformats/go-multistream v0.4.1 // indirect - github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.11.0 // indirect - github.com/opencontainers/runtime-spec v1.1.0 // indirect - github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect - github.com/pelletier/go-toml v1.9.4 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect - github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.1 // indirect - github.com/quic-go/webtransport-go v0.5.3 // indirect - github.com/raulk/go-watchdog v1.3.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/schollz/closestmatch v2.1.0+incompatible // indirect - github.com/sirupsen/logrus v1.9.0 // indirect - github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/spf13/afero v1.6.0 // indirect - github.com/spf13/cast v1.4.1 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.10.1 // indirect - github.com/stretchr/testify v1.8.4 // indirect - github.com/subosito/gotenv v1.2.0 // indirect - github.com/sykesm/zap-logfmt v0.0.4 // indirect - github.com/tdewolff/minify/v2 v2.12.9 // indirect - github.com/tdewolff/parse/v2 v2.6.8 // indirect - github.com/test-go/testify v1.1.4 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.2 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect - github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - github.com/yosssi/ace v0.0.5 // indirect - go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.13.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.13.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.13.0 // indirect - go.opentelemetry.io/otel/sdk v1.13.0 // indirect - go.opentelemetry.io/otel/trace v1.14.0 // indirect - go.opentelemetry.io/proto/otlp v0.19.0 // indirect - go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.20.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.25.0 // indirect - golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.13.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.12.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.53.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.2.1 // indirect - rsc.io/tmplfunc v0.0.3 // indirect -) diff --git a/token-sdk/owner/go.sum b/token-sdk/owner/go.sum deleted file mode 100644 index 60388580..00000000 --- a/token-sdk/owner/go.sum +++ /dev/null @@ -1,2020 +0,0 @@ -bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c/go.mod h1:hSVuE3qU7grINVSwrmzHfpg9k87ALBk+XaualNyUzI4= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= -cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -code.cloudfoundry.org/clock v1.0.0/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME= -github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4= -github.com/DATA-DOG/go-txdb v0.1.3/go.mod h1:DhAhxMXZpUJVGnT+p9IbzJoRKvlArO2pkHjnGX7o0n0= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= -github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= -github.com/IBM/idemix v0.0.2-0.20230831093709-b7a940638990 h1:hEZKSPmBJddcapbHqCSogIMTIzUXQhL/vTWzbngnRjw= -github.com/IBM/idemix v0.0.2-0.20230831093709-b7a940638990/go.mod h1:A9w6lDhpXujKBck1rcw6unxAzJtx+QsuT5qd1CS7BKc= -github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20230831093709-b7a940638990 h1:2h+Ou3S30pkBlkukOfprO5wGD4A13NBnyQx/gDQVzaQ= -github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20230831093709-b7a940638990/go.mod h1:sgvrLB3a8mKr4rX+aBDXPCZBgSRRmQxlyxA3jmwq/Sk= -github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20230831093709-b7a940638990 h1:crSJPccrt4hk0dqbmBUc+T1w91oTkauADD/UQvRRB10= -github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20230831093709-b7a940638990/go.mod h1:EPAfwEciT+Yke9xTooqJUcEuf2R8pmIA0QjPG6df1xM= -github.com/IBM/idemix/bccsp/types v0.0.0-20230831093709-b7a940638990 h1:UkW/eqL8hlqaGLLsY9oZsv1iwEMJOuNbAomK07C30/8= -github.com/IBM/idemix/bccsp/types v0.0.0-20230831093709-b7a940638990/go.mod h1:2lO6nmsoSH3WDJdat4kIicU+WTs4qDntGZkF8XdgHm8= -github.com/IBM/mathlib v0.0.3-0.20230831091907-c532c4d3b65c h1:QVrlfdfx7MslApfSdSLiLIOFmYlLhP6wY4LyRBVed4I= -github.com/IBM/mathlib v0.0.3-0.20230831091907-c532c4d3b65c/go.mod h1:k0NBSWMYVgaZ2keDuI8DSwdIEhUNhp8XnlVmm6Xwyuk= -github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk= -github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= -github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI= -github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= -github.com/ReneKroon/ttlcache/v2 v2.11.0 h1:OvlcYFYi941SBN3v9dsDcC2N8vRxyHcCmJb3Vl4QMoM= -github.com/ReneKroon/ttlcache/v2 v2.11.0/go.mod h1:mBxvsNY+BT8qLLd6CuAJubbKo6r0jh3nb5et22bbfGY= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 h1:KkH3I3sJuOLP3TjA/dfr4NAY8bghDwnXiU7cTKxQqo0= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/sarama v1.20.1/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/sarama v1.26.3 h1:wSN3FpDXLe3e2z47OzGii5VAK693oVkyHFwh240jWjg= -github.com/Shopify/sarama v1.26.3/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= -github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/ale-linux/aries-framework-go/component/kmscrypto v0.0.0-20230817163708-4b3de6d91874 h1:O08ZCyb1f7UeyOmTeItAw7eSZOlyM0fBnrPgaYgKEiA= -github.com/ale-linux/aries-framework-go/component/kmscrypto v0.0.0-20230817163708-4b3de6d91874/go.mod h1:4sHtFlGI84SVjaSW7u1pCfC0bjijd9ZeqbKptU/Qljs= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= -github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= -github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= -github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/badgerodon/peg v0.0.0-20130729175151-9e5f7f4d07ca/go.mod h1:TWe0N2hv5qvpLHT+K16gYcGBllld4h65dQ/5CNuirmk= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= -github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cayleygraph/cayley v0.7.7 h1:z+7xkAbg6bKiXJOtOkEG3zCm2K084sr/aGwFV7xcQNs= -github.com/cayleygraph/cayley v0.7.7/go.mod h1:VUd+PInYf94/VY41ePeFtFyP99BAs953kFT4N+6F7Ko= -github.com/cayleygraph/quad v1.1.0 h1:w1nXAmn+nz07+qlw89dke9LwWkYpeX+OcvfTvGQRBpM= -github.com/cayleygraph/quad v1.1.0/go.mod h1:maWODEekEhrO0mdc9h5n/oP7cH1h/OTgqQ2qWbuI9M4= -github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= -github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a/go.mod h1:rzgs2ZOiguV6/NpiDgADjRLPNyZlApIWxKpkT+X8SdY= -github.com/cloudflare/cfssl v1.4.1/go.mod h1:KManx/OJPb5QY+y0+o/898AMcM128sF0bURvoVUSjTo= -github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4= -github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= -github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.9.1 h1:mru55qKdWl3E035hAoh1jj9d7hVnYY5pfb6tmovSmII= -github.com/consensys/gnark-crypto v0.9.1/go.mod h1:a2DQL4+5ywF6safEeZFEPGRiiGbjzGFRUN2sg06VuU4= -github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= -github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a h1:W8b4lQ4tFF21aspRGoBuCNV6V2fFJBF+pm1J6OY8Lys= -github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cucumber/godog v0.8.0/go.mod h1:Cp3tEV1LRAyH/RuCThcxHS/+9ORZ+FMzPva2AZ5Ki+A= -github.com/cznic/mathutil v0.0.0-20170313102836-1447ad269d64/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= -github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= -github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= -github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= -github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/deepmap/oapi-codegen v1.15.0 h1:SQqViaeb4k2vMul8gx12oDOIadEtoRqTdLkxjzqtQ90= -github.com/deepmap/oapi-codegen v1.15.0/go.mod h1:a6KoHV7lMRwsPoEg2C6NDHiXYV3EQfiFocOlJ8dgJQE= -github.com/dennwc/base v1.0.0 h1:xlBzvBNRvkQ1LFI/jom7rr0vZsvYDKtvMM6lIpjFb3M= -github.com/dennwc/base v1.0.0/go.mod h1:zaTDIiAcg2oKW9XhjIaRc1kJVteCFXSSW6jwmCedUaI= -github.com/dennwc/graphql v0.0.0-20180603144102-12cfed44bc5d/go.mod h1:lg9KQn0BgRCSCGNpcGvJp/0Ljf1Yxk8TZq9HSYc43fk= -github.com/dgraph-io/badger v1.5.4/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= -github.com/dgraph-io/badger v1.5.5/go.mod h1:QgCntgIUPsjnp7cMLhUybJHb7iIoQWAHT6tF8ngCjWk= -github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= -github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= -github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= -github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-farm v0.0.0-20190416075124-e1214b5e05dc/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.1.4/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.7.3-0.20180412203414-a422774e593b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v0.7.3-0.20190309235953-33c3200e0d16/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v17.12.0-ce-rc1.0.20190628135806-70f67c6240bb+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dop251/goja v0.0.0-20190105122144-6d5bf35058fa/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= -github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/flimzy/diff v0.1.5/go.mod h1:lFJtC7SPsK0EroDmGTSrdtWKAxOk3rO+q+e04LL05Hs= -github.com/flimzy/diff v0.1.6/go.mod h1:lFJtC7SPsK0EroDmGTSrdtWKAxOk3rO+q+e04LL05Hs= -github.com/flimzy/kivik v1.8.1/go.mod h1:S2aPycbG0eDFll4wgXt9uacSNkXISPufutnc9sv+mdA= -github.com/flimzy/testy v0.1.16/go.mod h1:3szguN8NXqgq9bt9Gu8TQVj698PJWmyx/VY1frwwKrM= -github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= -github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= -github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= -github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= -github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/frankban/quicktest v1.9.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/fsouza/go-dockerclient v1.2.2/go.mod h1:KpcjM623fQYE9MZiTGzKhjfxXAV9wbyX2C1cyRHfhl0= -github.com/fsouza/go-dockerclient v1.4.1/go.mod h1:PUNHxbowDqRXfRgZqMz1OeGtbWC6VKyZvJ99hDjB0qs= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/getkin/kin-openapi v0.120.0 h1:MqJcNJFrMDFNc07iwE8iFC5eT2k/NPUFDIpNeiZv8Jg= -github.com/getkin/kin-openapi v0.120.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw= -github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-kivik/couchdb v1.8.1/go.mod h1:5XJRkAMpBlEVA4q0ktIZjUPYBjoBmRoiWvwUBzP3BOQ= -github.com/go-kivik/kivik v1.8.1/go.mod h1:nIuJ8z4ikBrVUSk3Ua8NoDqYKULPNjuddjqRvlSUyyQ= -github.com/go-kivik/kiviktest v1.1.2/go.mod h1:JdhVyzixoYhoIDUt6hRf1yAfYyaDa5/u9SDOindDkfQ= -github.com/go-kivik/pouchdb v1.3.5/go.mod h1:U+siUrqLCVxeMU3QjQTYIC3/F/e6EUKm+o5buJb7vpw= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= -github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.1 h1:OQl5ys5MBea7OGCdvPbBJWRgnhC/fGona6QKfvFeau8= -github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= -github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/logger v1.0.7 h1:LTLwWelETXDYyqF/ASf0nxaIcdEOIJNxRokPcfI/xbU= -github.com/gobuffalo/logger v1.0.7/go.mod h1:u40u6Bq3VVvaMcy5sRBclD8SXhBYPS0Qk95ubt+1xJM= -github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= -github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= -github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= -github.com/gobuffalo/packr/v2 v2.7.1 h1:n3CIW5T17T8v4GGK5sWXLVWJhCz7b5aNLSxW6gYim4o= -github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12 h1:uK3X/2mt4tbSGoHvbLBHUny7CKiuwUip3MArtukol4E= -github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= -github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/jsbuiltin v0.0.0-20180426082241-50091555e127/go.mod h1:7X1acUyFRf+oVFTU6SWw9mnb57Vxn+Nbh8iPbKg95hs= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= -github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= -github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.4.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= -github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4= -github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hidal-go/hidalgo v0.0.0-20190814174001-42e03f3b5eaa/go.mod h1:bPkrxDlroXxigw8BMWTEPTv4W5/rQwNgg2BECXsgyX0= -github.com/hidal-go/hidalgo v0.0.0-20201109092204-05749a6d73df h1:bvz3e467dv98bVHQ9F5QbGKtGvyQO3rPD8lwu6fZ/D4= -github.com/hidal-go/hidalgo v0.0.0-20201109092204-05749a6d73df/go.mod h1:bPkrxDlroXxigw8BMWTEPTv4W5/rQwNgg2BECXsgyX0= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/hyperledger-labs/fabric-smart-client v0.3.0 h1:CNSFdHfhlvAjD4OrOojvtsZBEN50sl6uSl3qXZhzX+o= -github.com/hyperledger-labs/fabric-smart-client v0.3.0/go.mod h1:ZmxAL+oOP3B/HEu+z9a69+PwfWKfUiMsSBpwdPwlh2g= -github.com/hyperledger-labs/fabric-token-sdk v0.3.0 h1:YE1NMmf1o8oEb4j3XI3CrtAd+bpHJdTY3rY1RqfYR28= -github.com/hyperledger-labs/fabric-token-sdk v0.3.0/go.mod h1:NcyBbgCtVohGdui/yMDirJ9tk0EolWD0WVLSk5a1A7I= -github.com/hyperledger-labs/orion-sdk-go v0.2.5 h1:HFGRTuMZgzo9EtyJeFAhVSlbrj6x3jtY0aDcghdjzRE= -github.com/hyperledger-labs/orion-sdk-go v0.2.5/go.mod h1:At8hiFATfkDXQ4AFLVbaTiC9GDhVDo8aN/supb1KBb4= -github.com/hyperledger-labs/orion-server v0.2.5 h1:aFudmB9SAnsT5v8jhazkuszEu0pdJNFqaYZF2GpvAuI= -github.com/hyperledger-labs/orion-server v0.2.5/go.mod h1:8kXVAU1wvFYGbFL1qmXwMi2i8gKV2smOdp1F1kq0HMk= -github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.3-alpha.1 h1:vBvo0PNm82ht7wpBjlYY4ZHxV3YprCfdVd3T4JG9vBw= -github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.3-alpha.1/go.mod h1:POCGO/RK9YDfgdhuyqjoD9tRNtWfK7Rh5AYYmsb1Chc= -github.com/hyperledger-labs/weaver-dlt-interoperability/sdks/fabric/go-sdk v1.2.3-alpha.1.0.20210812140206-37f430515b8c h1:pKr8VnHlduEgdInwLWykYAw+lpUizjQJaJ8I5fVoRUo= -github.com/hyperledger-labs/weaver-dlt-interoperability/sdks/fabric/go-sdk v1.2.3-alpha.1.0.20210812140206-37f430515b8c/go.mod h1:si2XAWZclHXC359OyYMpNHfonf2P7P2nzABdCA8mPqs= -github.com/hyperledger/fabric v1.4.0-rc1.0.20201118191903-ec81f3e74fa1/go.mod h1:ppiyrJ+sUSk/rAX9cTd8xwAwSQ7chEbOQMAqtQ3pLG4= -github.com/hyperledger/fabric v1.4.0-rc1.0.20230401164317-bd8e24856939 h1:+XwAnpbvmxEeRD1yT+gd77643Y1QQUv0B2HUr4CRNWE= -github.com/hyperledger/fabric v1.4.0-rc1.0.20230401164317-bd8e24856939/go.mod h1:H7BI2gsTl4fW9ARtYG7UOGjwecXHSReVaIz4p2xqUB8= -github.com/hyperledger/fabric-amcl v0.0.0-20200128223036-d1aa2665426a/go.mod h1:X+DIyUsaTmalOpmpQfIvFZjKHQedrURQ5t4YqquX7lE= -github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2 h1:B1Nt8hKb//KvgGRprk0h1t4lCnwhE9/ryb1WqfZbV+M= -github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2/go.mod h1:X+DIyUsaTmalOpmpQfIvFZjKHQedrURQ5t4YqquX7lE= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20190823162523-04390e015b85/go.mod h1:HZK6PKLWrvdD/t0oSLiyaRaUM6fZ7qjJuOlb0zrn0mo= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20200128192331-2d899240a7ed/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20201119163726-f8ef75b17719/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20220920210243-7bc6fa0dd58b h1:MGT5rdajc4zbsbU7yMzkLJmsiRwJk5gBX5OdpU117Bg= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20220920210243-7bc6fa0dd58b/go.mod h1:OxME3M0bbgoWYHpXIVMzpbXgFqrTZnFmlH0Cpml54m0= -github.com/hyperledger/fabric-config v0.0.5/go.mod h1:YpITBI/+ZayA3XWY5lF302K7PAsFYjEEPM/zr3hegA8= -github.com/hyperledger/fabric-config v0.0.7/go.mod h1:aeDZ0moG/qKvwLjddcqYr8+58/oNaJy3HE0tI01546c= -github.com/hyperledger/fabric-config v0.1.0 h1:TsR3y5xEoUmXWfp8tcDycjJhVvXEHiV5kfZIxuIte08= -github.com/hyperledger/fabric-config v0.1.0/go.mod h1:aeDZ0moG/qKvwLjddcqYr8+58/oNaJy3HE0tI01546c= -github.com/hyperledger/fabric-contract-api-go v1.1.1/go.mod h1:+39cWxbh5py3NtXpRA63rAH7NzXyED+QJx1EZr0tJPo= -github.com/hyperledger/fabric-lib-go v1.0.0 h1:UL1w7c9LvHZUSkIvHTDGklxFv2kTeva1QI2emOVc324= -github.com/hyperledger/fabric-lib-go v1.0.0/go.mod h1:H362nMlunurmHwkYqR5uHL2UDWbQdbfz74n8kbCFsqc= -github.com/hyperledger/fabric-private-chaincode v0.0.0-20210907122433-d56466264e4d h1:LR34x2vhXUuXsETE9HBhz+eZM6nTuzPiWsF5jnNI550= -github.com/hyperledger/fabric-private-chaincode v0.0.0-20210907122433-d56466264e4d/go.mod h1:CBeWypXEi4LndnexZzEEqVIIqjdrUzUUHmmFcEcGRX4= -github.com/hyperledger/fabric-protos-go v0.0.0-20190821214336-621b908d5022/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20190919234611-2a87503ac7c9/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20200707132912-fee30f3ccd23/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20201028172056-a3136dde2354/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.2.0 h1:opaGKvsYYD0abMl6ErriNc+CEgLW+ELdKKQ0QyBL7/0= -github.com/hyperledger/fabric-protos-go v0.2.0/go.mod h1:WWnyWP40P2roPmmvxsUXSvVI/CF6vwY1K1UFidnKBys= -github.com/hyperledger/fabric-samples/chaincode/marbles02/go v0.0.0-20210428060230-9db8164f049b/go.mod h1:MvJbTLiLI/KBavKkC+OAqYU1IGvbY8WOu+Qzs/jncnA= -github.com/hyperledger/fabric-sdk-go v1.0.0/go.mod h1:qWE9Syfg1KbwNjtILk70bJLilnmCvllIYFCSY/pa1RU= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd/go.mod h1:3LVOLeyx9XVvwPgrt2be44XgSqndprz1G18rSk8KD84= -github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY= -github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= -github.com/ipfs/boxo v0.8.0-rc1 h1:DL5SDbBNSS9ZNsF+UhoQ39d05/wgoJ2k/T+y7JeWRaw= -github.com/ipfs/boxo v0.8.0-rc1/go.mod h1:EgDiNox/+W/+ySwEotRrHlvdmrhbSAB4p22ELg+ZsCc= -github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= -github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= -github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= -github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= -github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= -github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= -github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= -github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= -github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= -github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= -github.com/iris-contrib/httpexpect/v2 v2.15.2 h1:T9THsdP1woyAqKHwjkEsbCnMefsAFvk8iJJKokcJ3Go= -github.com/iris-contrib/httpexpect/v2 v2.15.2/go.mod h1:JLDgIqnFy5loDSUv1OA2j0mb6p/rDhiCqigP22Uq9xE= -github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw= -github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= -github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= -github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= -github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= -github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= -github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= -github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= -github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= -github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548/go.mod h1:hGT6jSUVzF6no3QaDSMLGLEHtHSBSefs+MgcDWnmhmo= -github.com/jmoiron/sqlx v0.0.0-20180124204410-05cef0741ade/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU= -github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/kataras/blocks v0.0.7 h1:cF3RDY/vxnSRezc7vLFlQFTYXG/yAr1o7WImJuZbzC4= -github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= -github.com/kataras/golog v0.1.9 h1:vLvSDpP7kihFGKFAvBSofYo7qZNULYSHOH2D7rPTKJk= -github.com/kataras/golog v0.1.9/go.mod h1:jlpk/bOaYCyqDqH18pgDHdaJab72yBE6i0O3s30hpWY= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 h1:Vx8kDVhO2qepK8w44lBtp+RzN3ld743i+LYPzODJSpQ= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9/go.mod h1:ldkoR3iXABBeqlTibQ3MYaviA1oSlPvim6f55biwBh4= -github.com/kataras/pio v0.0.12 h1:o52SfVYauS3J5X08fNjlGS5arXHjW/ItLkyLcKjoH6w= -github.com/kataras/pio v0.0.12/go.mod h1:ODK/8XBhhQ5WqrAhKy+9lTPS7sBf6O3KcLhc9klfRcY= -github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= -github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= -github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= -github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= -github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= -github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= -github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= -github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.0.0/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28/go.mod h1:T/T7jsxVqf9k/zYOqbgNAsANsjxTd1Yq3htjDhQ1H0c= -github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4= -github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ= -github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lib/pq v0.0.0-20180201184707-88edab080323/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= -github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= -github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= -github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= -github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= -github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= -github.com/libp2p/go-libp2p-kad-dht v0.22.0 h1:cW2nGgG0hztDM42tOPyC5cVflD7EzLaHM0/Kjol6Wio= -github.com/libp2p/go-libp2p-kad-dht v0.22.0/go.mod h1:hareSo3Z/GJ7nUWPMj7XhD/56a7+rRltYCWwCuy3FQk= -github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= -github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= -github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= -github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= -github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= -github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= -github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= -github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= -github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= -github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= -github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= -github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= -github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/linkeddata/gojsonld v0.0.0-20170418210642-4f5db6791326/go.mod h1:nfqkuSNlsk1bvti/oa7TThx4KmRMBmSxf3okHI9wp3E= -github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw= -github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= -github.com/mailru/easyjson v0.0.0-20180730094502-03f2033d19d5/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= -github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/matttproud/golang_protobuf_extensions v1.0.0/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/maxbrunsfeld/counterfeiter/v6 v6.3.0/go.mod h1:fcEyUyXZXoV4Abw8DX0t7wyL8mCDxXyU4iAFZfT3IHw= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= -github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= -github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= -github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= -github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= -github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= -github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= -github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= -github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= -github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= -github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= -github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= -github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= -github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= -github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= -github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= -github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= -github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= -github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= -github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= -github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= -github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= -github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= -github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= -github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= -github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= -github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= -github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= -github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= -github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= -github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= -github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= -github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= -github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= -github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= -github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= -github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc8/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= -github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.0.0/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= -github.com/otiai10/copy v1.5.1 h1:a/cs2E1/1V0az8K5nblbl+ymEa4E11AfaOLMar8V34w= -github.com/otiai10/copy v1.5.1/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= -github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= -github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= -github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/peterh/liner v0.0.0-20170317030525-88609521dc4b/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.5.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.6.0+incompatible h1:Ix9yFKn1nSPBLFl/yZknTp8TU5G4Ps0JDmguYK6iH1A= -github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= -github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.0.0-20180518154759-7600349dcfe1/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= -github.com/prometheus/procfs v0.0.0-20180612222113-7d6f385de8be/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= -github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= -github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= -github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= -github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= -github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= -github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= -github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= -github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= -github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.3.1/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.1.1/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= -github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk= -github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU= -github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/sykesm/zap-logfmt v0.0.2/go.mod h1:TerDJT124HaO8UTpZ2wJCipJRAKQ9XONM1mzUabIh6M= -github.com/sykesm/zap-logfmt v0.0.4 h1:U2WzRvmIWG1wDLCFY3sz8UeEmsdHQjHFNlIdmroVFaI= -github.com/sykesm/zap-logfmt v0.0.4/go.mod h1:AuBd9xQjAe3URrWT1BBDk2v2onAZHkZkWRMiYZXiZWA= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/syndtr/goleveldb v1.0.1-0.20190625010220-02440ea7a285/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/tdewolff/minify/v2 v2.12.9 h1:dvn5MtmuQ/DFMwqf5j8QhEVpPX6fi3WGImhv8RUB4zA= -github.com/tdewolff/minify/v2 v2.12.9/go.mod h1:qOqdlDfL+7v0/fyymB+OP497nIxJYSvX4MQWA8OoiXU= -github.com/tdewolff/parse/v2 v2.6.8 h1:mhNZXYCx//xG7Yq2e/kVLNZw4YfYmeHbhx+Zc0OvFMA= -github.com/tdewolff/parse/v2 v2.6.8/go.mod h1:XHDhaU6IBgsryfdnpzUXBlT6leW/l25yrFBTEb4eIyM= -github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0= -github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= -github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0= -github.com/tedsuo/ifrit v0.0.0-20220120221754-dd274de71113 h1:PnxSSxsUvOqMh7nslHscii/GV/Y9ZflmkZ2oEEEIGj4= -github.com/tedsuo/ifrit v0.0.0-20220120221754-dd274de71113/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0= -github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= -github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/tylertreat/BoomFilters v0.0.0-20181028192813-611b3dbe80e8 h1:7X4KYG3guI2mPQGxm/ZNNsiu4BjKnef0KG0TblMC+Z8= -github.com/tylertreat/BoomFilters v0.0.0-20181028192813-611b3dbe80e8/go.mod h1:OYRfF6eb5wY9VRFkXJH8FFBi3plw2v+giaIu7P054pM= -github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/urfave/cli v1.18.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= -github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= -github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= -github.com/weppos/publicsuffix-go v0.5.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA= -github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= -github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= -github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= -github.com/zmap/zcrypto v0.0.0-20190729165852-9051775e6a2e/go.mod h1:w7kd3qXHh8FNaczNjslXqvFQiv5mMWRXlL9klTUAHc8= -github.com/zmap/zlint v0.0.0-20190806154020-fd021b4cfbeb/go.mod h1:29UiAJNsiVdvTBFCJW8e3q6dcDbOoPkhMgttOSCIMMY= -go.etcd.io/bbolt v1.3.1-etcd.7/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd v0.5.0-alpha.5.0.20181228115726-23731bf9ba55/go.mod h1:weASp41xM3dk0YHg1s/W8ecdGP5G4teSTMBPpYAaUgA= -go.etcd.io/etcd v0.5.0-alpha.5.0.20210226220824-aa7126864d82 h1:RCaUKN0yRYKT2JzV9kH4u+D6l9VWcJMQ449QKRriFc8= -go.etcd.io/etcd v0.5.0-alpha.5.0.20210226220824-aa7126864d82/go.mod h1:WWRiAtnzDdtuCMxtFwME/Knea11a6fJgJkwtC1QSc/k= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= -go.mongodb.org/mongo-driver v1.0.4/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= -go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.13.0 h1:pa05sNT/P8OsIQ8mPZKTIyiBuzS/xDGLVx+DCt0y6Vs= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.13.0/go.mod h1:rqbht/LlhVBgn5+k3M5QK96K5Xb0DvXpMJ5SFQpY6uw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.13.0 h1:Any/nVxaoMq1T2w0W85d6w5COlLuCCgOYKQhJJWEMwQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.13.0/go.mod h1:46vAP6RWfNn7EKov73l5KBFlNxz8kYlxR1woU+bJ4ZY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.13.0 h1:Ntu7izEOIRHEgQNjbGc7j3eNtYMAiZfElJJ4JiiRDH4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.13.0/go.mod h1:wZ9SAjm2sjw3vStBhlCfMZWZusyOQrwrHOFo00jyMC4= -go.opentelemetry.io/otel/sdk v1.13.0 h1:BHib5g8MvdqS65yo2vV1s6Le42Hm6rrw08qU6yz5JaM= -go.opentelemetry.io/otel/sdk v1.13.0/go.mod h1:YLKPx5+6Vx/o1TCUYYs+bpymtkmazOMT6zoRrC7AQ7I= -go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= -go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= -go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= -go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.12.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= -golang.org/x/crypto v0.0.0-20180608092829-8ac0e0d97ce4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201026091529-146b70c837a4/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190614160838-b47fdc937951/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191009170203-06d7bd2c5f4f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200819091447-39769834ee22/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200131233409-575de47986ce/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180608181217-32ee49c4dd80/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= -gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg= -gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= -gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= -gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= -gopkg.in/olivere/elastic.v5 v5.0.80/go.mod h1:uhHoB4o3bvX5sorxBU29rPcmBQdV2Qfg0FBrx5D6pV0= -gopkg.in/olivere/elastic.v5 v5.0.81/go.mod h1:uhHoB4o3bvX5sorxBU29rPcmBQdV2Qfg0FBrx5D6pV0= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= -lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs= -moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= -rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/token-sdk/owner/main.go b/token-sdk/owner/main.go deleted file mode 100644 index 1471551e..00000000 --- a/token-sdk/owner/main.go +++ /dev/null @@ -1,114 +0,0 @@ -package main - -import ( - "net/http" - "os" - "os/signal" - "syscall" - - "github.com/hyperledger/fabric-samples/token-sdk/owner/routes" - "github.com/hyperledger/fabric-samples/token-sdk/owner/service" - - "github.com/hyperledger-labs/fabric-smart-client/pkg/api" - "github.com/hyperledger-labs/fabric-smart-client/pkg/node" - fabric "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/sdk" - viewregistry "github.com/hyperledger-labs/fabric-smart-client/platform/view" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/flogging" - tokensdk "github.com/hyperledger-labs/fabric-token-sdk/token/sdk" -) - -var logger = flogging.MustGetLogger("main") - -func main() { - dir := getEnv("CONF_DIR", "./conf/owner1") - port := getEnv("PORT", "9200") - - fsc := startFabricSmartClient(dir) - // Tell the service how to respond to other nodes when they initiate an action - registry := viewregistry.GetRegistry(fsc) - succeedOrPanic(registry.RegisterResponder(&service.AcceptCashView{}, "github.com/hyperledger/fabric-samples/token-sdk/issuer/service/IssueCashView")) - succeedOrPanic(registry.RegisterResponder(&service.AcceptCashView{}, &service.TransferView{})) - - controller := routes.Controller{Service: service.TokenService{FSC: fsc}} - err := routes.StartWebServer(port, controller, logger) - if err != nil { - if err == http.ErrServerClosed { - logger.Infof("Webserver closing, exiting...", err.Error()) - fsc.Stop() - } else { - logger.Fatalf("echo error - %s", err.Error()) - fsc.Stop() - os.Exit(1) - } - } -} - -type Node interface { - api.ServiceProvider - Stop() -} - -func startFabricSmartClient(confDir string) Node { - logger.Infof("Initializing Fabric Smart Client and Token SDK...") - fsc := node.NewFromConfPath(confDir) - succeedOrPanic(fsc.InstallSDK(fabric.NewSDK(fsc))) - succeedOrPanic(fsc.InstallSDK(tokensdk.NewSDK(fsc))) - succeedOrPanic(fsc.Start()) - - // Stop gracefully - go handleSignals((map[os.Signal]func(){ - syscall.SIGINT: func() { - logger.Info("Stopping FSC node...") - fsc.Stop() - os.Exit(130) - }, - syscall.SIGTERM: func() { - logger.Info("Stopping FSC node...") - fsc.Stop() - os.Exit(143) - }, - syscall.SIGSTOP: func() { - logger.Info("Stopping FSC node...") - fsc.Stop() - os.Exit(145) - }, - syscall.SIGHUP: func() { - logger.Info("Stopping FSC node...") - fsc.Stop() - os.Exit(129) - }, - })) - logger.Infof("FSC node is ready!") - - return fsc -} - -// getEnv returns an environment variable or the fallback -func getEnv(key, fallback string) string { - if value, ok := os.LookupEnv(key); ok { - return value - } - return fallback -} - -func succeedOrPanic(err error) { - if err != nil { - logger.Fatalf("Failed initializing Token SDK - %s", err.Error()) - os.Exit(1) - } -} - -func handleSignals(handlers map[os.Signal]func()) { - var signals []os.Signal - for sig := range handlers { - signals = append(signals, sig) - } - - signalChan := make(chan os.Signal, 1) - signal.Notify(signalChan, signals...) - - for sig := range signalChan { - logger.Infof("Received signal: %d (%s)", sig, sig) - handlers[sig]() - } -} diff --git a/token-sdk/owner/oapi-server.yaml b/token-sdk/owner/oapi-server.yaml deleted file mode 100644 index dd884978..00000000 --- a/token-sdk/owner/oapi-server.yaml +++ /dev/null @@ -1,11 +0,0 @@ -package: routes -generate: - echo-server: true - strict-server: true - models: true - embedded-spec: true -output-options: - include-tags: - - operations - - owner -output: owner/routes/routes.gen.go diff --git a/token-sdk/owner/routes/operations.go b/token-sdk/owner/routes/operations.go deleted file mode 100644 index 3aba80ed..00000000 --- a/token-sdk/owner/routes/operations.go +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package routes - -import ( - "context" -) - -type OperationsAPI struct{} - -// (GET /readyz) -func (c Controller) Readyz(ctx context.Context, request ReadyzRequestObject) (ReadyzResponseObject, error) { - // TODO: what defines readiness if the REST API is available after FSC? - return Readyz200JSONResponse{ - HealthSuccessJSONResponse: HealthSuccessJSONResponse{ - Message: "ok", - }, - }, nil -} - -// (GET /healthz) -func (c Controller) Healthz(ctx context.Context, request HealthzRequestObject) (HealthzResponseObject, error) { - // TODO: how to determine health? - return Healthz200JSONResponse{ - HealthSuccessJSONResponse: HealthSuccessJSONResponse{ - Message: "ok", - }, - }, nil -} diff --git a/token-sdk/owner/routes/routes.gen.go b/token-sdk/owner/routes/routes.gen.go deleted file mode 100644 index d1ccd4a1..00000000 --- a/token-sdk/owner/routes/routes.gen.go +++ /dev/null @@ -1,897 +0,0 @@ -// Package routes provides primitives to interact with the openapi HTTP API. -// -// Code generated by github.com/deepmap/oapi-codegen version v1.13.4 DO NOT EDIT. -package routes - -import ( - "bytes" - "compress/gzip" - "context" - "encoding/base64" - "encoding/json" - "fmt" - "net/http" - "net/url" - "path" - "strings" - "time" - - "github.com/deepmap/oapi-codegen/pkg/runtime" - "github.com/getkin/kin-openapi/openapi3" - "github.com/labstack/echo/v4" -) - -// Account Information about an account and its balance -type Account struct { - // Balance balance in base units for each currency - Balance []Amount `json:"balance"` - - // Id account id as registered at the Certificate Authority - Id string `json:"id"` -} - -// Amount The amount to issue, transfer or redeem. -type Amount struct { - // Code the code of the token - Code string `json:"code"` - - // Value value in base units (usually cents) - Value int64 `json:"value"` -} - -// Counterparty The counterparty in a Transfer or Issuance transaction. -type Counterparty struct { - Account string `json:"account"` - - // Node The node that holds the recipient account - Node string `json:"node"` -} - -// Error defines model for Error. -type Error struct { - // Message High level error message - Message string `json:"message"` - - // Payload Details about the error - Payload string `json:"payload"` -} - -// RedeemRequest Instructions to redeem tokens from an account -type RedeemRequest struct { - // Amount The amount to issue, transfer or redeem. - Amount Amount `json:"amount"` - - // Message optional message that will be visible to the auditor - Message *string `json:"message,omitempty"` -} - -// TransactionRecord A transaction -type TransactionRecord struct { - // Amount The amount to issue, transfer or redeem. - Amount Amount `json:"amount"` - - // Id transaction id - Id string `json:"id"` - - // Message user provided message - Message string `json:"message"` - - // Recipient the recipient of the transaction - Recipient string `json:"recipient"` - - // Sender the sender of the transaction - Sender string `json:"sender"` - - // Status Unknown | Pending | Confirmed | Deleted - Status string `json:"status"` - - // Timestamp timestamp in the format: "2018-03-20T09:12:28Z" - Timestamp time.Time `json:"timestamp"` -} - -// TransferRequest Instructions to issue or transfer tokens to an account -type TransferRequest struct { - // Amount The amount to issue, transfer or redeem. - Amount Amount `json:"amount"` - - // Counterparty The counterparty in a Transfer or Issuance transaction. - Counterparty Counterparty `json:"counterparty"` - - // Message optional message that will be sent and stored with the transfer transaction - Message *string `json:"message,omitempty"` -} - -// Code The token code to filter on -type Code = string - -// Id account id as registered at the Certificate Authority -type Id = string - -// AccountSuccess defines model for AccountSuccess. -type AccountSuccess struct { - Message string `json:"message"` - - // Payload Information about an account and its balance - Payload Account `json:"payload"` -} - -// AccountsSuccess defines model for AccountsSuccess. -type AccountsSuccess struct { - Message string `json:"message"` - Payload []Account `json:"payload"` -} - -// ErrorResponse defines model for ErrorResponse. -type ErrorResponse = Error - -// HealthSuccess defines model for HealthSuccess. -type HealthSuccess struct { - // Message ok - Message string `json:"message"` -} - -// RedeemSuccess defines model for RedeemSuccess. -type RedeemSuccess struct { - Message string `json:"message"` - - // Payload Transaction id - Payload string `json:"payload"` -} - -// TransactionsSuccess defines model for TransactionsSuccess. -type TransactionsSuccess struct { - Message string `json:"message"` - Payload []TransactionRecord `json:"payload"` -} - -// TransferSuccess defines model for TransferSuccess. -type TransferSuccess struct { - Message string `json:"message"` - - // Payload Transaction id - Payload string `json:"payload"` -} - -// OwnerAccountParams defines parameters for OwnerAccount. -type OwnerAccountParams struct { - Code *Code `form:"code,omitempty" json:"code,omitempty"` -} - -// RedeemJSONRequestBody defines body for Redeem for application/json ContentType. -type RedeemJSONRequestBody = RedeemRequest - -// TransferJSONRequestBody defines body for Transfer for application/json ContentType. -type TransferJSONRequestBody = TransferRequest - -// ServerInterface represents all server handlers. -type ServerInterface interface { - - // (GET /healthz) - Healthz(ctx echo.Context) error - // Get all accounts on this node and their balances - // (GET /owner/accounts) - OwnerAccounts(ctx echo.Context) error - // Get an account and their balances - // (GET /owner/accounts/{id}) - OwnerAccount(ctx echo.Context, id Id, params OwnerAccountParams) error - // Redeem (burn) tokens - // (POST /owner/accounts/{id}/redeem) - Redeem(ctx echo.Context, id Id) error - // Get all transactions for an account - // (GET /owner/accounts/{id}/transactions) - OwnerTransactions(ctx echo.Context, id Id) error - // Transfer tokens to another account - // (POST /owner/accounts/{id}/transfer) - Transfer(ctx echo.Context, id Id) error - - // (GET /readyz) - Readyz(ctx echo.Context) error -} - -// ServerInterfaceWrapper converts echo contexts to parameters. -type ServerInterfaceWrapper struct { - Handler ServerInterface -} - -// Healthz converts echo context to params. -func (w *ServerInterfaceWrapper) Healthz(ctx echo.Context) error { - var err error - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.Healthz(ctx) - return err -} - -// OwnerAccounts converts echo context to params. -func (w *ServerInterfaceWrapper) OwnerAccounts(ctx echo.Context) error { - var err error - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.OwnerAccounts(ctx) - return err -} - -// OwnerAccount converts echo context to params. -func (w *ServerInterfaceWrapper) OwnerAccount(ctx echo.Context) error { - var err error - // ------------- Path parameter "id" ------------- - var id Id - - err = runtime.BindStyledParameterWithLocation("simple", false, "id", runtime.ParamLocationPath, ctx.Param("id"), &id) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) - } - - // Parameter object where we will unmarshal all parameters from the context - var params OwnerAccountParams - // ------------- Optional query parameter "code" ------------- - - err = runtime.BindQueryParameter("form", true, false, "code", ctx.QueryParams(), ¶ms.Code) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter code: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.OwnerAccount(ctx, id, params) - return err -} - -// Redeem converts echo context to params. -func (w *ServerInterfaceWrapper) Redeem(ctx echo.Context) error { - var err error - // ------------- Path parameter "id" ------------- - var id Id - - err = runtime.BindStyledParameterWithLocation("simple", false, "id", runtime.ParamLocationPath, ctx.Param("id"), &id) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.Redeem(ctx, id) - return err -} - -// OwnerTransactions converts echo context to params. -func (w *ServerInterfaceWrapper) OwnerTransactions(ctx echo.Context) error { - var err error - // ------------- Path parameter "id" ------------- - var id Id - - err = runtime.BindStyledParameterWithLocation("simple", false, "id", runtime.ParamLocationPath, ctx.Param("id"), &id) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.OwnerTransactions(ctx, id) - return err -} - -// Transfer converts echo context to params. -func (w *ServerInterfaceWrapper) Transfer(ctx echo.Context) error { - var err error - // ------------- Path parameter "id" ------------- - var id Id - - err = runtime.BindStyledParameterWithLocation("simple", false, "id", runtime.ParamLocationPath, ctx.Param("id"), &id) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.Transfer(ctx, id) - return err -} - -// Readyz converts echo context to params. -func (w *ServerInterfaceWrapper) Readyz(ctx echo.Context) error { - var err error - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.Readyz(ctx) - return err -} - -// This is a simple interface which specifies echo.Route addition functions which -// are present on both echo.Echo and echo.Group, since we want to allow using -// either of them for path registration -type EchoRouter interface { - CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route -} - -// RegisterHandlers adds each server route to the EchoRouter. -func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") -} - -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. -func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { - - wrapper := ServerInterfaceWrapper{ - Handler: si, - } - - router.GET(baseURL+"/healthz", wrapper.Healthz) - router.GET(baseURL+"/owner/accounts", wrapper.OwnerAccounts) - router.GET(baseURL+"/owner/accounts/:id", wrapper.OwnerAccount) - router.POST(baseURL+"/owner/accounts/:id/redeem", wrapper.Redeem) - router.GET(baseURL+"/owner/accounts/:id/transactions", wrapper.OwnerTransactions) - router.POST(baseURL+"/owner/accounts/:id/transfer", wrapper.Transfer) - router.GET(baseURL+"/readyz", wrapper.Readyz) - -} - -type AccountSuccessJSONResponse struct { - Message string `json:"message"` - - // Payload Information about an account and its balance - Payload Account `json:"payload"` -} - -type AccountsSuccessJSONResponse struct { - Message string `json:"message"` - Payload []Account `json:"payload"` -} - -type ErrorResponseJSONResponse Error - -type HealthSuccessJSONResponse struct { - // Message ok - Message string `json:"message"` -} - -type RedeemSuccessJSONResponse struct { - Message string `json:"message"` - - // Payload Transaction id - Payload string `json:"payload"` -} - -type TransactionsSuccessJSONResponse struct { - Message string `json:"message"` - Payload []TransactionRecord `json:"payload"` -} - -type TransferSuccessJSONResponse struct { - Message string `json:"message"` - - // Payload Transaction id - Payload string `json:"payload"` -} - -type HealthzRequestObject struct { -} - -type HealthzResponseObject interface { - VisitHealthzResponse(w http.ResponseWriter) error -} - -type Healthz200JSONResponse struct{ HealthSuccessJSONResponse } - -func (response Healthz200JSONResponse) VisitHealthzResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type Healthz503JSONResponse struct{ ErrorResponseJSONResponse } - -func (response Healthz503JSONResponse) VisitHealthzResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(503) - - return json.NewEncoder(w).Encode(response) -} - -type OwnerAccountsRequestObject struct { -} - -type OwnerAccountsResponseObject interface { - VisitOwnerAccountsResponse(w http.ResponseWriter) error -} - -type OwnerAccounts200JSONResponse struct{ AccountsSuccessJSONResponse } - -func (response OwnerAccounts200JSONResponse) VisitOwnerAccountsResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type OwnerAccountsdefaultJSONResponse struct { - Body Error - StatusCode int -} - -func (response OwnerAccountsdefaultJSONResponse) VisitOwnerAccountsResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) -} - -type OwnerAccountRequestObject struct { - Id Id `json:"id"` - Params OwnerAccountParams -} - -type OwnerAccountResponseObject interface { - VisitOwnerAccountResponse(w http.ResponseWriter) error -} - -type OwnerAccount200JSONResponse struct{ AccountSuccessJSONResponse } - -func (response OwnerAccount200JSONResponse) VisitOwnerAccountResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type OwnerAccountdefaultJSONResponse struct { - Body Error - StatusCode int -} - -func (response OwnerAccountdefaultJSONResponse) VisitOwnerAccountResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) -} - -type RedeemRequestObject struct { - Id Id `json:"id"` - Body *RedeemJSONRequestBody -} - -type RedeemResponseObject interface { - VisitRedeemResponse(w http.ResponseWriter) error -} - -type Redeem200JSONResponse struct{ RedeemSuccessJSONResponse } - -func (response Redeem200JSONResponse) VisitRedeemResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type RedeemdefaultJSONResponse struct { - Body Error - StatusCode int -} - -func (response RedeemdefaultJSONResponse) VisitRedeemResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) -} - -type OwnerTransactionsRequestObject struct { - Id Id `json:"id"` -} - -type OwnerTransactionsResponseObject interface { - VisitOwnerTransactionsResponse(w http.ResponseWriter) error -} - -type OwnerTransactions200JSONResponse struct { - TransactionsSuccessJSONResponse -} - -func (response OwnerTransactions200JSONResponse) VisitOwnerTransactionsResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type OwnerTransactionsdefaultJSONResponse struct { - Body Error - StatusCode int -} - -func (response OwnerTransactionsdefaultJSONResponse) VisitOwnerTransactionsResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) -} - -type TransferRequestObject struct { - Id Id `json:"id"` - Body *TransferJSONRequestBody -} - -type TransferResponseObject interface { - VisitTransferResponse(w http.ResponseWriter) error -} - -type Transfer200JSONResponse struct{ TransferSuccessJSONResponse } - -func (response Transfer200JSONResponse) VisitTransferResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type TransferdefaultJSONResponse struct { - Body Error - StatusCode int -} - -func (response TransferdefaultJSONResponse) VisitTransferResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) -} - -type ReadyzRequestObject struct { -} - -type ReadyzResponseObject interface { - VisitReadyzResponse(w http.ResponseWriter) error -} - -type Readyz200JSONResponse struct{ HealthSuccessJSONResponse } - -func (response Readyz200JSONResponse) VisitReadyzResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) -} - -type Readyz503JSONResponse struct{ ErrorResponseJSONResponse } - -func (response Readyz503JSONResponse) VisitReadyzResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(503) - - return json.NewEncoder(w).Encode(response) -} - -// StrictServerInterface represents all server handlers. -type StrictServerInterface interface { - - // (GET /healthz) - Healthz(ctx context.Context, request HealthzRequestObject) (HealthzResponseObject, error) - // Get all accounts on this node and their balances - // (GET /owner/accounts) - OwnerAccounts(ctx context.Context, request OwnerAccountsRequestObject) (OwnerAccountsResponseObject, error) - // Get an account and their balances - // (GET /owner/accounts/{id}) - OwnerAccount(ctx context.Context, request OwnerAccountRequestObject) (OwnerAccountResponseObject, error) - // Redeem (burn) tokens - // (POST /owner/accounts/{id}/redeem) - Redeem(ctx context.Context, request RedeemRequestObject) (RedeemResponseObject, error) - // Get all transactions for an account - // (GET /owner/accounts/{id}/transactions) - OwnerTransactions(ctx context.Context, request OwnerTransactionsRequestObject) (OwnerTransactionsResponseObject, error) - // Transfer tokens to another account - // (POST /owner/accounts/{id}/transfer) - Transfer(ctx context.Context, request TransferRequestObject) (TransferResponseObject, error) - - // (GET /readyz) - Readyz(ctx context.Context, request ReadyzRequestObject) (ReadyzResponseObject, error) -} - -type StrictHandlerFunc = runtime.StrictEchoHandlerFunc -type StrictMiddlewareFunc = runtime.StrictEchoMiddlewareFunc - -func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { - return &strictHandler{ssi: ssi, middlewares: middlewares} -} - -type strictHandler struct { - ssi StrictServerInterface - middlewares []StrictMiddlewareFunc -} - -// Healthz operation middleware -func (sh *strictHandler) Healthz(ctx echo.Context) error { - var request HealthzRequestObject - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.Healthz(ctx.Request().Context(), request.(HealthzRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "Healthz") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(HealthzResponseObject); ok { - return validResponse.VisitHealthzResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// OwnerAccounts operation middleware -func (sh *strictHandler) OwnerAccounts(ctx echo.Context) error { - var request OwnerAccountsRequestObject - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.OwnerAccounts(ctx.Request().Context(), request.(OwnerAccountsRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "OwnerAccounts") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(OwnerAccountsResponseObject); ok { - return validResponse.VisitOwnerAccountsResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// OwnerAccount operation middleware -func (sh *strictHandler) OwnerAccount(ctx echo.Context, id Id, params OwnerAccountParams) error { - var request OwnerAccountRequestObject - - request.Id = id - request.Params = params - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.OwnerAccount(ctx.Request().Context(), request.(OwnerAccountRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "OwnerAccount") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(OwnerAccountResponseObject); ok { - return validResponse.VisitOwnerAccountResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// Redeem operation middleware -func (sh *strictHandler) Redeem(ctx echo.Context, id Id) error { - var request RedeemRequestObject - - request.Id = id - - var body RedeemJSONRequestBody - if err := ctx.Bind(&body); err != nil { - return err - } - request.Body = &body - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.Redeem(ctx.Request().Context(), request.(RedeemRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "Redeem") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(RedeemResponseObject); ok { - return validResponse.VisitRedeemResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// OwnerTransactions operation middleware -func (sh *strictHandler) OwnerTransactions(ctx echo.Context, id Id) error { - var request OwnerTransactionsRequestObject - - request.Id = id - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.OwnerTransactions(ctx.Request().Context(), request.(OwnerTransactionsRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "OwnerTransactions") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(OwnerTransactionsResponseObject); ok { - return validResponse.VisitOwnerTransactionsResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// Transfer operation middleware -func (sh *strictHandler) Transfer(ctx echo.Context, id Id) error { - var request TransferRequestObject - - request.Id = id - - var body TransferJSONRequestBody - if err := ctx.Bind(&body); err != nil { - return err - } - request.Body = &body - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.Transfer(ctx.Request().Context(), request.(TransferRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "Transfer") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(TransferResponseObject); ok { - return validResponse.VisitTransferResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// Readyz operation middleware -func (sh *strictHandler) Readyz(ctx echo.Context) error { - var request ReadyzRequestObject - - handler := func(ctx echo.Context, request interface{}) (interface{}, error) { - return sh.ssi.Readyz(ctx.Request().Context(), request.(ReadyzRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "Readyz") - } - - response, err := handler(ctx, request) - - if err != nil { - return err - } else if validResponse, ok := response.(ReadyzResponseObject); ok { - return validResponse.VisitReadyzResponse(ctx.Response()) - } else if response != nil { - return fmt.Errorf("Unexpected response type: %T", response) - } - return nil -} - -// Base64 encoded, gzipped, json marshaled Swagger object -var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+RaW2/bOBb+KwR3H2YANZKdzU1vnXawLfZhB2kKLKbNAy0eW5xQpEpSznpT//cFL7rL", - "l6SZou08JTapw3O+850b5QecyaKUAoTROH3AJVGkAAPKfcokBfuXCZziTxWoDY6wIAXg1K9FWGc5FMRu", - "oqAzxUrDpN19kwMy8g4EshuRkWjJuAGFpMARhv+SouRWzK/vr/+DI2w2pf2kjWJihbfbCDPanFwSk7cH", - "M4ojrOBTxRRQnBpVwW41SJbJShjEKCIaKVgxbUABRcQgkwN6BcqwJcuIAfSyMrlUzGx6ChLOMpjQcGuV", - "0KUUGhxWL/1J76osAx3QEwaEsf+SsuT2ECZF/Ie2mj10VC6VLK0eXlABWpOVw31wZoRLsuGSOGT+rmCJ", - "U/y3uHVg7EXqOOiCvZI1Uh8a0a2g28YwufgDMuMN62MYTEK1uVaRcIL+auYyA4U+2u7GKqIU2fyJOPyq", - "lFTX9RePQWGfHU7qlApuoafAGyDc5E9xQ0Pxjg+wvHO47/JQXxt5Nxm5U0g/Fd9roADFs7KsDW2Xn+x5", - "9gygY2N6DBzkN0WEJpn9hFxGasVeZPNzoOdwBsnZ8oLC5Yxczs+vZovz88UsOb+is7Pkgl4BXZ5mF4uL", - "SyCzJbm6PDu7ADi7WPzjaFC/nL4dK/SfBXLnCKTAKAbrg1gfFe0d5a8hk4p+xbh3Zy9BHQ/aZLiZIMZW", - "JM/Gjm7PwKRt9KV59wDrvw5RGzO6lXas3VuxlKpwsCOykJVBRKC6AyCCImY0WhBOhKvoHY/UX6Yf6qan", - "bkzWhFeA01mSJMk2albfv3vdWZ0nyfbWtyyhXxgl0eaEodJhATGBFkQDqoTVcikVApLlKKuUApHZnuS4", - "ElhMV8C6ofpa7VGfCI4rNQRjDkQ4qD3ZRhK3ZltIpnUFEaqjBrlaaJP3Sd+du1w48krd4FJYkoqb9pm+", - "FhYK18bKpYPFhepUCgtHDa1wXw88/FOlK8L5BmXWfz/jCHvy2g5XmHNbBQomWFEVOE2ao5gwsAI1Ajh0", - "4/78KYBfWQxBlUSZzTTMWWeH1ZWgmw7Ob7WuHE87+XyAOqnjsiGF8H6Q9wLUbBwTpA3kEZKi8cxQT+Hm", - "iZwYlEtOtXOIgoyVDGyYB5mHGCk8YPX2Kch8F7YrdYNrxcYZLsWP6KDesFWOOKyBo6G845PyazCEcR1S", - "noXDyXqW7Fx3YNfwqQI9mXO1UVUo70aGeAzFDC2VLDpJGI8Y0IT9cTltdyvq/iG8BtAT5J5xjhaA1kyz", - "BXdTqIWHVJSZIwAK2k2hMu49Riq97IbKIFIas/dkKpuvZ/PTjtHYDb6B6bZ0yIWdwEFQUJ2o04aYSuMU", - "v5JiyVTobFkB2pCixCmeJ7PLF8npi3lyk1yls3k6v/x9Ijof6Zup+mIO9At7PFppUKhUcs0o0H1x0UHk", - "YSJvt6mhTt49r4zE1XBOyfJrxwoKbhgKei/uhLwX6DP6DQRlYoU+o8ZT6DN6DRzMdIfcceJIvXrJpm6r", - "na8mKfo46e6PuFtwKDHwwko4rpAHiLrQRzVduko2GER75sC2lz46x7g2wBalphEI6cbI50w22aBk7nuq", - "V16fnqg0hE5VG2nbsHtm8pZrztJ9pBs1BR2lot3pzF23iaWcQN43XLbQdtouq2Avz5+gX0h2BxQtNogg", - "yqw+i8oARRzoClT0UZQKNKi1pXup2JpkG1Rp++l3UBL9S8h7txX9pqRc6hPHI+M6zJt6LlqD0l6t2Uli", - "QZYlCFIynOLTk+Tk1BUykztfxyHHx4EMOn5gdOuGV1Brd735YdQMN2WhUhynODemTOOYy4zwXGqTXiVJ", - "EpOSxetZjLe322jHMXF35n3+M3N35fM/K3gFjs+W5W7seWv7jzdhfXBBOU+SXSxu9sX966RthM+S08NP", - "9W/BLJ0MWVlzW800trrrqiiI2uAUX4OplNBoniSI+Xzq+GEnIY28iS6SYhftyv/ZD6bfuQfLWQ/LrjqO", - "6NNpxOrgOtjGyTuR/7fdVl+NPgn/4b2qG47DbPJ4L+zhne0VXCD7JmIXYvMuYtFQSkYUl9qJoUTsEXO6", - "E/h/gkGE8xptjaQtX0z7Nt9KNjkwVY/tFtWGWxZtT6tv084xc5osdJA+Lpm172I+TDu/3RIz6hQ/sMv1", - "m9YDT6bmX4uZ/fujH46KsS/j7nZQ6glK+unvSWS89c0IaPOLpJtnezfSn0e3/Z7HqAq2TyF3/z3DD89t", - "by76aVEp8XN78/zd0PmgLbv4PuzMdufh7quRp/P/sTyceiHzl+kBeq+KllL1h7nvPtfW89PubFtPwt9S", - "vh1O58+VcYdv0H54lt9MXVZIk9uB+vsj+SMtszGhgNDN7rH12i9/x1OrM9BZn2VQGpQRzvUhej7uAiD6", - "spk3+sY4FAAfXZ2HGkDWhHESbu5bpMIPweovxvpMPt8gVf+OzH8+8mkXkOiecA5utA9CfJyOZbwLrPAX", - "GeHGjFAmLEHbp1uebW+3/w8AAP//KMjhw4wnAAA=", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode -func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) - if err != nil { - return nil, fmt.Errorf("error base64 decoding spec: %w", err) - } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } - var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } - - return buf.Bytes(), nil -} - -var rawSpec = decodeSpecCached() - -// a naive cached of a decoded swagger spec -func decodeSpecCached() func() ([]byte, error) { - data, err := decodeSpec() - return func() ([]byte, error) { - return data, err - } -} - -// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. -func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { - res := make(map[string]func() ([]byte, error)) - if len(pathToFile) > 0 { - res[pathToFile] = rawSpec - } - - return res -} - -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { - resolvePath := PathToRawSpec("") - - loader := openapi3.NewLoader() - loader.IsExternalRefsAllowed = true - loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { - pathToFile := url.String() - pathToFile = path.Clean(pathToFile) - getSpec, ok := resolvePath[pathToFile] - if !ok { - err1 := fmt.Errorf("path not found: %s", pathToFile) - return nil, err1 - } - return getSpec() - } - var specData []byte - specData, err = rawSpec() - if err != nil { - return - } - swagger, err = loader.LoadFromData(specData) - if err != nil { - return - } - return -} diff --git a/token-sdk/owner/routes/routes.go b/token-sdk/owner/routes/routes.go deleted file mode 100644 index 9e267393..00000000 --- a/token-sdk/owner/routes/routes.go +++ /dev/null @@ -1,191 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package routes - -import ( - "context" - "fmt" - - "github.com/hyperledger/fabric-samples/token-sdk/owner/service" -) - -type Controller struct { - Service service.TokenService -} - -// Transfer tokens to another account -// (POST /owner/accounts/{id}/transfer) -func (c Controller) Transfer(ctx context.Context, request TransferRequestObject) (TransferResponseObject, error) { - code := request.Body.Amount.Code - value := uint64(request.Body.Amount.Value) - sender := request.Id - recipient := request.Body.Counterparty.Account - recipientNode := request.Body.Counterparty.Node - var message string - if request.Body.Message != nil { - message = *request.Body.Message - } - - txID, err := c.Service.TransferTokens(code, value, sender, recipient, recipientNode, message) - if err != nil { - return TransferdefaultJSONResponse{ - Body: Error{ - Message: "can't transfer funds", - Payload: err.Error(), - }, - StatusCode: 500, - }, nil - } - return Transfer200JSONResponse{ - TransferSuccessJSONResponse: TransferSuccessJSONResponse{ - Message: fmt.Sprintf("%s transferred %d %s to %s", sender, value, code, recipient), - Payload: txID, - }, - }, nil -} - -// Get all accounts on this node and their balances -// (GET /owner/accounts) -func (c Controller) OwnerAccounts(ctx context.Context, request OwnerAccountsRequestObject) (OwnerAccountsResponseObject, error) { - balances, err := c.Service.GetAllBalances() - if err != nil { - return OwnerAccountsdefaultJSONResponse{ - Body: Error{ - Message: "can't get accounts", - Payload: err.Error(), - }, - StatusCode: 500, - }, nil - } - - acc := []Account{} - for wallet, balance := range balances { - amounts := []Amount{} - for typ, val := range balance { - amounts = append(amounts, Amount{ - Code: typ, - Value: val, - }) - } - acc = append(acc, Account{ - Id: wallet, - Balance: amounts, - }) - } - return OwnerAccounts200JSONResponse{ - AccountsSuccessJSONResponse: AccountsSuccessJSONResponse{ - Message: fmt.Sprintf("got %d accounts", len(acc)), - Payload: acc, - }, - }, err -} - -// Get an account and their balances -// (GET /owner/accounts/{id}) -func (c Controller) OwnerAccount(ctx context.Context, request OwnerAccountRequestObject) (OwnerAccountResponseObject, error) { - var code string - if request.Params.Code != nil { - code = *request.Params.Code - } - balance, err := c.Service.GetBalance(request.Id, code) - if err != nil { - return OwnerAccountdefaultJSONResponse{ - Body: Error{ - Message: "can't get account", - Payload: err.Error(), - }, - StatusCode: 500, - }, nil - } - - amounts := []Amount{} - for typ, val := range balance { - amounts = append(amounts, Amount{ - Code: typ, - Value: val, - }) - } - return OwnerAccount200JSONResponse{ - AccountSuccessJSONResponse: AccountSuccessJSONResponse{ - Message: fmt.Sprintf("got balances for %s", request.Id), - Payload: Account{ - Id: request.Id, - Balance: amounts, - }, - }, - }, nil -} - -// Get all transactions for an account -// (GET /owner/accounts/{id}/transactions) -func (c Controller) OwnerTransactions(ctx context.Context, request OwnerTransactionsRequestObject) (OwnerTransactionsResponseObject, error) { - var history []service.TransactionHistoryItem - var err error - - history, err = c.Service.GetHistory(request.Id) - if err != nil { - return OwnerTransactionsdefaultJSONResponse{ - Body: Error{ - Message: "can't get history", - Payload: err.Error(), - }, - StatusCode: 500, - }, nil - } - - pl := []TransactionRecord{} - for _, tx := range history { - pl = append(pl, TransactionRecord{ - Amount: Amount{ - Code: tx.TokenType, - Value: tx.Amount, - }, - Id: tx.TxID, - Recipient: tx.Recipient, - Sender: tx.Sender, - Status: tx.Status, - Timestamp: tx.Timestamp, - Message: tx.Message, - }) - } - return OwnerTransactions200JSONResponse{ - TransactionsSuccessJSONResponse: TransactionsSuccessJSONResponse{ - Message: fmt.Sprintf("got %d transactions for %s", len(pl), request.Id), - Payload: pl, - }, - }, nil -} - -// Redeem (burn) tokens -// (POST /owner/accounts/{id}/redeem) -func (c Controller) Redeem(ctx context.Context, request RedeemRequestObject) (RedeemResponseObject, error) { - code := request.Body.Amount.Code - value := uint64(request.Body.Amount.Value) - account := request.Id - var message string - if request.Body.Message != nil { - message = *request.Body.Message - } - - txID, err := c.Service.RedeemTokens(code, value, account, message) - if err != nil { - return RedeemdefaultJSONResponse{ - Body: Error{ - Message: "can't redeem tokens", - Payload: err.Error(), - }, - StatusCode: 500, - }, nil - } - - return Redeem200JSONResponse{ - RedeemSuccessJSONResponse: RedeemSuccessJSONResponse{ - Message: fmt.Sprintf("%s redeemed %d %s", account, value, code), - Payload: txID, - }, - }, nil -} diff --git a/token-sdk/owner/routes/server.go b/token-sdk/owner/routes/server.go deleted file mode 100644 index f3e639b2..00000000 --- a/token-sdk/owner/routes/server.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package routes - -import ( - "fmt" - "log" - "os" - - oapimiddleware "github.com/deepmap/oapi-codegen/pkg/middleware" - "github.com/labstack/echo/v4" - middleware "github.com/labstack/echo/v4/middleware" -) - -type Logger interface { - Infof(template string, args ...interface{}) - Debugf(template string, args ...interface{}) - Warnf(template string, args ...interface{}) - Errorf(template string, args ...interface{}) - Fatalf(template string, args ...interface{}) -} - -// Start web server on the main thread. It exits the application if it fails setting up. -func StartWebServer(port string, routesImplementation StrictServerInterface, logger Logger) error { - e := echo.New() - baseURL := "/api/v1" - - handler := NewStrictHandler(routesImplementation, nil) - RegisterHandlersWithBaseURL(e, handler, baseURL) - - // Request validator - swagger, err := GetSwagger() - if err != nil { - log.Fatalf("Error loading swagger spec\n: %s", err) - os.Exit(1) - } - swagger.Servers = nil - e.Group(baseURL).Use(oapimiddleware.OapiRequestValidator(swagger)) - - e.Use(middleware.CORS()) - e.Use(middleware.RequestID()) - e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{ - Skipper: func(c echo.Context) bool { - return c.Path() == "/api/v1/healthz" || c.Path() == "/api/v1/readyz" - }, - LogRequestID: true, LogMethod: true, LogURI: true, LogStatus: true, LogLatency: true, - LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error { - if v.Status < 400 { - logger.Infof("%d %s %s %s [%s]", v.Status, v.Method, v.URI, v.Latency.String(), v.RequestID) - } else if v.Status >= 400 && v.Status < 500 { - logger.Warnf("%d %s %s %s [%s]", v.Status, v.Method, v.URI, v.Latency.String(), v.RequestID) - } else { - logger.Errorf("%d %s %s %s [%s]", v.Status, v.Method, v.URI, v.Latency.String(), v.RequestID) - } - return nil - }, - })) - - // Start REST API server - return e.Start(fmt.Sprintf("0.0.0.0:%s", port)) -} diff --git a/token-sdk/owner/service/accept.go b/token-sdk/owner/service/accept.go deleted file mode 100644 index f61ba87b..00000000 --- a/token-sdk/owner/service/accept.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package service - -import ( - "github.com/hyperledger-labs/fabric-smart-client/pkg/api" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/flogging" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx" - "github.com/pkg/errors" -) - -var logger = flogging.MustGetLogger("owner") - -type TokenService struct { - FSC api.ServiceProvider -} - -type AcceptCashView struct{} - -func (v *AcceptCashView) Call(context view.Context) (interface{}, error) { - logger.Infof("incoming session from [%s]", context.Session().Info().Endpoint) - - // The recipient of a token (issued or transfer) responds, as first operation, - // to a request for a recipient. The recipient identity is a new nym key and not the main key of the wallet. - id, err := ttx.RespondRequestRecipientIdentity(context) - if err != nil { - return "", errors.Wrap(err, "failed to respond to identity request") - } - logger.Infof("shared recipient id: [%s]", id.UniqueID()) - - // After we responded with the recipient identity, the counterparty assembles - // the transaction that assigns the tokens to the recipient id and sends it to us. - tx, err := ttx.ReceiveTransaction(context) - if err != nil { - err = errors.Wrap(err, "failed to receive tokens") - logger.Error(err.Error()) - return "", err - } - logger.Infof("transaction received: [%s]", tx.ID()) - - // The recipient can perform any check on the transaction as required by the business process - // In particular, here, the recipient checks that the transaction contains at least one output, and - // that there is at least one output that names the recipient. (The recipient is receiving something. - outputs, err := tx.Outputs() - if err != nil { - err = errors.Wrap(err, "failed getting outputs") - logger.Error(err.Error()) - return "", err - } - if outputs.Count() <= 0 { - err = errors.New("outputs should be more than zero") - logger.Error(err.Error()) - return "", err - } - if outputs.ByRecipient(id).Count() <= 0 { - err = errors.New("outputs to me should be more than zero") - logger.Error(err.Error()) - return "", err - } - - // If everything is fine, the recipient accepts and sends back her signature. - // Notice that, a signature from the recipient might or might not be required to make the transaction valid. - // This depends on the driver implementation. - _, err = context.RunView(ttx.NewAcceptView(tx)) - if err != nil { - return "", errors.Wrap(err, "failed to accept new tokens") - } - logger.Infof("transaction accepted: [%s]", tx.ID()) - - // Before completing, the recipient waits for finality of the transaction - _, err = context.RunView(ttx.NewFinalityView(tx)) - if err != nil { - return "", errors.Wrap(err, "new tokens were not committed") - } - logger.Infof("transaction committed: [%s]", tx.ID()) - - return nil, nil -} diff --git a/token-sdk/owner/service/balance.go b/token-sdk/owner/service/balance.go deleted file mode 100644 index 6533528e..00000000 --- a/token-sdk/owner/service/balance.go +++ /dev/null @@ -1,69 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package service - -import ( - "strconv" - - "github.com/hyperledger-labs/fabric-token-sdk/token" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx" - "github.com/pkg/errors" -) - -// SERVICE -type BalanceByWallet map[string]ValueByTokenType -type ValueByTokenType map[string]int64 - -// GetAllBalances returns a map of all wallets with their balances per token type -func (s TokenService) GetAllBalances() (walletBalance BalanceByWallet, err error) { - walletBalance = make(BalanceByWallet) - wm := token.GetManagementService(s.FSC).WalletManager() - wallets, err := wm.OwnerWalletIDs() - if err != nil { - return walletBalance, errors.Wrap(err, "can't get list of wallets") - } - logger.Infof("getting balances for %v", wallets) - for _, w := range wallets { - b, err := s.GetBalance(w, "") - if err != nil { - logger.Error(err) - return walletBalance, err - } - walletBalance[w] = b - } - - return -} - -// GetBalance returns the balances per token type of a wallet -func (s TokenService) GetBalance(wallet string, tokenType string) (typeVal ValueByTokenType, err error) { - typeVal = make(ValueByTokenType) - - // Tokens owned by identities in this wallet will be listed - if wallet == "" { - return typeVal, errors.New("no wallet id provided") - } - w := ttx.GetWallet(s.FSC, wallet) - if w == nil { - return nil, errors.Errorf("wallet not found: %s", wallet) - } - - unspentTokens, err := w.ListUnspentTokens(ttx.WithType(tokenType)) - if len(unspentTokens.Tokens) == 0 { - return typeVal, nil - } - // Add the value of all unspent tokens in the wallet - for _, token := range unspentTokens.Tokens { - val, err := strconv.ParseInt(token.Quantity, 0, 64) - if err != nil { - return typeVal, errors.Wrap(err, "Error parsing token "+token.Id.String()) - } - typeVal[token.Type] += val - } - - return -} diff --git a/token-sdk/owner/service/history.go b/token-sdk/owner/service/history.go deleted file mode 100644 index 3f21ca0a..00000000 --- a/token-sdk/owner/service/history.go +++ /dev/null @@ -1,93 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package service - -import ( - "time" - - "github.com/hyperledger-labs/fabric-token-sdk/token" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/ttxdb" - "github.com/pkg/errors" -) - -// SERVICE - -type TransactionHistoryItem struct { - // TxID is the transaction ID - TxID string - // ActionType is the type of action performed by this transaction record - ActionType int - // SenderEID is the enrollment ID of the account that is sending tokens - Sender string - // RecipientEID is the enrollment ID of the account that is receiving tokens - Recipient string - // TokenType is the type of token - TokenType string - // Amount is positive if tokens are received. Negative otherwise - Amount int64 - // Timestamp is the time the transaction was submitted to the db - Timestamp time.Time - // Status is the status of the transaction - Status string - // Message is the user message sent with the transaction. It comes from - // the ApplicationMetadata and is sent in the transient field - Message string -} - -// GetHistory returns the full transaction history for an owner. -func (s TokenService) GetHistory(wallet string) (txs []TransactionHistoryItem, err error) { - // Get query executor - owner := ttx.NewOwner(s.FSC, token.GetManagementService(s.FSC)) - aqe := owner.NewQueryExecutor() - defer aqe.Done() - it, err := aqe.Transactions(ttxdb.QueryTransactionsParams{ - SenderWallet: wallet, - RecipientWallet: wallet, - }) - if err != nil { - return txs, errors.Wrap(err, "failed querying transactions from db") - } - defer it.Close() - - // we need transaction info to get the transient field (application metadata) - tip := ttx.NewTransactionInfoProvider(s.FSC, token.GetManagementService(s.FSC)) - if tip == nil { - return txs, errors.New("failed to get transactionInfoProvider") - } - - // Return the list of accepted transactions - for { - tx, err := it.Next() - if err != nil { - return txs, errors.Wrap(err, "failed iterating over transactions") - } - if tx == nil { - break - } - transaction := TransactionHistoryItem{ - TxID: tx.TxID, - ActionType: int(tx.ActionType), - Sender: tx.SenderEID, - Recipient: tx.RecipientEID, - TokenType: tx.TokenType, - Amount: tx.Amount.Int64(), - Timestamp: tx.Timestamp.UTC(), - Status: string(tx.Status), - } - // set user provided message from transient field - ti, err := tip.TransactionInfo(tx.TxID) - if err != nil { - return txs, errors.Wrapf(err, "cannot get transaction info for %s", tx.TxID) - } - if ti.ApplicationMetadata != nil && string(ti.ApplicationMetadata["message"]) != "" { - transaction.Message = string(ti.ApplicationMetadata["message"]) - } - txs = append(txs, transaction) - } - return -} diff --git a/token-sdk/owner/service/redeem.go b/token-sdk/owner/service/redeem.go deleted file mode 100644 index 5644cc18..00000000 --- a/token-sdk/owner/service/redeem.go +++ /dev/null @@ -1,130 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package service - -import ( - viewregistry "github.com/hyperledger-labs/fabric-smart-client/platform/view" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" - "github.com/pkg/errors" - - token2 "github.com/hyperledger-labs/fabric-token-sdk/token" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx" - "github.com/hyperledger-labs/fabric-token-sdk/token/token" -) - -// SERVICE - -// Redeem burns an amount of a certain token. It prepares the transaction, -// gets it approved by the auditor and sends it to the blockchain for endorsement and commit. -func (s TokenService) RedeemTokens(tokenType string, quantity uint64, wallet string, message string) (txID string, err error) { - logger.Infof("redeeming %d %s from [%s] with message [%s]", quantity, tokenType, wallet, message) - res, err := viewregistry.GetManager(s.FSC).InitiateView(&RedeemView{ - Redeem: &Redeem{ - Wallet: wallet, - TokenType: tokenType, - Quantity: quantity, - Message: message, - }, - }) - if err != nil { - logger.Error(err) - return - } - txID, ok := res.(string) - if !ok { - err = errors.New("cannot parse redeem response") - logger.Error(err) - return - } - - return -} - -// VIEW - -// Redeem contains the input information for a redeem operation -type Redeem struct { - // Wallet is the identifier of the wallet that owns the tokens to redeem - Wallet string - // TokenIDs contains a list of token ids to redeem. If empty, tokens are selected on the spot. - TokenIDs []*token.ID - // TokenType of tokens to redeem - TokenType string - // Quantity to redeem - Quantity uint64 - // Message is an optional user message sent with the transaction. - // It's stored in the ApplicationMetadata and is sent in the transient field. - Message string -} - -type RedeemView struct { - *Redeem -} - -func (v *RedeemView) Call(context view.Context) (interface{}, error) { - // specify the auditor and create the envelope for the transaction - logger.Debug("getting identity of auditor") - auditor := viewregistry.GetIdentityProvider(context).Identity("auditor") - if auditor == nil { - return "", errors.New("auditor identity not found") - } - tx, err := ttx.NewTransaction(context, nil, ttx.WithAuditor(auditor)) - if err != nil { - return "", errors.Wrap(err, "failed creating transaction") - } - - // The sender will select tokens owned by this wallet - logger.Debug("loading wallet [%s]", v.Wallet) - senderWallet := ttx.GetWallet(context, v.Wallet) - if senderWallet == nil { - return "", errors.Errorf("sender wallet [%s] not found", v.Wallet) - } - - // the sender adds a new redeem operation to the transaction following the instruction received. - // Notice the use of `token2.WithTokenIDs(t.TokenIDs...)`. If t.TokenIDs is not empty, the Redeem - // function uses those tokens, otherwise the tokens will be selected on the spot. - // Token selection happens internally by invoking the default token selector: - // selector, err := tx.TokenService().SelectorManager().NewSelector(tx.ID()) - // if err != nil { - // return "", errors.Wrap(err, "failed getting selector") - // } - // selector.Select(wallet, amount, tokenType) - // It is also possible to pass a custom token selector to the Redeem function by using the relative opt: - // token2.WithTokenSelector(selector). - err = tx.Redeem( - senderWallet, - v.TokenType, - v.Quantity, - token2.WithTokenIDs(v.TokenIDs...), - ) - if err != nil { - return "", errors.Wrap(err, "failed adding tokens to redeem") - } - - // You can set any metadata you want. It is shared with the - // auditor but not committed to the ledger. - if v.Message != "" { - tx.SetApplicationMetadata("message", []byte(v.Message)) - } - - // The sender is ready to collect all the required signatures. - // In this case, the sender's and the auditor's signatures. - // Invoke the Token Chaincode to collect endorsements on the Token Request and prepare the relative transaction. - // This is all done in one shot running the following view. - logger.Infof("collecting signatures and submitting transaction to chaincode: [%s]", tx.ID()) - _, err = context.RunView(ttx.NewCollectEndorsementsView(tx)) - if err != nil { - return "", errors.Wrap(err, "failed to sign transaction") - } - // Send to the ordering service and wait for finality - logger.Infof("submitting fabric transaction to orderer for final settlemement: [%s]", tx.ID()) - _, err = context.RunView(ttx.NewOrderingAndFinalityView(tx)) - if err != nil { - return "", errors.Wrap(err, "failed to order or commit transaction") - } - return tx.ID(), nil -} diff --git a/token-sdk/owner/service/transfer.go b/token-sdk/owner/service/transfer.go deleted file mode 100644 index d0394c09..00000000 --- a/token-sdk/owner/service/transfer.go +++ /dev/null @@ -1,159 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package service - -import ( - viewregistry "github.com/hyperledger-labs/fabric-smart-client/platform/view" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx" - "github.com/pkg/errors" -) - -// SERVICE - -// TransferTokens transfers an amount of a certain token. It connects to the other node, prepares the transaction, -// gets it approved by the auditor and sends it to the blockchain for endorsement and commit. -func (s TokenService) TransferTokens(tokenType string, quantity uint64, sender string, recipient string, recipientNode string, message string) (txID string, err error) { - logger.Infof("going to transfer %d %s from [%s] to [%s] on [%s] with message [%s]", quantity, tokenType, sender, recipient, recipientNode, message) - res, err := viewregistry.GetManager(s.FSC).InitiateView(&TransferView{ - Transfer: &Transfer{ - Wallet: sender, - TokenType: tokenType, - Quantity: quantity, - Recipient: recipient, - RecipientNode: recipientNode, - Message: message, - }, - }) - if err != nil { - logger.Error(err) - return - } - txID, ok := res.(string) - if !ok { - err = errors.New("cannot parse transfer response") - logger.Error(err) - return - } - return -} - -// VIEW - -// Transfer contains the input information for a transfer -type Transfer struct { - // Wallet is the identifier of the wallet that owns the tokens to transfer - Wallet string - // TokenType of tokens to transfer - TokenType string - // Quantity to transfer - Quantity uint64 - // RecipientNode is the identity of the recipient's FSC node - RecipientNode string - // Recipient is the identity of the recipient's wallet - Recipient string - // Message is an optional user message sent with the transaction. - // It's stored in the ApplicationMetadata and is sent in the transient field. - Message string -} - -type TransferView struct { - *Transfer -} - -func (v *TransferView) Call(context view.Context) (interface{}, error) { - // As a first step operation, the sender tries its own node or contacts the recipients - // FSC node to ask for the identity to use to assign ownership of the freshly created token. - var recipient view.Identity - var err error - w := ttx.GetWallet(context, v.Recipient) - if w != nil { - // Get recipient identity from own wallet - logger.Infof("getting local identity for %s", v.Recipient) - recipient, err = w.GetRecipientIdentity() - if err != nil { - return nil, errors.Wrapf(err, "failed getting recipient identity from own node: %s", v.Recipient) - } - } else { - node := view.Identity(v.RecipientNode) - rec := view.Identity(v.Recipient) - eps := viewregistry.GetEndpointService(context) - if !eps.IsBoundTo(node, rec) { - logger.Infof("binding [%s] to node [%s]", v.Recipient, v.RecipientNode) - eps.Bind(node, rec) // TODO: it doesn't forget a wrong binding - } - - // Request recipient identity from other node - logger.Infof("requesting [%s] identity from [%s]", v.Recipient, v.RecipientNode) - recipient, err = ttx.RequestRecipientIdentity(context, rec) - if err != nil { - return "", errors.Wrapf(err, "failed getting recipient identity from %s", v.RecipientNode) - } - } - - // specify the auditor and create the envelope for the transaction - logger.Debug("getting identity of auditor") - auditor := viewregistry.GetIdentityProvider(context).Identity("auditor") // TODO: should not be hardcoded - if auditor == nil { - return "", errors.New("auditor identity not found") - } - tx, err := ttx.NewTransaction(context, nil, ttx.WithAuditor(auditor)) - if err != nil { - return "", errors.Wrap(err, "failed creating transaction") - } - - // The sender will select tokens owned by this wallet - senderWallet := ttx.GetWallet(context, v.Wallet) - if senderWallet == nil { - return "", errors.Errorf("sender wallet [%s] not found", v.Wallet) - } - - // The sender adds a new transfer operation to the transaction following the instruction received. - // Notice the use of `token2.WithTokenIDs(v.TokenIDs...)`. If v.TokenIDs is not empty, the Transfer - // function uses those tokens, otherwise the tokens will be selected on the spot. - // Token selection happens internally by invoking the default token selector: - // selector, err := tx.TokenService().SelectorManager().NewSelector(tx.ID()) - // assert.NoError(err, "failed getting selector") - // selector.Select(wallet, amount, tokenType) - // It is also possible to pass a custom token selector to the Transfer function by using the relative opt: - // token2.WithTokenSelector(selector). - err = tx.Transfer( - senderWallet, - v.TokenType, - []uint64{v.Quantity}, - []view.Identity{recipient}, - ) - if err != nil { - return "", errors.Wrap(err, "failed adding new tokens") - } - // You can set any metadata you want. It is shared with the recipient and - // auditor but not committed to the ledger. - if v.Message != "" { - tx.SetApplicationMetadata("message", []byte(v.Message)) - } - - // The sender is ready to collect all the required signatures. - // In this case, the sender's and the auditor's signatures. - // Invoke the Token Chaincode to collect endorsements on the Token Request and prepare the relative transaction. - // This is all done in one shot running the following view. - // Before completing, all recipients receive the approved transaction. - // Depending on the token driver implementation, the recipient's signature might or might not be needed to make - // the token transaction valid. - logger.Infof("collecting signatures and submitting transaction to chaincode: [%s]", tx.ID()) - _, err = context.RunView(ttx.NewCollectEndorsementsView(tx)) - if err != nil { - return "", errors.Wrap(err, "failed to sign transaction") - } - - // Send to the ordering service and wait for finality - logger.Infof("submitting fabric transaction to orderer for final settlemement: [%s]", tx.ID()) - _, err = context.RunView(ttx.NewOrderingAndFinalityView(tx)) - if err != nil { - return "", errors.Wrap(err, "failed to order or commit transaction") - } - return tx.ID(), nil -} diff --git a/token-sdk/scripts/down.sh b/token-sdk/scripts/down.sh deleted file mode 100755 index a6c5b97d..00000000 --- a/token-sdk/scripts/down.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# -# This script fully tears down and deletes all artifacts from the sample network that was started with ./scripts/up.sh. - - -ls scripts/down.sh || { echo "run this script from the root directory: ./scripts/down.sh"; exit 1; } -TEST_NETWORK_HOME="${TEST_NETWORK_HOME:-$(pwd)/../test-network}" -ls "$TEST_NETWORK_HOME/network.sh" 1> /dev/null || { echo "Set the TEST_NETWORK_HOME environment variable to the directory of your fabric-samples/test-network; e.g.: - -export TEST_NETWORK_HOME=\"$TEST_NETWORK_HOME\" -"; exit 1; } - -docker-compose down -docker-compose -f compose-ca.yaml down - -docker stop peer0org1_tokenchaincode_ccaas peer0org2_tokenchaincode_ccaas -bash "$TEST_NETWORK_HOME"/network.sh down - -rm -rf keys -rm -rf data -rm tokenchaincode/zkatdlog_pp.json diff --git a/token-sdk/scripts/enroll-users.sh b/token-sdk/scripts/enroll-users.sh deleted file mode 100755 index 70a6ddf0..00000000 --- a/token-sdk/scripts/enroll-users.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -# -# Register and enroll all identities needed for the Token network. - -set -Exeuo pipefail - -# enroll admin -fabric-ca-client enroll -u http://admin:adminpw@localhost:27054 - -# Fabric Smart Client node identities (identity of the node, used when talking to other nodes) -for node in issuer auditor owner1 owner2 -do - fabric-ca-client register -u http://localhost:27054 --id.name fsc${node} --id.secret password --id.type client - fabric-ca-client enroll -u http://fsc${node}:password@localhost:27054 -M "$(pwd)/keys/${node}/fsc/msp" - - # make private key name predictable - mv "$(pwd)/keys/${node}/fsc/msp/keystore/"* "$(pwd)/keys/${node}/fsc/msp/keystore/priv_sk" -done - -# Issuer and Auditor wallet users (non-anonymous) -fabric-ca-client register -u http://localhost:27054 --id.name auditor --id.secret password --id.type client -fabric-ca-client enroll -u http://auditor:password@localhost:27054 -M "$(pwd)/keys/auditor/aud/msp" - -fabric-ca-client register -u http://localhost:27054 --id.name issuer --id.secret password --id.type client -fabric-ca-client enroll -u http://issuer:password@localhost:27054 -M "$(pwd)/keys/issuer/iss/msp" - -# Owner wallet users (pseudonymous) on the owner1 node -fabric-ca-client register -u http://localhost:27054 --id.name alice --id.secret password --id.type client --enrollment.type idemix --idemix.curve gurvy.Bn254 -fabric-ca-client enroll -u http://alice:password@localhost:27054 -M "$(pwd)/keys/owner1/wallet/alice/msp" --enrollment.type idemix --idemix.curve gurvy.Bn254 - -fabric-ca-client register -u http://localhost:27054 --id.name bob --id.secret password --id.type client --enrollment.type idemix --idemix.curve gurvy.Bn254 -fabric-ca-client enroll -u http://bob:password@localhost:27054 -M "$(pwd)/keys/owner1/wallet/bob/msp" --enrollment.type idemix --idemix.curve gurvy.Bn254 - -# Owner wallet users (pseudonymous) on the owner2 node -fabric-ca-client register -u http://localhost:27054 --id.name carlos --id.secret password --id.type client --enrollment.type idemix --idemix.curve gurvy.Bn254 -fabric-ca-client enroll -u http://carlos:password@localhost:27054 -M "$(pwd)/keys/owner2/wallet/carlos/msp" --enrollment.type idemix --idemix.curve gurvy.Bn254 - -fabric-ca-client register -u http://localhost:27054 --id.name dan --id.secret password --id.type client --enrollment.type idemix --idemix.curve gurvy.Bn254 -fabric-ca-client enroll -u http://dan:password@localhost:27054 -M "$(pwd)/keys/owner2/wallet/dan/msp" --enrollment.type idemix --idemix.curve gurvy.Bn254 diff --git a/token-sdk/scripts/up.sh b/token-sdk/scripts/up.sh deleted file mode 100755 index 69ecaabc..00000000 --- a/token-sdk/scripts/up.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash -# -# This script generates crypto, starts Fabric, deploys the chaincode and starts the token nodes. - -set -Eeuo pipefail - -# Checks -ls scripts/up.sh || { echo "run this script from the root directory: ./scripts/up.sh"; exit 1; } -docker-compose version -git --version -go version -tokengen version || { echo "install tokengen (see readme)"; exit 1; } - -[ ! -f data/auditor/kvs ] || { echo "delete existing crypto before running ./scripts/up.sh: - -# ./scripts/down.sh"; exit 1; } -TEST_NETWORK_HOME="${TEST_NETWORK_HOME:-$(pwd)/../test-network}" -ls "$TEST_NETWORK_HOME/network.sh" 1> /dev/null || { echo "Set the TEST_NETWORK_HOME environment variable to the directory of your fabric-samples/test-network; e.g.: - -export TEST_NETWORK_HOME=\"$TEST_NETWORK_HOME\" -"; exit 1; } - -# Generate identities for the nodes, issuer, auditor and owner -mkdir -p keys/ca -docker-compose -f compose-ca.yaml up -d -while ! fabric-ca-client getcainfo -u localhost:27054 2>/dev/null; do echo "waiting for CA to start..." && sleep 1; done -./scripts/enroll-users.sh -# generate the parameters needed for the tokenchaincode -tokengen gen dlog --base 300 --exponent 5 --issuers keys/issuer/iss/msp --idemix keys/owner1/wallet/alice --auditors keys/auditor/aud/msp --output tokenchaincode - - -# Start Fabric network -bash "$TEST_NETWORK_HOME/network.sh" up createChannel -# copy the keys and certs of the peers, orderer and the client user -mkdir -p keys/fabric -cp -r "$TEST_NETWORK_HOME/organizations" keys/fabric/ - -# Install and start tokenchaincode as a service -INIT_REQUIRED="--init-required" "$TEST_NETWORK_HOME/network.sh" deployCCAAS -ccn tokenchaincode -ccp "$(pwd)/tokenchaincode" -cci "init" -ccs 1 - -# Start token nodes -mkdir -p data/auditor data/issuer data/owner1 data/owner2 -docker-compose up -d -echo " -Ready! - -Visit http://localhost:8080 in your browser to view the API documentation and try some transactions. -" diff --git a/token-sdk/swagger.yaml b/token-sdk/swagger.yaml deleted file mode 100644 index cb349f9b..00000000 --- a/token-sdk/swagger.yaml +++ /dev/null @@ -1,519 +0,0 @@ -openapi: 3.0.3 -info: - title: Tokens - version: "1.0" - description: |- - Issue, hold, transfer and redeem tokens. Backed by a distributed ledger, - preserving privacy using Zero Knowledge Proofs. This API definition fronts 4 different services, which each play a different - role in the ecosystem. - - To try it out, let the Issuer issue some funds to one of the users. Watch the balances - get updated and see the transaction history. Transfer it to another account, or redeem - the tokens to destroy them. -servers: - - url: http://localhost:9000/api/v1/ - description: auditor - - url: http://localhost:9100/api/v1/ - description: issuer - - url: http://localhost:9200/api/v1/ - description: alice and bob - - url: http://localhost:9300/api/v1/ - description: carlos and dan - -paths: - # Auditor - /auditor/accounts/{id}: - servers: - - url: http://localhost:9000/api/v1/ - description: auditor - get: - tags: - - auditor - parameters: - - $ref: "#/components/parameters/id" - - $ref: "#/components/parameters/code" - required: true - responses: - "200": - $ref: "#/components/responses/AccountSuccess" - default: - $ref: "#/components/responses/ErrorResponse" - operationId: auditorAccount - summary: Get an account and their balance of a certain type - - /auditor/accounts/{id}/transactions: - servers: - - url: http://localhost:9000/api/v1/ - description: auditor - get: - tags: - - auditor - parameters: - - $ref: "#/components/parameters/id" - operationId: auditorTransactions - summary: Get all transactions for an account - responses: - "200": - $ref: "#/components/responses/TransactionsSuccess" - default: - $ref: "#/components/responses/ErrorResponse" - - # Issuer - /issuer/issue: - servers: - - url: http://localhost:9100/api/v1/ - description: issuer - summary: Issue tokens to an account - post: - tags: - - issuer - responses: - "200": - $ref: "#/components/responses/IssueSuccess" - default: - $ref: "#/components/responses/ErrorResponse" - requestBody: - description: Instructions to issue funds to an account - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/TransferRequest" - operationId: issue - summary: Issue tokens of any kind to an account - - # Owner - /owner/accounts: - servers: - - url: http://localhost:9200/api/v1/ - description: alice and bob - - url: http://localhost:9300/api/v1/ - description: carlos and dan - get: - tags: - - owner - responses: - "200": - $ref: "#/components/responses/AccountsSuccess" - default: - $ref: "#/components/responses/ErrorResponse" - operationId: ownerAccounts - summary: Get all accounts on this node and their balances of each type - - /owner/accounts/{id}: - servers: - - url: http://localhost:9200/api/v1/ - description: alice and bob - - url: http://localhost:9300/api/v1/ - description: carlos and dan - get: - tags: - - owner - parameters: - - $ref: "#/components/parameters/id" - - $ref: "#/components/parameters/code" - responses: - "200": - $ref: "#/components/responses/AccountSuccess" - default: - $ref: "#/components/responses/ErrorResponse" - operationId: ownerAccount - summary: Get an account and its balances of each token type - - /owner/accounts/{id}/transactions: - servers: - - url: http://localhost:9200/api/v1/ - description: alice and bob - - url: http://localhost:9300/api/v1/ - description: carlos and dan - get: - tags: - - owner - parameters: - - $ref: "#/components/parameters/id" - operationId: ownerTransactions - summary: Get all transactions for an account - description: | - Note that the system uses Unspent Transaction Outputs (UTXO). - For a transfer, you'll often see two transactions with the same id. The user specified amount goes - to the counterparty, and some other amount (the remaining part of the input token) goes back to the - sender! - - This could be confusing for a user. A simple solution is to filter out the transactions with the same - sender and recipient. - responses: - "200": - $ref: "#/components/responses/TransactionsSuccess" - default: - $ref: "#/components/responses/ErrorResponse" - - /owner/accounts/{id}/transfer: - servers: - - url: http://localhost:9200/api/v1/ - description: alice and bob - - url: http://localhost:9300/api/v1/ - description: carlos and dan - summary: Transfer tokens to another account - post: - tags: - - owner - parameters: - - $ref: "#/components/parameters/id" - name: id - requestBody: - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/TransferRequest" - responses: - "200": - $ref: "#/components/responses/TransferSuccess" - default: - $ref: "#/components/responses/ErrorResponse" - operationId: transfer - summary: Transfer tokens to another account - - /owner/accounts/{id}/redeem: - servers: - - url: http://localhost:9200/api/v1/ - description: alice and bob - - url: http://localhost:9300/api/v1/ - description: carlos and dan - summary: Redeem (burn) tokens - post: - tags: - - owner - parameters: - - $ref: "#/components/parameters/id" - requestBody: - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/RedeemRequest" - operationId: redeem - summary: Redeem (burn) tokens - responses: - "200": - $ref: "#/components/responses/RedeemSuccess" - default: - $ref: "#/components/responses/ErrorResponse" - - # Operations - /healthz: - get: - tags: - - operations - operationId: healthz - summary: Returns 200 if the service is healthy - responses: - "200": - $ref: "#/components/responses/HealthSuccess" - "503": - $ref: "#/components/responses/ErrorResponse" - /readyz: - get: - tags: - - operations - operationId: readyz - summary: Returns 200 if the service is ready to accept calls - responses: - "200": - $ref: "#/components/responses/HealthSuccess" - "503": - $ref: "#/components/responses/ErrorResponse" - -components: - responses: - AccountSuccess: - description: Success response - content: - application/json: - schema: - type: object - required: - - message - - payload - properties: - message: - type: string - payload: - $ref: "#/components/schemas/Account" - AccountsSuccess: - description: Success response - content: - application/json: - schema: - type: object - required: - - message - - payload - properties: - message: - type: string - payload: - type: array - items: - $ref: "#/components/schemas/Account" - TransactionsSuccess: - description: Success response - content: - application/json: - schema: - type: object - required: - - message - - payload - properties: - message: - type: string - example: "transactions retrieved" - payload: - type: array - items: - $ref: "#/components/schemas/TransactionRecord" - TransferSuccess: - description: Success response - content: - application/json: - schema: - type: object - required: - - message - - payload - properties: - message: - type: string - payload: - type: string - description: Transaction id - example: - message: transferred tokens - payload: 7c26ed6e5e05f7de81a82691b66b1069d1507d9edf3c7b78ea1fa98557ee57b4 - RedeemSuccess: - description: Success response - content: - application/json: - schema: - type: object - required: - - message - - payload - properties: - message: - type: string - example: tokens redeemed - payload: - type: string - description: Transaction id - example: 7c26ed6e5e05f7de81a82691b66b1069d1507d9edf3c7b78ea1fa98557ee57b4 - IssueSuccess: - description: Success or error response - content: - application/json: - schema: - type: object - required: - - message - - payload - properties: - message: - type: string - payload: - type: string - description: Transaction id - HealthSuccess: - description: Success response - content: - application/json: - schema: - type: object - required: - - message - properties: - message: - type: string - description: ok - example: - message: ok - - ErrorResponse: - description: Error response - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - - schemas: - # Common - Amount: - description: The amount to issue, transfer or redeem. - type: object - required: - - code - - value - properties: - code: - description: the code of the token - default: EURX - type: string - value: - description: value in base units (usually cents) - type: integer - format: int64 - minimum: 0 - example: - code: EURX - value: 100 - Account: - type: object - description: Information about an account and its balance - required: - - id - - balance - properties: - id: - type: string - description: account id as registered at the Certificate Authority - example: alice - balance: - type: array - description: balance in base units for each currency - items: - $ref: "#/components/schemas/Amount" - example: - id: alice - balance: - - code: EURX - value: 10000 - - code: USDX - value: 200 - Counterparty: - description: The counterparty in a Transfer or Issuance transaction. - required: - - node - - account - type: object - properties: - node: - description: The node that holds the recipient account - type: string - account: - type: string - example: - node: owner1 - account: alice - TransactionRecord: - type: object - description: A transaction - required: - - id - - sender - - recipient - - amount - - timestamp - - status - - message - properties: - id: - type: string - description: transaction id - sender: - type: string - description: the sender of the transaction - recipient: - type: string - description: the recipient of the transaction - amount: - $ref: "#/components/schemas/Amount" - timestamp: - type: string - format: date-time - description: 'timestamp in the format: "2018-03-20T09:12:28Z"' - status: - type: string - description: Unknown | Pending | Confirmed | Deleted - message: - type: string - description: user provided message - example: - id: 123 - sender: alice - recipient: bob - amount: - code: EURX - value: 100 - timestamp: "2018-03-20T09:12:28Z" - status: Confirmed - message: "" - - # Owner - TransferRequest: - description: Instructions to issue or transfer tokens to an account - required: - - counterparty - - amount - type: object - properties: - amount: - $ref: "#/components/schemas/Amount" - counterparty: - $ref: "#/components/schemas/Counterparty" - message: - description: optional message that will be sent and stored with the transfer transaction - type: string - RedeemRequest: - description: Instructions to redeem tokens from an account - required: - - amount - type: object - properties: - amount: - $ref: "#/components/schemas/Amount" - message: - description: optional message that will be visible to the auditor - type: string - Error: - required: - - message - - payload - type: object - properties: - message: - description: High level error message - type: string - payload: - description: Details about the error - type: string - example: - message: error message - payload: "" - parameters: - id: - name: id - schema: - example: alice - description: account id as registered at the Certificate Authority - type: string - in: path - required: true - code: - name: code - in: query - schema: - example: EURX - description: The token code to filter on - type: string - securitySchemes: {} - headers: {} -tags: - - name: issuer - description: can create tokens of any kind, and send them to owner accounts - - name: owner - description: is the service that hosts the keys and accounts of end users - - name: auditor - description: gets to see every transaction in the clear, and keeps a history - - name: operations - description: Service health and readiness -security: [] diff --git a/token-sdk/tokenchaincode/Dockerfile b/token-sdk/tokenchaincode/Dockerfile deleted file mode 100644 index 7fa696b0..00000000 --- a/token-sdk/tokenchaincode/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM golang:1.20 as builder -RUN git clone https://github.com/hyperledger-labs/fabric-token-sdk.git -WORKDIR fabric-token-sdk - -# Change the hash to checkout a different commit / version. It should be the same as in app/go.mod. -RUN git checkout v0.3.0 && go mod download -RUN CGO_ENABLED=1 go build -buildvcs=false -o /tcc token/services/network/fabric/tcc/main/main.go && chmod +x /tcc - -# Final image -FROM golang:1.20 -COPY --from=builder /tcc . -EXPOSE 9999 - -# zkatdlog is the output of the tokengen command. It contains the certificates -# of the issuer and auditor and the CA that issues owner account credentials, -# As well as cryptographic curves needed by the chaincode to verify proofs. -# It is generated once to initialize the network, when the 'init' function is -# invoked on the chaincode. -ENV PUBLIC_PARAMS_FILE_PATH=/zkatdlog_pp.json -ADD zkatdlog_pp.json /zkatdlog_pp.json - -CMD [ "./tcc"] diff --git a/token-sdk/transfer.png b/token-sdk/transfer.png deleted file mode 100644 index 3bd6b278..00000000 Binary files a/token-sdk/transfer.png and /dev/null differ diff --git a/token-utxo/README.md b/token-utxo/README.md deleted file mode 100644 index 6517b622..00000000 --- a/token-utxo/README.md +++ /dev/null @@ -1,231 +0,0 @@ -# UTXO token scenario - -The UTXO token smart contract demonstrates how to create and transfer fungible tokens using a UTXO (unspent transaction output) model. In a UTXO model, unspent transaction outputs representing a number of tokens can be 'spent' to transfer tokens between participants. -An unspent transaction output can only be spent once, and the full value must be completely spent. A transaction that spends UTXOs as input will also generate new UTXOs as outputs, where the value of the inputs must equal the value of the outputs. As an example, if you own an unspent transaction output representing 5000 tokens, and you need to transfer 100 tokens to a recipient, the transaction would spend the 5000 token UTXO as input, create a new 100 token UTXO output owned by the recipient, and return a new 4900 token UTXO to you as 'change'. - -Each UTXO in this sample has a key derived from the transaction id that created it, as well as a number of tokens, and an owner that is authorized to spend the tokens. -Ownership of each UTXO could be represented at the organization level or client identity level. In this sample UTXO ownership is based on a client identity, where the client ID is simply a base64-encoded concatenation of the issuer and subject from the client identity's enrollment certificate. The client ID can therefore be used as the payment address when transferring tokens in a UTXO transaction. - -While a transfer transaction spends UTXOs and creates new UTXOs for the recipient(s), a mint transaction can create new UTXOs. In this sample it is assumed that only one organization (played by Org1) is in a central banker role and can mint new tokens owned by their client ID. Any client from any organization can transfer tokens in a UTXO transaction. - -In this tutorial, you will mint and transfer tokens as follows: - -- A member of Org1 uses the `Mint` function to create a UTXO representing a number of tokens. The `Mint` function reads the certificate information of the client identity that submitted the transaction using the `GetClientIdentity.GetID()` API and assigns the UTXO ownership to the minter client ID. -- The same minter client will then use the `Transfer` function to transfer the requested number of tokens to a recipient. The minted UTXO key gets passed as input to the `Transfer` function, a UTXO output representing the number of transferred tokens gets created for the recipient, and another UTXO output representing the 'change' gets created for the minter. It is assumed that the recipient has provided their client ID to the transfer caller out of band. The recipient can then transfer tokens to other registered users in the same fashion. - -## Bring up the test network - -You can run the UTXO token transfer scenario using the Fabric test network. Open a command terminal and navigate to the test network directory in your local clone of the `fabric-samples`. We will operate from the `test-network` directory for the remainder of the tutorial. -``` -cd fabric-samples/test-network -``` - -Run the following command to start the test network: -``` -./network.sh up createChannel -ca -``` - -The test network is deployed with two peer organizations. The `createChannel` flag deploys the network with a single channel named `mychannel` with Org1 and Org2 as channel members. -The -ca flag is used to deploy the network using certificate authorities. This allows you to use each organization's CA to register and enroll new users for this tutorial. - -## Deploy the smart contract to the channel - -You can use the test network script to deploy the UTXO token contract to the channel that was just created. Deploy the smart contract to `mychannel` using the following command: -``` -./network.sh deployCC -ccn token_utxo -ccp ../token-utxo/chaincode-go/ -ccl go -``` - -The above command deploys the go chaincode with short name `token_utxo`. The smart contract will utilize the default endorsement policy of majority of channel members. -Since the channel has two members, this implies that we'll need to get peer endorsements from 2 out of the 2 channel members. - -Now you are ready to call the deployed smart contract via peer CLI calls. But let's first create the client identities for our scenario. - -## Register identities - -The smart contract supports UTXO ownership based on individual client identities from organizations that are members of the channel. In our scenario, the minter of the tokens will be a member of Org1, while the recipient will belong to Org2. To highlight the connection between the `GetClientIdentity().GetID()` API and the information within a user's certificate, we will register two new identities using the Org1 and Org2 Certificate Authorities (CA's), and then use the CA's to generate each identity's certificate and private key. - -First, we need to set the following environment variables to use the Fabric CA client (and subsequent commands) -``` -export PATH=${PWD}/../bin:${PWD}:$PATH -export FABRIC_CFG_PATH=$PWD/../config/ -``` - -The terminal we have been using will represent Org1. We will use the Org1 CA to create the minter identity. Set the Fabric CA client home to the MSP of the Org1 CA admin (this identity was generated by the test network script): -``` -export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/peerOrganizations/org1.example.com/ -``` - -You can register a new minter client identity using the `fabric-ca-client` tool: -``` -fabric-ca-client register --caname ca-org1 --id.name minter --id.secret minterpw --id.type client --tls.certfiles "${PWD}/organizations/fabric-ca/org1/tls-cert.pem" -``` - -You can now generate the identity certificates and MSP folder by providing the enroll name and secret to the enroll command: -``` -fabric-ca-client enroll -u https://minter:minterpw@localhost:7054 --caname ca-org1 -M "${PWD}/organizations/peerOrganizations/org1.example.com/users/minter@org1.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org1/tls-cert.pem" -``` - -Run the command below to copy the Node OU configuration file into the minter identity MSP folder. -``` -cp "${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org1.example.com/users/minter@org1.example.com/msp/config.yaml" -``` - -Open a new terminal to represent Org2 and navigate to fabric-samples/test-network. We'll use the Org2 CA to create the Org2 recipient identity. Set the Fabric CA client home to the MSP of the Org2 CA admin: -``` -cd fabric-samples/test-network -export PATH=${PWD}/../bin:${PWD}:$PATH -export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/peerOrganizations/org2.example.com/ -``` - -You can register a recipient client identity using the `fabric-ca-client` tool: -``` -fabric-ca-client register --caname ca-org2 --id.name recipient --id.secret recipientpw --id.type client --tls.certfiles "${PWD}/organizations/fabric-ca/org2/tls-cert.pem" -``` - -We can now enroll to generate the identity certificates and MSP folder: -``` -fabric-ca-client enroll -u https://recipient:recipientpw@localhost:8054 --caname ca-org2 -M "${PWD}/organizations/peerOrganizations/org2.example.com/users/recipient@org2.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org2/tls-cert.pem" -``` - -Run the command below to copy the Node OU configuration file into the recipient identity MSP folder. -``` -cp "${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org2.example.com/users/recipient@org2.example.com/msp/config.yaml" -``` - -## Initialize the contract -Once we created the identity of the minter we can now initialize the contract. -Note that we need to call the initialize function before being able to use any functions of the contract. Initialize() can be called only once. - -Shift back to the Org1 terminal, we'll set the following environment variables to operate the `peer` CLI as the minter identity from Org1. -``` -export CORE_PEER_TLS_ENABLED=true -export CORE_PEER_LOCALMSPID=Org1MSP -export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/minter@org1.example.com/msp -export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt -export CORE_PEER_ADDRESS=localhost:7051 -export TARGET_TLS_OPTIONS=(-o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt") -``` - -We can then invoke the smart contract to initilize it -``` -peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_utxo -c '{"function":"Initialize","Args":["some name", "some symbol"]}' -``` - -## Mint some tokens - -Now that we have initialized the contract and created the identity of the minter, we can invoke the smart contract to mint some tokens. -Shift back to the Org1 terminal, we'll set the following environment variables to operate the `peer` CLI as the minter identity from Org1. -``` -export CORE_PEER_TLS_ENABLED=true -export CORE_PEER_LOCALMSPID=Org1MSP -export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/minter@org1.example.com/msp -export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt -export CORE_PEER_ADDRESS=localhost:7051 -export TARGET_TLS_OPTIONS=(-o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt") -``` - -The last environment variable above will be utilized within the CLI invoke commands to set the target peers for endorsement, and the target ordering service endpoint and TLS options. - -We can then invoke the smart contract to mint 5000 tokens: -``` -peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_utxo -c '{"function":"Mint","Args":["5000"]}' -``` - -The mint function validated that the client is a member of the minter organization, and then created a UTXO with 5000 tokens belonging to the minter client identity. -The function returns the UTXO that was created so that we can inspect it. Here is the returned UTXO with JSON formatting applied: -``` -{ - "utxo_key":"c3706696c537e7bd6940fedfd52f4a3a630d253297db0ecc2b3ba514b45f5e7c.0", - "owner":"eDUwOTo6Q049bWludGVyLE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzEuZXhhbXBsZS5jb20sTz1vcmcxLmV4YW1wbGUuY29tLEw9RHVyaGFtLFNUPU5vcnRoIENhcm9saW5hLEM9VVM=", - "amount":5000 -} -``` - -Notice that the utxo_key is set to the transaction id, concatenated with ".0" to indicate that this is the first (and only) UTXO output of the transaction. Your transaction id will be different and unique. The owner is set to the minter's client ID, meaning that only this client can spend the UTXO, and the amount is "5000". - -The utxo_key that was created will be needed when you spend the UTXO in the Transfer function below. Copy the utxo_key value (including the ".0") so that you'll have it available for the Transfer function. - -We can check the minter client's total set of owned UTXOs by calling the `ClientUTXOs` function. -``` -peer chaincode query -C mychannel -n token_utxo -c '{"function":"ClientUTXOs","Args":[]}' -``` - -The same minted UTXO is returned. - - -## Transfer tokens - -The minter intends to transfer 100 tokens to the Org2 recipient, but first the Org2 recipient needs to provide their own client ID as the payment address. -A client can derive their client ID from their own public certificate, but to be sure the client ID is accurate, the contract has a `ClientID` utility function that simply looks at the callers certificate and returns the calling client's ID. -Let's prepare the Org2 terminal by setting the environment variables for the Org2 recipient user. -``` -export FABRIC_CFG_PATH=$PWD/../config/ -export CORE_PEER_TLS_ENABLED=true -export CORE_PEER_LOCALMSPID=Org2MSP -export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/recipient@org2.example.com/msp -export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -export CORE_PEER_ADDRESS=localhost:9051 -``` - -Using the Org2 terminal, the Org2 recipient user can retrieve their own client ID: -``` -peer chaincode query -C mychannel -n token_utxo -c '{"function":"ClientID","Args":[]}' -``` - -The function returns of recipient's client ID: -``` -eDUwOTo6Q049cmVjaXBpZW50LE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzIuZXhhbXBsZS5jb20sTz1vcmcyLmV4YW1wbGUuY29tLEw9SHVyc2xleSxTVD1IYW1wc2hpcmUsQz1VSw== -``` - -Let's base64 decode the client ID to make sure it is the Org2 recipient user: -``` -echo eDUwOTo6Q049cmVjaXBpZW50LE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzIuZXhhbXBsZS5jb20sTz1vcmcyLmV4YW1wbGUuY29tLEw9SHVyc2xleSxTVD1IYW1wc2hpcmUsQz1VSw== | base64 --decode -``` - -The result shows that the subject and issuer is indeed the recipient user from Org2: -``` -x509::CN=recipient,OU=client,O=Hyperledger,ST=North Carolina,C=US::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK -``` - -After the Org2 recipient provides their client ID to the minter, the minter can initiate a transfer of tokens. We'll pass in the utxo_key of the UTXO with 5000 tokens to spend, and request that two new UTXOs get created, a UTXO with 100 tokens for the recipient, and a UTXO with 4900 tokens for the minter as the 'change'. Since the contract will create the UTXO output keys, we'll initially leave the output keys blank. -Back in the Org1 terminal, request the UTXO transfer. **Replace YOUR_UTXO_KEY below with the key you saved earlier**: -``` -peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_utxo -c '{"function":"Transfer","Args":["[\"YOUR_UTXO_KEY\"]"," [{\"utxo_key\":\"\",\"owner\":\"eDUwOTo6Q049cmVjaXBpZW50LE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzIuZXhhbXBsZS5jb20sTz1vcmcyLmV4YW1wbGUuY29tLEw9SHVyc2xleSxTVD1IYW1wc2hpcmUsQz1VSw==\",\"amount\":100},{\"utxo_key\":\"\",\"owner\":\"eDUwOTo6Q049bWludGVyLE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzEuZXhhbXBsZS5jb20sTz1vcmcxLmV4YW1wbGUuY29tLEw9RHVyaGFtLFNUPU5vcnRoIENhcm9saW5hLEM9VVM=\",\"amount\":4900}]"]}' -``` - -The `Transfer` function verifies that the calling client owns the input UTXO, and that the sum of the input amounts equals the sum of the output amounts. It will then delete (spend) the input UTXO, and create the two output UTXOs. If you passed the incorrect UTXO input key, or requested UTXO output values that don't total 5000, you'll get an error indicating as such. - -The new UTXO outputs are returned in the successful response: -``` -[{\"utxo_key\":\"e51c3d19e92326f772e49e8a3e58f2bbf72bc3905e55fcd649b97a91b9b2cf44.0\",\"owner\":\"eDUwOTo6Q049cmVjaXBpZW50LE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzIuZXhhbXBsZS5jb20sTz1vcmcyLmV4YW1wbGUuY29tLEw9SHVyc2xleSxTVD1IYW1wc2hpcmUsQz1VSw==\",\"amount\":100},{\"utxo_key\":\"e51c3d19e92326f772e49e8a3e58f2bbf72bc3905e55fcd649b97a91b9b2cf44.1\",\"owner\":\"eDUwOTo6Q049bWludGVyLE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzEuZXhhbXBsZS5jb20sTz1vcmcxLmV4YW1wbGUuY29tLEw9RHVyaGFtLFNUPU5vcnRoIENhcm9saW5hLEM9VVM=\",\"amount\":4900}] -``` - -While still in the Org1 terminal, let's request the minter's UTXOs again: -``` -peer chaincode query -C mychannel -n token_utxo -c '{"function":"ClientUTXOs","Args":[]}' -``` - -The new UTXO worth 4900 tokens is returned. - -And then using the Org2 terminal, let's request the recipient's UTXOs: -``` -peer chaincode query -C mychannel -n token_utxo -c '{"function":"ClientUTXOs","Args":[]}' -``` - -The new UTXO worth 100 tokens is returned. - -Congratulations, you've transferred 100 tokens! The Org2 recipient can now transfer tokens to other registered users in the same manner. - -## Clean up - -When you are finished, you can bring down the test network. The command will remove all the nodes of the test network, and delete any ledger data that you created: -``` -./network.sh down -``` - -## Contract extension ideas - -You can extend the basic UTXO token sample to meet other requirements. For example: - -* Rather than using the default 'majority' endorsement policy, you could set the endorsement policy to a subset of organizations that represent trust anchors for the contract execution. -* You could utilize anonymous payment addresses on the UTXO outputs based on private-public key pairs, instead of UTXOs assigned to a client ID. In order to spend the tokens, the client would have to sign the transfer input as proof that they own the address private key, which the contract would then validate, similar to the Bitcoin model in the permissionless blockchain space. However, in a permissioned blockchain such as Fabric, only registered clients are authorized to participate. Furthermore, if you don't want to leak the registered client identity associated with each address, the clients could be registered using an Identity Mixer MSP, so that the client itself is also anonymous in each of the token transactions. diff --git a/token-utxo/chaincode-go/chaincode/token_contract.go b/token-utxo/chaincode-go/chaincode/token_contract.go deleted file mode 100644 index 4de96034..00000000 --- a/token-utxo/chaincode-go/chaincode/token_contract.go +++ /dev/null @@ -1,379 +0,0 @@ -package chaincode - -import ( - "errors" - "fmt" - "log" - "strconv" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" -) - -// SmartContract provides functions for transferring tokens using UTXO transactions -type SmartContract struct { - contractapi.Contract -} - -// UTXO represents an unspent transaction output -type UTXO struct { - Key string `json:"utxo_key"` - Owner string `json:"owner"` - Amount int `json:"amount"` -} - -// Define key names for options -const nameKey = "name" -const symbolKey = "symbol" - -// Mint creates a new unspent transaction output (UTXO) owned by the minter -func (s *SmartContract) Mint(ctx contractapi.TransactionContextInterface, amount int) (*UTXO, error) { - - // check if contract has been intilized first - initialized, err := checkInitialized(ctx) - if err != nil { - return nil, fmt.Errorf("failed to check if contract is already initialized: %v", err) - } - if !initialized { - return nil, errors.New("contract options need to be set before calling any function, call Initialize() to initialize contract") - } - - // Check minter authorization - this sample assumes Org1 is the central banker with privilege to mint new tokens - clientMSPID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return nil, fmt.Errorf("failed to get MSPID: %v", err) - } - if clientMSPID != "Org1MSP" { - return nil, errors.New("client is not authorized to mint new tokens") - } - - // Get ID of submitting client identity - minter, err := ctx.GetClientIdentity().GetID() - if err != nil { - return nil, fmt.Errorf("failed to get client id: %v", err) - } - - if amount <= 0 { - return nil, errors.New("mint amount must be a positive integer") - } - - utxo := UTXO{} - utxo.Key = ctx.GetStub().GetTxID() + ".0" - utxo.Owner = minter - utxo.Amount = amount - - // the utxo has a composite key of owner:utxoKey, this enables ClientUTXOs() function to query for an owner's utxos. - utxoCompositeKey, err := ctx.GetStub().CreateCompositeKey("utxo", []string{minter, utxo.Key}) - if err != nil { - return nil, err - } - - err = ctx.GetStub().PutState(utxoCompositeKey, []byte(strconv.Itoa(amount))) - if err != nil { - return nil, err - } - - log.Printf("utxo minted: %+v", utxo) - - return &utxo, nil -} - -// Transfer transfers UTXOs containing tokens from client to recipient(s) -func (s *SmartContract) Transfer(ctx contractapi.TransactionContextInterface, utxoInputKeys []string, utxoOutputs []UTXO) ([]UTXO, error) { - - // check if contract has been intilized first - initialized, err := checkInitialized(ctx) - if err != nil { - return nil, fmt.Errorf("failed to check if contract is already initialized: %v", err) - } - if !initialized { - return nil, errors.New("contract options need to be set before calling any function, call Initialize() to initialize contract") - } - - // Get ID of submitting client identity - clientID, err := ctx.GetClientIdentity().GetID() - if err != nil { - return nil, fmt.Errorf("failed to get client id: %v", err) - } - - // Validate and summarize utxo inputs - utxoInputs := make(map[string]*UTXO) - var totalInputAmount int - for _, utxoInputKey := range utxoInputKeys { - if utxoInputs[utxoInputKey] != nil { - return nil, errors.New("the same utxo input can not be spend twice") - } - - utxoInputCompositeKey, err := ctx.GetStub().CreateCompositeKey("utxo", []string{clientID, utxoInputKey}) - if err != nil { - return nil, fmt.Errorf("failed to create composite key: %v", err) - } - - // validate that client has a utxo matching the input key - valueBytes, err := ctx.GetStub().GetState(utxoInputCompositeKey) - if err != nil { - return nil, fmt.Errorf("failed to read utxoInputCompositeKey %s from world state: %v", utxoInputCompositeKey, err) - } - - if valueBytes == nil { - return nil, fmt.Errorf("utxoInput %s not found for client %s", utxoInputKey, clientID) - } - - amount, _ := strconv.Atoi(string(valueBytes)) // Error handling not needed since Itoa() was used when setting the utxo amount, guaranteeing it was an integer. - - utxoInput := &UTXO{ - Key: utxoInputKey, - Owner: clientID, - Amount: amount, - } - - totalInputAmount, err = add(totalInputAmount, amount) - if err != nil { - return nil, err - } - - utxoInputs[utxoInputKey] = utxoInput - } - - // Validate and summarize utxo outputs - var totalOutputAmount int - txID := ctx.GetStub().GetTxID() - for i, utxoOutput := range utxoOutputs { - - if utxoOutput.Amount <= 0 { - return nil, errors.New("utxo output amount must be a positive integer") - } - - utxoOutputs[i].Key = fmt.Sprintf("%s.%d", txID, i) - - totalOutputAmount, err = add(totalOutputAmount, utxoOutput.Amount) - if err != nil { - return nil, err - } - } - - // Validate total inputs equals total outputs - if totalInputAmount != totalOutputAmount { - return nil, fmt.Errorf("total utxoInput amount %d does not equal total utxoOutput amount %d", totalInputAmount, totalOutputAmount) - } - - // Since the transaction is valid, now delete utxo inputs from owner's state - for _, utxoInput := range utxoInputs { - - utxoInputCompositeKey, err := ctx.GetStub().CreateCompositeKey("utxo", []string{utxoInput.Owner, utxoInput.Key}) - if err != nil { - return nil, fmt.Errorf("failed to create composite key: %v", err) - } - - err = ctx.GetStub().DelState(utxoInputCompositeKey) - if err != nil { - return nil, err - } - log.Printf("utxoInput deleted: %+v", utxoInput) - } - - // Create utxo outputs using a composite key based on the owner and utxo key - for _, utxoOutput := range utxoOutputs { - utxoOutputCompositeKey, err := ctx.GetStub().CreateCompositeKey("utxo", []string{utxoOutput.Owner, utxoOutput.Key}) - if err != nil { - return nil, fmt.Errorf("failed to create composite key: %v", err) - } - - err = ctx.GetStub().PutState(utxoOutputCompositeKey, []byte(strconv.Itoa(utxoOutput.Amount))) - if err != nil { - return nil, err - } - log.Printf("utxoOutput created: %+v", utxoOutput) - } - - return utxoOutputs, nil -} - -// ClientUTXOs returns all UTXOs owned by the calling client -func (s *SmartContract) ClientUTXOs(ctx contractapi.TransactionContextInterface) ([]*UTXO, error) { - - // check if contract has been intilized first - initialized, err := checkInitialized(ctx) - if err != nil { - return nil, fmt.Errorf("failed to check if contract is already initialized: %v", err) - } - if !initialized { - return nil, errors.New("contract options need to be set before calling any function, call Initialize() to initialize contract") - } - - // Get ID of submitting client identity - clientID, err := ctx.GetClientIdentity().GetID() - if err != nil { - return nil, fmt.Errorf("failed to get client id: %v", err) - } - - // since utxos have a composite key of owner:utxoKey, we can query for all utxos matching owner:* - utxoResultsIterator, err := ctx.GetStub().GetStateByPartialCompositeKey("utxo", []string{clientID}) - if err != nil { - return nil, err - } - defer utxoResultsIterator.Close() - - var utxos []*UTXO - for utxoResultsIterator.HasNext() { - utxoRecord, err := utxoResultsIterator.Next() - if err != nil { - return nil, err - } - - // composite key is expected to be owner:utxoKey - _, compositeKeyParts, err := ctx.GetStub().SplitCompositeKey(utxoRecord.Key) - if err != nil { - return nil, err - } - - if len(compositeKeyParts) != 2 { - return nil, errors.New("expected composite key with two parts (owner:utxoKey)") - } - - utxoKey := compositeKeyParts[1] // owner is at [0], utxoKey is at[1] - - if utxoRecord.Value == nil { - return nil, fmt.Errorf("utxo %s has no value", utxoKey) - } - - amount, _ := strconv.Atoi(string(utxoRecord.Value)) // Error handling not needed since Itoa() was used when setting the utxo amount, guaranteeing it was an integer. - - utxo := &UTXO{ - Key: utxoKey, - Owner: clientID, - Amount: amount, - } - - utxos = append(utxos, utxo) - } - return utxos, nil -} - -// ClientID returns the client id of the calling client -// Users can use this function to get their own client id, which they can then give to others as the payment address -func (s *SmartContract) ClientID(ctx contractapi.TransactionContextInterface) (string, error) { - - // check if contract has been intilized first - initialized, err := checkInitialized(ctx) - if err != nil { - return "", fmt.Errorf("failed to check if contract is already initialized: %v", err) - } - if !initialized { - return "", errors.New("contract options need to be set before calling any function, call Initialize() to initialize contract") - } - - // Get ID of submitting client identity - clientID, err := ctx.GetClientIdentity().GetID() - if err != nil { - return "", fmt.Errorf("failed to get client id: %v", err) - } - - return clientID, nil -} - -// Name returns a descriptive name for fungible tokens in this contract -// returns {String} Returns the name of the token - -func (s *SmartContract) Name(ctx contractapi.TransactionContextInterface) (string, error) { - - // check if contract has been intilized first - initialized, err := checkInitialized(ctx) - if err != nil { - return "", fmt.Errorf("failed to check if contract is already initialized: %v", err) - } - if !initialized { - return "", errors.New("contract options need to be set before calling any function, call Initialize() to initialize contract") - } - - bytes, err := ctx.GetStub().GetState(nameKey) - if err != nil { - return "", fmt.Errorf("failed to get Name bytes: %s", err) - } - - return string(bytes), nil -} - -// Symbol returns an abbreviated name for fungible tokens in this contract. -// returns {String} Returns the symbol of the token - -func (s *SmartContract) Symbol(ctx contractapi.TransactionContextInterface) (string, error) { - - // Check if contract has been intilized first - initialized, err := checkInitialized(ctx) - if err != nil { - return "", fmt.Errorf("failed to check if contract is already initialized: %v", err) - } - if !initialized { - return "", errors.New("contract options need to be set before calling any function, call Initialize() to initialize contract") - } - - bytes, err := ctx.GetStub().GetState(symbolKey) - if err != nil { - return "", fmt.Errorf("failed to get Symbol: %v", err) - } - - return string(bytes), nil -} - -// Set information for a token and intialize contract. -// param {String} name The name of the token -// param {String} symbol The symbol of the token -func (s *SmartContract) Initialize(ctx contractapi.TransactionContextInterface, name string, symbol string) (bool, error) { - - // Check minter authorization - this sample assumes Org1 is the central banker with privilege to intitialize contract - clientMSPID, err := ctx.GetClientIdentity().GetMSPID() - if err != nil { - return false, fmt.Errorf("failed to get MSPID: %v", err) - } - if clientMSPID != "Org1MSP" { - return false, errors.New("client is not authorized to initialize contract") - } - - // check contract options are not already set, client is not authorized to change them once intitialized - bytes, err := ctx.GetStub().GetState(nameKey) - if err != nil { - return false, fmt.Errorf("failed to get Name: %v", err) - } - if bytes != nil { - return false, errors.New("contract options are already set, client is not authorized to change them") - } - - err = ctx.GetStub().PutState(nameKey, []byte(name)) - if err != nil { - return false, fmt.Errorf("failed to set token name: %v", err) - } - - err = ctx.GetStub().PutState(symbolKey, []byte(symbol)) - if err != nil { - return false, fmt.Errorf("failed to set symbol: %v", err) - } - - log.Printf("name: %v, symbol: %v", name, symbol) - - return true, nil -} - -// Checks that contract options have been already initialized -func checkInitialized(ctx contractapi.TransactionContextInterface) (bool, error) { - tokenName, err := ctx.GetStub().GetState(nameKey) - if err != nil { - return false, fmt.Errorf("failed to get token name: %v", err) - } - if tokenName == nil { - return false, nil - } - return true, nil -} - -// add two number checking for overflow -func add(b int, q int) (int, error) { - - // Check overflow - sum := q + b - - if (sum < q) == (b >= 0 && q >= 0) { - return 0, fmt.Errorf("math: addition overflow occurred %d + %d", b, q) - } - - return sum, nil -} diff --git a/token-utxo/chaincode-go/go.mod b/token-utxo/chaincode-go/go.mod deleted file mode 100644 index 4f4e3738..00000000 --- a/token-utxo/chaincode-go/go.mod +++ /dev/null @@ -1,26 +0,0 @@ -module github.com/hyperledger/fabric-samples/token-utxo/chaincode-go - -go 1.22.0 - -require github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 - -require ( - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 // indirect - github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.36.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/token-utxo/chaincode-go/go.sum b/token-utxo/chaincode-go/go.sum deleted file mode 100644 index fa4d3b24..00000000 --- a/token-utxo/chaincode-go/go.sum +++ /dev/null @@ -1,61 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0 h1:IhkHfrl5X/fVnmB6pWeCYCdIJRi9bxj+WTnVN8DtW3c= -github.com/hyperledger/fabric-chaincode-go/v2 v2.0.0/go.mod h1:PHHaFffjw7p7n9bmCfcm7RqDqYdivNEsJdiNIKZo5Lk= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0 h1:rmUoBmciB0GL/miqcbJmJbgp5QTWoJUrZo+CNxrNLF4= -github.com/hyperledger/fabric-contract-api-go/v2 v2.2.0/go.mod h1:FeWeO/jwGjiME7ak3GufqKIcwkejtzrDG4QxbfKydWs= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4 h1:YJrd+gMaeY0/vsN0aS0QkEKTivGoUnSRIXxGJ7KI+Pc= -github.com/hyperledger/fabric-protos-go-apiv2 v0.3.4/go.mod h1:bau/6AJhvEcu9GKKYHlDXAxXKzYNfhP6xu2GXuxEcFk= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/token-utxo/chaincode-go/token_utxo.go b/token-utxo/chaincode-go/token_utxo.go deleted file mode 100644 index 1014f4f2..00000000 --- a/token-utxo/chaincode-go/token_utxo.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 -*/ - -package main - -import ( - "log" - - "github.com/hyperledger/fabric-contract-api-go/v2/contractapi" - "github.com/hyperledger/fabric-samples/token-utxo/chaincode-go/chaincode" -) - -func main() { - tokenChaincode, err := contractapi.NewChaincode(&chaincode.SmartContract{}) - if err != nil { - log.Panicf("Error creating token-utxo chaincode: %v", err) - } - - if err := tokenChaincode.Start(); err != nil { - log.Panicf("Error starting token-utxo chaincode: %v", err) - } -}