From 59fd868ca86664d522231f723cb39ca5873d4b29 Mon Sep 17 00:00:00 2001 From: Peter Broadhurst Date: Mon, 11 Oct 2021 22:07:57 -0400 Subject: [PATCH 1/3] Clean up Gen 1 "KAT" implementation, and update README Signed-off-by: Peter Broadhurst --- README.md | 163 ++---- images/firefly_explorer.png | Bin 0 -> 136736 bytes images/hyperledger_firefly_logo.png | Bin 0 -> 16678 bytes .../intro_to_firefly_teaser.svg | 0 kat/.gitignore | 5 - kat/.vscode/settings.json | 4 - kat/README.md | 71 --- kat/asset_trail_overview.png | Bin 599724 -> 0 bytes kat/nodemon.json | 6 - kat/package.json | 95 --- kat/src/app.ts | 22 - kat/src/clients/api-gateway.ts | 113 ---- kat/src/clients/app2app.ts | 113 ---- kat/src/clients/database.ts | 264 --------- kat/src/clients/db-providers/mongodb.ts | 72 --- kat/src/clients/db-providers/nedb.ts | 67 --- kat/src/clients/doc-exchange.ts | 172 ------ kat/src/clients/event-streams.ts | 168 ------ kat/src/clients/gateway-providers/corda.ts | 167 ------ kat/src/clients/gateway-providers/ethereum.ts | 260 --------- kat/src/clients/ipfs.ts | 74 --- kat/src/handlers/asset-definitions.ts | 151 ----- kat/src/handlers/asset-instances-pinning.ts | 70 --- kat/src/handlers/asset-instances.ts | 542 ------------------ kat/src/handlers/asset-trade.ts | 205 ------- kat/src/handlers/batches.ts | 24 - kat/src/handlers/client-events.ts | 28 - kat/src/handlers/members.ts | 65 --- kat/src/handlers/payment-definitions.ts | 108 ---- kat/src/handlers/payment-instances.ts | 158 ----- kat/src/index.ts | 93 --- kat/src/lib/batch-manager.ts | 70 --- kat/src/lib/batch-processor.ts | 263 --------- kat/src/lib/config.ts | 68 --- kat/src/lib/event-stream.ts | 205 ------- kat/src/lib/interfaces.ts | 513 ----------------- kat/src/lib/logging.ts | 71 --- kat/src/lib/request-handlers.ts | 57 -- kat/src/lib/settings.ts | 76 --- kat/src/lib/utils.ts | 176 ------ kat/src/routers/asset-definitions.ts | 100 ---- kat/src/routers/asset-instances.ts | 185 ------ kat/src/routers/batches.ts | 28 - kat/src/routers/members.ts | 82 --- kat/src/routers/payment-definitions.ts | 81 --- kat/src/routers/payment-instances.ts | 90 --- kat/src/routers/settings.ts | 41 -- kat/src/schemas/asset-definition.json | 34 -- kat/src/schemas/config.json | 199 ------- kat/src/schemas/indexes.json | 24 - kat/src/schemas/settings.json | 32 -- kat/src/test/common.ts | 308 ---------- kat/src/test/corda-suite.ts | 26 - .../test/corda/assets/argument-validation.ts | 160 ------ .../assets/authored-private-structured.ts | 298 ---------- kat/src/test/corda/assets/index.ts | 23 - kat/src/test/corda/index.ts | 22 - .../test/corda/members/argument-validation.ts | 94 --- kat/src/test/corda/members/index.ts | 23 - kat/src/test/corda/members/registration.ts | 76 --- kat/src/test/ethereum-suite.ts | 25 - .../ethereum/assets/argument-validation.ts | 132 ----- .../authored/private/described-structured.ts | 311 ---------- .../private/described-unstructured.ts | 127 ---- .../assets/authored/private/structured.ts | 211 ------- .../assets/authored/private/unstructured.ts | 124 ---- .../authored/public/described-structured.ts | 259 --------- .../authored/public/described-unstructured.ts | 129 ----- .../assets/authored/public/structured.ts | 253 -------- .../assets/authored/public/unstructured.ts | 123 ---- kat/src/test/ethereum/assets/index.ts | 53 -- .../private/described-structured.ts | 181 ------ .../private/described-unstructured.ts | 90 --- .../assets/unauthored/private/structured.ts | 141 ----- .../assets/unauthored/private/unstructured.ts | 87 --- .../unauthored/public/described-structured.ts | 152 ----- .../public/described-unstructured.ts | 89 --- .../assets/unauthored/public/structured.ts | 145 ----- .../assets/unauthored/public/unstructured.ts | 87 --- kat/src/test/ethereum/clients/app2app-test.ts | 69 --- kat/src/test/ethereum/clients/index.ts | 21 - kat/src/test/ethereum/index.ts | 32 -- .../test/ethereum/lib/batch-manager-test.ts | 131 ----- .../test/ethereum/lib/batch-processor-test.ts | 368 ------------ kat/src/test/ethereum/lib/config.ts | 100 ---- kat/src/test/ethereum/lib/index.ts | 29 - kat/src/test/ethereum/lib/logging.ts | 53 -- kat/src/test/ethereum/lib/settings.ts | 59 -- .../ethereum/members/argument-validation.ts | 55 -- kat/src/test/ethereum/members/index.ts | 23 - kat/src/test/ethereum/members/registration.ts | 185 ------ .../ethereum/payments/argument-validation.ts | 63 -- .../ethereum/payments/authored-described.ts | 218 ------- kat/src/test/ethereum/payments/authored.ts | 189 ------ kat/src/test/ethereum/payments/index.ts | 29 - .../ethereum/payments/unauthored-described.ts | 139 ----- kat/src/test/ethereum/payments/unauthored.ts | 125 ---- kat/src/test/samples.ts | 86 --- kat/test-resources/config-corda.json | 41 -- kat/test-resources/config-ethereum.json | 33 -- kat/test-resources/settings.json | 3 - kat/tsconfig.json | 19 - 102 files changed, 53 insertions(+), 11441 deletions(-) create mode 100644 images/firefly_explorer.png create mode 100644 images/hyperledger_firefly_logo.png rename {architecture => images}/intro_to_firefly_teaser.svg (100%) delete mode 100644 kat/.gitignore delete mode 100644 kat/.vscode/settings.json delete mode 100644 kat/README.md delete mode 100644 kat/asset_trail_overview.png delete mode 100644 kat/nodemon.json delete mode 100644 kat/package.json delete mode 100644 kat/src/app.ts delete mode 100644 kat/src/clients/api-gateway.ts delete mode 100644 kat/src/clients/app2app.ts delete mode 100644 kat/src/clients/database.ts delete mode 100644 kat/src/clients/db-providers/mongodb.ts delete mode 100644 kat/src/clients/db-providers/nedb.ts delete mode 100644 kat/src/clients/doc-exchange.ts delete mode 100644 kat/src/clients/event-streams.ts delete mode 100644 kat/src/clients/gateway-providers/corda.ts delete mode 100644 kat/src/clients/gateway-providers/ethereum.ts delete mode 100644 kat/src/clients/ipfs.ts delete mode 100644 kat/src/handlers/asset-definitions.ts delete mode 100644 kat/src/handlers/asset-instances-pinning.ts delete mode 100644 kat/src/handlers/asset-instances.ts delete mode 100644 kat/src/handlers/asset-trade.ts delete mode 100644 kat/src/handlers/batches.ts delete mode 100644 kat/src/handlers/client-events.ts delete mode 100644 kat/src/handlers/members.ts delete mode 100644 kat/src/handlers/payment-definitions.ts delete mode 100644 kat/src/handlers/payment-instances.ts delete mode 100644 kat/src/index.ts delete mode 100644 kat/src/lib/batch-manager.ts delete mode 100644 kat/src/lib/batch-processor.ts delete mode 100644 kat/src/lib/config.ts delete mode 100644 kat/src/lib/event-stream.ts delete mode 100644 kat/src/lib/interfaces.ts delete mode 100644 kat/src/lib/logging.ts delete mode 100644 kat/src/lib/request-handlers.ts delete mode 100644 kat/src/lib/settings.ts delete mode 100644 kat/src/lib/utils.ts delete mode 100644 kat/src/routers/asset-definitions.ts delete mode 100644 kat/src/routers/asset-instances.ts delete mode 100644 kat/src/routers/batches.ts delete mode 100644 kat/src/routers/members.ts delete mode 100644 kat/src/routers/payment-definitions.ts delete mode 100644 kat/src/routers/payment-instances.ts delete mode 100644 kat/src/routers/settings.ts delete mode 100644 kat/src/schemas/asset-definition.json delete mode 100644 kat/src/schemas/config.json delete mode 100644 kat/src/schemas/indexes.json delete mode 100644 kat/src/schemas/settings.json delete mode 100644 kat/src/test/common.ts delete mode 100644 kat/src/test/corda-suite.ts delete mode 100644 kat/src/test/corda/assets/argument-validation.ts delete mode 100644 kat/src/test/corda/assets/authored-private-structured.ts delete mode 100644 kat/src/test/corda/assets/index.ts delete mode 100644 kat/src/test/corda/index.ts delete mode 100644 kat/src/test/corda/members/argument-validation.ts delete mode 100644 kat/src/test/corda/members/index.ts delete mode 100644 kat/src/test/corda/members/registration.ts delete mode 100644 kat/src/test/ethereum-suite.ts delete mode 100644 kat/src/test/ethereum/assets/argument-validation.ts delete mode 100644 kat/src/test/ethereum/assets/authored/private/described-structured.ts delete mode 100644 kat/src/test/ethereum/assets/authored/private/described-unstructured.ts delete mode 100644 kat/src/test/ethereum/assets/authored/private/structured.ts delete mode 100644 kat/src/test/ethereum/assets/authored/private/unstructured.ts delete mode 100644 kat/src/test/ethereum/assets/authored/public/described-structured.ts delete mode 100644 kat/src/test/ethereum/assets/authored/public/described-unstructured.ts delete mode 100644 kat/src/test/ethereum/assets/authored/public/structured.ts delete mode 100644 kat/src/test/ethereum/assets/authored/public/unstructured.ts delete mode 100644 kat/src/test/ethereum/assets/index.ts delete mode 100644 kat/src/test/ethereum/assets/unauthored/private/described-structured.ts delete mode 100644 kat/src/test/ethereum/assets/unauthored/private/described-unstructured.ts delete mode 100644 kat/src/test/ethereum/assets/unauthored/private/structured.ts delete mode 100644 kat/src/test/ethereum/assets/unauthored/private/unstructured.ts delete mode 100644 kat/src/test/ethereum/assets/unauthored/public/described-structured.ts delete mode 100644 kat/src/test/ethereum/assets/unauthored/public/described-unstructured.ts delete mode 100644 kat/src/test/ethereum/assets/unauthored/public/structured.ts delete mode 100644 kat/src/test/ethereum/assets/unauthored/public/unstructured.ts delete mode 100644 kat/src/test/ethereum/clients/app2app-test.ts delete mode 100644 kat/src/test/ethereum/clients/index.ts delete mode 100644 kat/src/test/ethereum/index.ts delete mode 100644 kat/src/test/ethereum/lib/batch-manager-test.ts delete mode 100644 kat/src/test/ethereum/lib/batch-processor-test.ts delete mode 100644 kat/src/test/ethereum/lib/config.ts delete mode 100644 kat/src/test/ethereum/lib/index.ts delete mode 100644 kat/src/test/ethereum/lib/logging.ts delete mode 100644 kat/src/test/ethereum/lib/settings.ts delete mode 100644 kat/src/test/ethereum/members/argument-validation.ts delete mode 100644 kat/src/test/ethereum/members/index.ts delete mode 100644 kat/src/test/ethereum/members/registration.ts delete mode 100644 kat/src/test/ethereum/payments/argument-validation.ts delete mode 100644 kat/src/test/ethereum/payments/authored-described.ts delete mode 100644 kat/src/test/ethereum/payments/authored.ts delete mode 100644 kat/src/test/ethereum/payments/index.ts delete mode 100644 kat/src/test/ethereum/payments/unauthored-described.ts delete mode 100644 kat/src/test/ethereum/payments/unauthored.ts delete mode 100644 kat/src/test/samples.ts delete mode 100644 kat/test-resources/config-corda.json delete mode 100644 kat/test-resources/config-ethereum.json delete mode 100644 kat/test-resources/settings.json delete mode 100644 kat/tsconfig.json diff --git a/README.md b/README.md index 4bef680473..cdc41349a3 100644 --- a/README.md +++ b/README.md @@ -4,26 +4,67 @@ [![Go Report Card](https://goreportcard.com/badge/github.com/hyperledger/firefly)](https://goreportcard.com/report/github.com/hyperledger/firefly) [![FireFy Documentation](https://img.shields.io/static/v1?label=FireFly&message=documentation&color=informational)](https://hyperledger.github.io/firefly//) -Hyperledger FireFly is a multiparty system for enterprise data flows, powered by blockchain. It solves all of the layers of complexity that sit between the low level blockchain and high level business processes and user interfaces. FireFly enables developers to build blockchain apps for enterprise radically faster by allowing them to focus on business logic instead of infrastructure. +![Hyperledger FireFly](./images/hyperledger_firefly_logo.png) -FireFly focusses on: +Hyperledger FireFly is an API and data orchestration layer to build enterprise multi-party systems, on top of blockchain tech. -- Providing a great developer API and experience, with a CLI and UI as first class project components -- Pluggability for implementations of multi-party system infrastructure (blockchains, off-chain data exchange, identity, compute etc.) -- Making proven multi-party system patterns easy for new projects to adopt -- Providing developer friendly access to custom transactions+events in the underlying blockchain platforms -- Giving visibility and control on the private data exchange that occurs between businesses in a multi-party system -- Simplifying the journey of building multi-party business processes, by empowering non-blockchain developers to build great APIs+UX +- Transaction submission and event streaming + - Radically simplified API access to your on-chain smart contracts +- Multi-protocol blockchain integration + - Hyperledger Fabric + - Enterprise Ethereum - Hyperledger Besu & Quorum + - Corda *(work in progress)* +- Developer friendly event-driven REST & WebSocket APIs + - For building multi-party business applications that solve real enterprise use cases +- Digital assets + - Tokens and NFTs ready for use, and easy to extend + customize +- On-chain/off-chain orchestration + - Enterprise data flows backed by blockchain, with secure off-chain transfer of private docs+data +- Microservice architecture, for docker deployment + - Fully pluggable architecture, embracing multiple runtime technologies (Go, Node.js, Java etc.) +- Built by developers for developers + - Ready to go in minutes, with a CLI, built-in UI explorer, OpenAPI spec, and samples +- Data operations at the boundary of your data center + - Fast database cache + audit of all data flowing out of your enterprise, to the network -You will see enterprise focussed code in FireFly solving hard "plumbing" problems like on-chain/off-chain event sequencing and aggregation, and enough smart contract code to make the patterns possible. You will then find patterns of integration with the individual communities that are already building the deep blockchain & multi-party compute tech, like Hyperledger Fabric, Hyperledger Besu, Quorum, Corda, IPFS, Hyperledger Avalon, OpenZeppelin, NodeRED etc. +## Quick Start Guide -> Watch this space for patterns on integrating Tokens into the model (fungible token value exchange, and NFTs), which is a big current focus of evolution in the gen2 FireFly architecture (building on the work done in gen1, also in this repo). The tokens working group is being lead by [Jim Zhang](https://github.com/jimthematrix) +Follow the [get started](https://hyperledger.github.io/firefly/gettingstarted/gettingstarted.html) guide in the doc, and your +local developer environment will be up in minutes. -![Introducing FireFly](./architecture/intro_to_firefly_teaser.svg) +You'll have your own private multi-party system, comprising a blockchain (Ethereum/Fabric) with API/Event connectors, a Private Data Exchange, an IPFS data sharing network, and ERC-1155 Token/NFT implementations. + +All with the Hyperledger FireFly Explorer UI of course, and a [samples to get you building fast](https://github.com/hyperledger/firefly-samples). + +![FireFly Explorer](images/firefly_explorer.png) + +## API Reference + +All the Hyperledger FireFly APIs are self-documenting via Swagger, and you can just open them up on `/api` on your running FireFly. + +Or you can check out the [latest API here](https://hyperledger.github.io/firefly/swagger/swagger.html). ## Documentation -https://hyperledger.github.io/firefly// +https://hyperledger.github.io/firefly + +## Components + +There are multiple Git repos making up the Hyperledger FireFly project, and this +list is likely to grow as additional pluggable extensions come online in the community: + +- Command Line Interface (CLI) - https://github.com/hyperledger/firefly-cli +- Core (this repo) - https://github.com/hyperledger/firefly +- Sample applications - https://github.com/hyperledger/firefly-samples +- HTTPS Data Exchange - https://github.com/hyperledger/firefly-dataexchange-https +- Ethereum (Hyperledger Besu / Quorum) connector: https://github.com/hyperledger/firefly-ethconnect +- Corda connector: https://github.com/hyperledger/firefly-cordaconnect - contributed from Kaleido generation 1 - porting to generation 2 +- Hyperledger Fabric connector - in design phase, including collaboration with https://github.com/hyperledger/fabric-smart-client +- FireFly Explorer UI - https://github.com/hyperledger/firefly-ui + +## Multi-party Systems + +![Introducing FireFly](./images/intro_to_firefly_teaser.svg) ## FireFly repos @@ -32,14 +73,6 @@ As such there are a number of repos, and the list will grow as the community evo But not to worry, one of those repos is a CLI designed to get you running with all the components you need in minutes! -- CLI / Developer experience - https://github.com/hyperledger/firefly-cli -- UI Explorer - https://github.com/hyperledger/firefly-ui -- Sample applications - https://github.com/hyperledger/firefly-samples -- Core (this repo) - https://github.com/hyperledger/firefly -- HTTP Data Exchange - https://github.com/hyperledger/firefly-dataexchange-https -- Ethereum (Hyperledger Besu / Quorum) connector: https://github.com/hyperledger/firefly-ethconnect -- Corda connector: https://github.com/hyperledger/firefly-cordaconnect - contributed from Kaleido generation 1 - porting to generation 2 -- Hyperledger Fabric connector - in design phase, including collaboration with https://github.com/hyperledger/fabric-smart-client > Note only the projects that are primarily built to support FireFly are listed here, not all > of the ecosystem of projects that integrate underneath the plugins. See [below](#firefly-code-hierarchy) for @@ -51,10 +84,6 @@ Use the FireFly CLI for fast bootstrap: https://github.com/hyperledger/firefly-c ## Navigating this repo -There are **two core codebases** currently active in this repo: - -### Generation 2: FireFly - Directories: - [internal](./internal): The core Golang implementation code @@ -64,56 +93,6 @@ Directories: [Full code layout here](#firefly-code-hierarchy) -This latest generation is re-engineered from the ground up to improve developer experience, runtime performance, and extensibility. - -This means a simplified REST/WebSocket programming model for app development, and a wider range of infrastructure options for deployment. - -It also means a focus on an architecture and code structure for a vibrant open source community. - -A few highlights: - -- Golang codebase - - Strong coding standards, including unit test coverage, translation support, logging and more - - Fast starting, low memory footprint, multi-threaded runtime -- OpenAPI 3.0 API specification (Swagger) - - Generated from the API router code, to avoid divergence with the implementation -- Active/active HA architecture for the core runtime - - Deferring to the core database for state high availability - - Exploiting leader election where required -- Fully pluggable architecture - - Everything from Database through to Blockchain, and Compute - - Golang plugin infrastructure to decouple the core code from the implementation - - Remote Agent model to decouple code languages, and HA designs -- Updated API resource model - - `Asset`, `Data`, `Message`, `Event`, `Topic`, `Transaction` -- Added flexibility, with simplified the developer experience: - - Versioning of data definitions - - Introducing a first class `Context` construct link related events into a single sequence - - Allow many pieces of data to be attached to a single message, and be automatically re-assembled on arrival - - Clearer separation of concerns between the FireFly DB and the Application DB - - Better search, filter and query support - -### Generation 1: Kaleido Asset Trail (KAT) - -Directories: - -- [kat](./kat): The core TypeScript runtime -- [solidity_kat](./solidity_kat): Ethereum/Solidity smart contract code -- [cordapp_kat](./cordapp_kat): The Corda smart contract (CorDapp) - -This was the original implementation of the multi-party systems API by Kaleido, and is already deployed in a number production projects. - -The codebase distilled years of learning, into a set of patterns for performing blockchain orchestrated data exchange. - -It depends on the following Kaleido services: - -- Blockchain nodes - - Ethereum with the Kaleido [Kaleido REST API Gateway](https://docs.kaleido.io/kaleido-services/ethconnect/) - - Corda with the Kaleido built-in API for streaming KAT transactions -- [Kaleido Event Streams](https://docs.kaleido.io/kaleido-services/event-streams/) -- [Kaleido App2App Messaging](https://docs.kaleido.io/kaleido-services/app2app/) -- [Kaleido Document Exchange](https://docs.kaleido.io/kaleido-services/document-store/) - ## FireFly code hierarchy ``` @@ -343,39 +322,3 @@ Plugins: Each plugin comprises a Go shim, plus a remote agent microservice runti └───────────────┘ * Plugins integrate by returning their config structure for unmarshaling (JSON tags) ``` - -## API Query Syntax - -REST collections provide filter, `skip`, `limit` and `sort` support. - -- The field in the message is used as the query parameter -- When multiple query parameters are supplied these are combined with AND -- When the same query parameter is supplied multiple times, these are combined with OR - -### Example - -`GET` `/api/v1/messages?confirmed=>0&type=broadcast&topic=t1&topic=t2&context=@someprefix&sort=sequence&descending&skip=100&limit=50` - -This states: - -- Filter on `confirmed` greater than 0 -- Filter on `type` exactly equal to `broadcast` -- Filter on `topic` exactly equal to `t1` _or_ `t2` -- Filter on `context` containing the case-sensitive string `someprefix` -- Sort on `sequence` in `descending` order -- Paginate with `limit` of `50` and `skip` of `100` (e.g. get page 3, with 50/page) - -Table of filter operations, which must be the first character of the query string (after the `=` in the above URL path example) - -| Operator | Description | -| -------- | --------------------------------- | -| (none) | Equal | -| `!` | Not equal | -| `<` | Less than | -| `<=` | Less than or equal | -| `>` | Greater than | -| `>=` | Greater than or equal | -| `@` | Containing - case sensitive | -| `!@` | Not containing - case sensitive | -| `^` | Containing - case insensitive | -| `!^` | Not containing - case insensitive | diff --git a/images/firefly_explorer.png b/images/firefly_explorer.png new file mode 100644 index 0000000000000000000000000000000000000000..d5da5acfc8a15599e2330a57680a54f6011a094b GIT binary patch literal 136736 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 GA^#tr)Pphr literal 0 HcmV?d00001 diff --git a/architecture/intro_to_firefly_teaser.svg b/images/intro_to_firefly_teaser.svg similarity index 100% rename from architecture/intro_to_firefly_teaser.svg rename to images/intro_to_firefly_teaser.svg diff --git a/kat/.gitignore b/kat/.gitignore deleted file mode 100644 index af125da1cd..0000000000 --- a/kat/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.nyc_output -coverage -build -test-resources/sandbox -node_modules \ No newline at end of file diff --git a/kat/.vscode/settings.json b/kat/.vscode/settings.json deleted file mode 100644 index f773748f87..0000000000 --- a/kat/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "mochaExplorer.files": "src/test/**/*.ts", - "mochaExplorer.require": "ts-node/register" -} \ No newline at end of file diff --git a/kat/README.md b/kat/README.md deleted file mode 100644 index 940eef7999..0000000000 --- a/kat/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# Kaleido Asset Trail - -![Kaleido Asset Trail](asset_trail_overview.png) - -## Setup - -Kaleido asset trail can be run as a Kaleido member service or as a standalone application. -For the latter, deploy an ERC20 token and use its address in the constructor of the [asset Trail smart contract](solidity_new/contracts/AssetTrail.sol), - -For each participating member, deploy the following runtimes: -* IPFS -* App2App Messaging (with 2 destinations representing KAT and the client) -* Document Exchange (with 1 destination) - -You must also define an Event Stream with subscriptions to all relevant -events for your use case (subscribe to all events if unsure). - -Asset trail has built-in storage and can optionally be configured to use MongoDB. - -Create a new folder for your config. -Populate `config.json` with the URLs for the deployed contract API, the event stream, the IPFS/App2App/Document -Exchange runtimes, a valid set of credentials, and the locally running MongoDB. - -```json -{ - "port": 5000, - "assetTrailInstanceID": "asset-trail-org-a", - "protocol": "ethereum", - "apiGateway": { - "apiEndpoint": "https://xx12345678-yy12345678-connect.aws-0.kaleido.io/instances/0xc4ed58b23059e5b2f867b6040b46dcea04396c8b" - }, - "eventStreams": { - "wsEndpoint": "wss://xx12345678-yy12345678-connect.aws-0.kaleido.io/ws", - "topic": "A" - }, - "ipfs": { - "apiEndpoint": "https://xx12345678-yy12345678-ipfs.aws-0.kaleido.io" - }, - "app2app": { - "socketIOEndpoint": "wss://xx12345678-yy12345678-app2app.aws-0.kaleido.io/api/v1", - "destinations": { - "kat": "kld://app2app/z/dev2/m/zzdza6cuf9/e/zzdk0au9rl/s/zzspcgumw6/d/kat", - "client": "kld://app2app/z/dev2/m/zzdza6cuf9/e/zzdk0au9rl/s/zzspcgumw6/d/client" - } - }, - "docExchange": { - "apiEndpoint": "https://xx12345678-yy12345678-documentstore.aws-0.kaleido.io/api/v1", - "socketIOEndpoint": "wss://xx12345678-yy12345678-documentstore.aws-0.kaleido.io/api/v1", - "destination": "kld://documentstore/z/dev2/m/zzdza6cuf9/e/zzdk0au9rl/s/zzu2yrgdqw/d/a" - }, - "appCredentials": { - "user": "xx12345678", - "password": "yyyyyyyyyyy" - }, - "mongodb": { - "connectionUrl": "mongodb://localhost:27017", - "databaseName": "assettrail0" - } -} -``` - -You can create separate config folders for each org you wish to simulate. - -Run the server with the following (substitute the path to your own data directory as needed): -``` -cd core -DATA_DIRECTORY=data/single-region/OrgA nodemon -``` - -If using Visual Studio Code, there is also a provided [.vscode/launch.json](launch.json) file which can be -edited to add launch configurations to the UI. diff --git a/kat/asset_trail_overview.png b/kat/asset_trail_overview.png deleted file mode 100644 index d99b989bebc9a9e50a8d75deda402975a7aff93e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 599724 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

4jeeEREoZh?@4|L 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 Y}6?`!^@=0|@@+IRRr{*j%kc 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

    &|n^7oR~&=|4XY z22Mf_Ff9V*W|U#-3v_m_<-jv*mi7gXtUX@0SR_@1#1nUD8gOKVZOYSR4fO)%4^0?M z`Hd|;7TbUcsd|m!LJZ*G65xp4D}+>B!IVOeepM>7=r>;EsNK+kabwuizhxuj9IQwy zJz?WDottFv8Bv+?Kh1oDpWr`yZfY=GSJmI;<~9fn=a$-X2XCeF?#iO%$);maS8;5?!L)Mh;KqsEjEgug3QKRe7>*BSH! zR{>@dCM?2SnH1F@P3#McRN^#gXnUDZGx)(094dUCx(hsC9oT>}mIq-$!@|TcbRUmi zg+NAyOBTedim%h)BKRu7=8rn<`rqr67+$BZ49vLR!Ryo+UZRAKc;H!HRL$KA{V zbTi3X{oby}a0bBwx*55r{`Lsy5b<*?u`OiT1M(+o+{X&=1m&H-AEt}z&>1+)VWz@@ zKlpRn1BJQFqNa=NWr2I}2xZZKj!=G~kPr)#EiV;`4S6iTmK!N|xCn1mwhB=|h1+G! zkPQ44u(q7Cjodz;{sTh?L~}g57`<_cFjjW)l$y1~>fih^jXBOu0_+lP>+Vq?%+lh| zvovAx1vX_#3*+-LuT<;e_x-gB$rxgWC%(-9>dWM{=>7XF&p7^59QEHk%d=^a?R9n&T1}l6 zF(7R55Ar!U{aF|<%thGwd(h6P$&}*RC8u+bpDc^+eNO`0VONA6Ms}E^t|e*qKzKxy zfA+FJ(0+sR7vUSxSw-4(v|IElN@=8T1_VfltlI54(4A8EZa(p>aJDj4p}yF zosiZR)7r~gM0Y6zp{=x&=N`6O!*wrEpBC6_N3&lz*hz$sI{s$4xdnv7BJEvN-=&BK z%{zXR-1~}y>OH{V>z+-JQswt*w?`y+kPL5Gq>y|$4NSmsTjHIx>^A0ECQf7swhmd` zy%Qbl1LN1~t4!ELKFwYH^qTh7IJuKZCS-6ICq8 z&E_*$hB-6*GK)#!|47LG?I&Oebq4@eM?vX|py-+iR&Lxc58SjFNf6MCdz`G>Wm`%p zs|}8a(pDf3Pah5&UBUDw&sHluyXKN4x5ya-$+Ewk^++ar{SxD#F;q|m%dRq|jNLB+ z_*-_oxZV)#YAFk&wOYA8W~KZB-YI?nI8?LWc}TX?N+ zmgpd+tVQLDx%4LTgRdLaV7p(@UB{b##a(EQ%VolL!kWu^S#^v1bfH{gNaE)+ps>~9 zoi8Y?oEtbXd6td(KR9JmGk#TAu4ehuE63peouP%h4jqBYA7)Z{9eD{VUoJEGf1GhV zc4&Ac80JrvYHH-kMkboxr_Atewfzsy%lO}M-mSxP@JseK;WF{V<0?~_oy|K6zuqr0 ztOl_v&0rUOmfWRwXW$nm!_~-qqP!Hz&7f+~v?sRgB+Lwp!2H~&Z4J&IkVniQL~v|j z94=;hOYBBvZ#C)cv!!#5JKlzGQMLf|?0fV9~=%zU?y{^yDX zF#{_<;0Ye?a~t*P0cl1&#W2}t0cZOGAPRQXHWK(UHiY_9e^!3>c1rnO`K4E;DVufH zuFmF1j|XZTq^fRHD|NJ!cOs|zs+U>8RVFHvBnT0}b{M~c01ig7Bou;C4^S-ZDdfvD;fBkD0Kwxw3J_-0zuiqPpdSOncnYsq%U-7LZ9*hTp<9v8Tf_lPs(qeE3Ck>>>Z4L zQ;lh!|JAJc_!fTHlX`D(&MsL6bw;i1QpcLMw1=54n+K&FKXK3AAe=n>U}X3?f(Xo) zyJ{5}$pGu`Ztso81j#&b-ow2&_TaqPMgMl*x>elLm7ZM|Gc6af>c7vM@BjF``_{l! z-R8AJ6;9b4pZgHjWU2XO8yNhI8QGo=iWopi%WF7!?}GAU%h`!ylN6`dC0EEB>L9FPTi!kzu%F zyGUk*)l|W5%Nl2wyh{t~qLtoWCll%N-tMl`s0zZjk4qo9Ilag5J<=k3-zpC>ybHNj z?w&+iiRj=FphHj2L+OMyT%UoA1hsad#+YBom=<;o)Tc1_Q=E9dYS+^yh~st@Pr!osd!^6JkSuADWmSV%zXoY5g7 zLQd=~M1&OFOBnk5b9|y;0Rk*Ln;j7rLch7W;QuW*S6X5K5ryXN^E{AM7uAQz_C+o% z+tmDiRXCmw|M3`=N>EJ^z+<$4NN}JzmnM-yfA9vfR z6kf7fUpjb55Ns^TGKisBskh+l})k5j3|1M zkB2094Fy5fXBt-xuh2%ZvTa9R@YNRoR+F~>yP6c~s*)qkR#IM~pybmYhDR3m|O;!DWiDJ>T;r@0+kd4_&JNR9v72idpA04^3Z8y%){ z$aadpfkpRH+Z(~+xee;q)BjVSYTy@%u3JVc8|qkV6H?xn#v)|Ymg-3IU1Mynp_}gM?PH1pWt?Y4Zo~eb)6LO{Gz#1 zXOc*`B`v7TFP}?`f$Gzc0%4WG+viE&? zv|441#9wqcHr*;XVUVrQ@HbmaC22;ccO-o&U_|rn2|NNU6^8~(SI>(9#%MjD$CO^; z_3-zThK>)HGu!xE4Y-vxUjiNL+iUU{O;OB^a`1@}Tyt8VxV1gwJ(FUu4}IjH^igkX z@eH&XBAFEQP$`>B(g*&)g=i}qFNH&`_8Mel>3>35RyzxGdBR5=K7>(=v@Oavo=UH%#fKm48 z^^PDh;nwtB=ITw8s`JnGV4IJHl8;C7SmT3|+a&Imtf56^tSBsq3cp-mEx0p$+P$Z?1ZlsZJkS^&`y1TnmLJ*Md?k+(ZX^?N-=zgEa?LKGk z_dEL!@F(}0*P3(8F~=MW&r<+oh(Cg61PL15;z4lu#iybxrwjyot8c~@eFCU>Nn89O z5sriCt$RS$2sq%0SV}#OLrEt2B4;ZkLe;{mZp*llvsyKoql9Lt?O27ul&5o0O zGv3(um{30&bT@RoRClB0qq=6~=v@U7vuY?a=;LSgd&6Khus8ALMT*VWD2x6Ww#BVL zQZKQ{uSHPf?o1LBkJfq;Ve7WtsGOf4UDO_}yf3<9eN}K*QJp>K;9D-ug(@_Yey_Ob z9pf@b-Dc^5GF?P=orx!rWOCkux=`{;{s(adJZ0{i@3ewjCicU_^`cIWH5idcd0O*y zlNqD@R_FX@q{GnRpY%f3q#u(kOT*l(8NfVjT^r@`R%F}q#D?6wcYm{@_rGmWwYhM? z&1*=aD|V;c4t@3ZH5@c-I(a~?lHQR`i%jdVC1^`Uz?x2^A_HP~B0Xg2D zvuZBciwl~g&zaF?F5lD82QN#++nQ5cS)yqJY2i@ko!Bc(Wv`WljzuHCJE_6SX3Jj> z^*rX2Qe&cXn_fx|=G->EvZ-6j{K5@QSV!6RS!CFQ36ooZk6e#4S5yaISoSStv>vX{ z8srvYr>%bg7@oepbD2?uJowDm2eQY`4DB2vtEY3ee8aDP*?#qeSt`-S%6uYocWUpu z(0p@9<4m0B-p_VQE{So<`cq}3UhY7S^&alW!RqhO6G!dIuAX1bU2p_B_a0mxKS`}Y694lkHPE&=d0k@9Gw1>o$kBw3sfvlqWTC_yg4sv*<@)`tX(*K`wZ{ogdSIS)QNSf_(WkPJf|o`Z`*)=)^X^iDdm- zeowMRo97ByO;9KP$~Cv#Co4r*cr_Aw;>R+%dG&9*Lh>?~!9@L;Nnv(^KOxhVV-r5>6H^oL{<|wQk(vGw_ z_8QWP=7tBaC2E;m2QO?Wd3t8+^q!m2noM1EMM%u?gQqYRQ`hQf0Z$;`bS+9RYcc`q z7*X74?^S137p7j&uL#7tb#0nQSCK7RpAAA2;Yj}7j{g6S6xHE!gycbJuxKF9X%$|? z<|ih_P4|(>DvWZ8mh}afNEawqROO%1?68nVE=yu>%xG@QGd@TMSgS12=f*6cea+cN$QjQg_e3mx}!&n);j`Mxw2>8aOyOf!J{v-SUQe?l4| z_ot}V;GRk4r0ALd2(|0A3)iLLfDL4ejM0Tvy^$)x%A{EI38rz{`5|vLVlqD_LdRAx zhx6Bkjch#mm(^R=@~bQ!smWcHCMhzxGKUqNKjSf=XaejeDu_16d;4=C@d*Ak9!#xk zvpl-$Y~$;!H}R1DcjJ-o%zPtWJI9|Q*n3487>iZudlvpGdu`IowzU%fT^gM7tT-;o zDhgTV)?2z4jDYqLW~7!45qNp3bt6qGB+7d&{|+z|-H%v0a}wAg42Oiw8zS7%;tf>b zV-HaToX)kRc55SMby@BW+IRs6F3T{KZL^^SK&2ufU%w5FXN zUm&Rj(7?U?Vs*1T9e??EL`R7EtyP%3)@OEa;ZLqGff^tFk7^RzX;R)QYO(6=N%<8^ z_4w|LW&hXMDif_m@2Ms)X*cNOfKSg&V_oL)$2<@v=5x`EzgV6$9~QqXd?$acSRcvh;UjGBr}Ahk#a=ub zlBJ7aL?Un`BeBhEb4P&q#k5`=NPOtOCcYy~Kyj7Vp0Srh`n8@9|1N(rbLR`IR4+1a zj$Srn2pH+;YzG)~U<-(>F4{JeQ&bDvY@(dr4fBAZ6eKJu@T59uLyd>XYYbVWNnYIo z*glHWC@j)yiA9QVe=++@hFRniOFZ{VJY&YSqs17-#&})*$@lS+uix3od-#>YN0-x4-TOeN1vUv0 zjxUXmhlOI{%H3Qq7Y7<nAB>c+QF!L@j6eTihF zOIUTZ<@E3H95i(Uv~^^_qK>=F%8K!nTwCXqJ}3ds_Z!iSR%I1U(12h{K(6>z;Xo3t zTut-0U-cw8*}(U~n@qCUEH(P8@k`8LMjgtS*XJrU7!M`_;(W?eY&|G&^8f!2-h&S6 z!G2f$yla2yL8GdRH$)ZtWVGl*m8UdDzW}pn*OPRp2Cvt^d*-ND?De97SPx|CF3S_~ zu%eF|d(2#qa>n(^v*zyPDzV;+c%GMxZ`(loBF_W(JK zM(s{LjXW#Oo`ntO+E+K?GUj_o*!?Vl?GWMPtVZr3gu&qI_U+^ag!6qV2cT zSIxW^CNlmPQ^3GxbCFIi?!#J7EY@@UN~kv)))ZeVdnrrW^29zZT$$xgc)RVrSKXC3 z!-Y(;E-~oM>YJ?gR>}z!PWh&ZioiI#4Xj3-P5Qsy)&&|axD6_IF$wX~PG+f8OzA>1 z)l^Po(CuyfsuGY^0~^dsl8KJ9_H^URF_e#V+vNVmPMy{NpniT0Mlx0AI+NQUV>1j4 zmY@cId;}x7tARKqk#vE2i*JL&BfvBtiCwJ1tHkSPu~dK&DLcQLr<^O*3MNCu8N^T| zH;iaK29DJBGCwnhIn4N*D@W7vXR2H#!jvbu!wtUQoz!6u*ZL(3J4uJ`zaCqR`&Y8E zu=%Y~psQ3=K@yxT(||q&AEnpyZc>boWKY4g3&n@+I8Lf^wwYr_RoiWA;Nmi?nf^!( zJ!*gZsJi~HqUyCXbE6Xm8-6g!cahbgJlcv@);~9zB3|rN@mk?l z?KrVqo(`MmIwYfma6YJmOva!(r`AE*qx35F;F^s8U8ZZxb`IS7& zqX4~rCwjI*bw>2pi+??yRY75f!UeC?>ldtgFqb3>ML_^bN!6u zu2;z-M>~DjJIG+e(59ZdxQKq>bD01&z%Q?dQC+CCpz_KN#qT=b zwwvdMPjXlce}<#xH0RJQt^jNY#(Zq*XpjSKcW$}$Ttn$y(xa2Qog&v?ZtBzTgq~2I z?QxmRfYA{9*4y5cT@>S{us}O64gEfEAaKK$czTg~058|6&64gE4%)&;-Nko#y;lQ( z^9hLYK`lJOwqXFMw_Ly0+e1jb9W?ANj_>F`QvKI6cRbHipxO$2b4rh!^Nx{`(mga> zlTB5e zR}wp`@U?m$rn}|6;!a}M)%32bH@>ebbosi)?%^nPO_sy^rXH%ux8?Ag&ItZkVSLXF z90lEHW8rDy*v0cy8B)7LZ)W}ne@CYg&fNlC5rfuK$})(TSDOsi56Zb12$Vy5mZ%6L zgjLHimt6-%>@W( z_v8;M(!lb9{|5n`hX;y^A^vAQ{RE&ugC>V)d^}%o+kg>y>Y}0t@zYZ6a3GqZO8a0I z#^;{H~XRv;3x?JE09dT90WfoyAfPt3oG5Zfpqo08f$b`aaZ4;1b=BoPJ`Nc0Y5FIB6b(~W;+kOxFx?!T#nV9^CzPOqq= zBtZi|*pj{ceZDQL7vVg){$l!@Vcx*1iJs{M`m4uvFv3LS9dkRp}VDsj4 zVod%0W3A8zaj~i$vXR}lGDZK#AL|m&k&=_8{Z*kk^$Gn(P)n3tYh8AqepK#_+OJpj zceNj4L^)`!CYDZt!9&k!1=El%{j#?DcP>GZvz8an>|ns@3U#&ax9CCWZ^t}l61-yf zuC00?l3-jG+s<9%%DVIhD`4KCam_0SY8)+4b`KE>RVoX_^p6wfwb}_4o2uupRM_b1 z2O)WuCL=aFWW19Y)YFW=s;A^s7prx&cR0t?6bRo$d3fZ@qUWhfgqzhaL6&DdYGm}p zqQ8P+q}Jv-cNP}2UIo*b1xN+VtZ6uLKuw|q52hj9u!KM#1^Tf3{m7IU)q)9XAmjgrmCEN2Igc z6JbWDCnIM)jJ7x8s@UJeRaK@3Fq99fu(=?6^uXb&0>9@&OmrgvF5ma=^(AV7+7N1G z`4f94Q6h^tK*_&qzQ_xG9pXI?)R7#H&OJ|#cteB@wJkCQ;#Yd+gXbaQRB6iU!DZ4W z!*#Bhxc-EJ86n_wrNmVHQtulysA}+kS=GodZgbfAT7REw*PW25E8tOfze8nl4jtSa z<2zSLde6m8SO60r9H}8@{FOE&L1aJ@1a(+tHSkOO9H0S@+bNG353sb#{e3$=onhiE zFh+g-D-vuA0C%A;H{fg5^6C_8R)A0}!#|niF#Aqf@5NcnXyG*}UpqenhCQLH-~DHL zC;5#|t^aT5TV{F&zS#mduA|@2m%3jq5L1zB3)LF=zrJYFa#JVLIMSBXs-d` zVk0Xlo&HIJpJi#7ZM$s3V{h-H5YII0)@=1rG6dTbxSgwAy`D?FNg0E^^#=p{W1zcx zt@2kSW#<;aNztRUmE8y!8n?j~ag@lx#S=CTXkV}>TOH6l1#!_1kOn=|Q?$;hX&`Yl z@-DvHyQ0EVZUibC(RT?0GgY6b@chxO-#QO<5R z3Y>$D64Fc4eee8C$24&s87febqwXO@Q*@NXICp_>BSNm35rt9Ikbe#-l-l7F)X4`v zJB_*sd!^ZAErVq9cs+POOex!p)*?kmChvlL@%gXvgwoQa{ctXqM$P+a$QN*&x0{r{@YP&j@Zwboy{ybC+<)wkbS`u(I;f--<5!jF?)11C)m z0DP|583k^{pnuM7Sej^*ZSYFr2?2cKvnnz7?W^(lh4jG2!0pdH-M< zY_%hMUKHYw!q>S6z#HpRTY?0gR!9l!aiet=ndBiMkMIOGpQQl0<*iWha)fW9=QN0% zv4HKP3L@|2#){*=(p^G=G$mok}9P>dt`>>lPr={{3xrezcAyqfB*o^`-Cde8G zU&lJlAM0KQc)7sFwfTIJ2~z!r`-G>P-UT|GU0{=}qV_M$i~@Ql zaTs9d6=3-S3>wKr81K~7sfh_igeDxT zf8XCj6`IiU3MB8`ze?WsySack=ll${DaJDI+TGXa3PS3ZMLA9pr+$;!GsK4|yx$dJ z2ck^B<(geckX>?9umogtKw6@u&kKMq>_5llDubjR2{y71tg*u?+rjn0c@4Q9<3I*F z5a3sdKJ_YknJ1F!v*3T!YFR2^6T~`z-mcjveU1$zoudaci5~F!@7bxT>9tV=L~i!K z2LEgS>!$|uObRr!7?eR=fZP+i7&9}{H*44)y>4dk5q>k zXfyTT&SSEE?jynJLLGr5t#snN2Hu-$0R1KMlRar_H*Vu>SXB`3-0@Z zG}MzyPH~flp8cMNP;4g8K57QOj~3bPoqIvxMM2=29M_&0Qoh*6D4pJ?9~K_0Bbs6c zKKL|cY3ceul;CA^gyjINjL{^k0jHH@2+N|U3amKW$tm3Ian~ilO0U#=Yi8STQjfV! zZZ>KJ(1qhzq?GaDDAKOd9(VFY0A5vQ_A`Y_RG)tiNx0jIJ4Z3%dg2%z<|!EQd8l1m zy)fcR`e}5B+}lId*L~y%PW<~{oVd|zuoBUcGX@#=6&d9gi=l~fBWpZ@^oqqDxRwF> z-GDDJgsd!)J_MlU{qiW1I1up_+yww6*)ycT1sGp{d~CnuJAu}&P&f&mj6a`#P+I0o zP85~RyCM-u^;+ORpSchC%)Kog>22?LrmH{sUwr1;JocxgEq~aFkt0M+g=A;0G30sqo5h_#@eq zh9TVrdq{+%G>K_0lRa*q?rRT+*e?XV(8|PoAl8)NxTEyJZ6;&H`O2#)%K+ktz6bgo zYikFgL`lLEJ{e(H@qY3W4yIHA^lVW6NZ&9t1BCZl?kl8!#HwT-CWhCI3P3G}sO^R1 zda+x}I>9$f2@%{UKyrygeO#;q$R(K?5EOH_bE+L+Fs_pq@80U91E0!K)=yb}gOAeu z_>JtLKo9BjpB}PG9(>a!5<%M%nwBG9KmYS@ngQ9S%|HIdHNL|Aopw7WSI-8gSwvv< zN2uDK__BO)b2?9YovFM3M(V9c`)8@Q{qz>lk14S^gYnv*(+Nca2hbDzIi0)@uP{z2 zdv;HT|3ZMalLs=OlbPL=t)NpDX!0jVi+>fXK3#wkjXKSOxpK40VAuHUG&%*W-+lA? z>5bv1r@nEi+6#Kij=JA_%TghGK$pL}$>V-%V%D5tQfnI@jv?-!szS^IbU`#gznkd^ zRNqS0prj%NDKc3BU1P}zK$qOGkCiXZ!S-&-l`I`J8{|wsl*K&=4gWMZ{>(5RFJh$t zZlw=$>Q;gQ`5#24bAS>lX1zs^jQ;6nrFNdZoO#nMMU2ImUrY0yCu>p>5jSI(#NWm) z*e__R3^?p9KHoDKrA!ht>zbEvKvF-Q$Lcf`I+=VJbjPSmW_|c&w%*RoP83u0pLU{N zSC}4yPlK9^K>hcO@^qaR{KQn;b%U)hsXRZq+dzeIFrNN#@U0)rK&}nhe2{IRQ6${t zZ;)Ze^aTjtzksJ0_vol;w19tDW=6yL`MPNO@Yd7D7SMafsYHv*F~s0 z3V}s-+H@Qvtd=a`j3(0zcG;02NvCCb^yLg>qPY#hoNHvp$si{^oZ>!`u}81mg2~g> z>|#R{U1sSN2q(%ya3>0rsZ34*Gismz%&286!D{x!=a`+ltU@2v0j;`8^ML~zy${z? zNlEkb!+@}xrS|myUTXib;FmAu#sRzw?W)b1IW_wev=x>gfoB099w!X6^%8e_Smw&C zFH5ob{1C;d{aF+@HSGfg0nJMXi>$w)O|qwUMt_ljc+kM^^^XFZZ<7x4r5qcqP|FhR zj8Qk3gVh`$d|WjeUyWA7P(V@7B{PbWLH-<<$94XVBj)@JDdrilQ7ky-X4QMIuvPw( zoDC1V{NAoya`lOds4jwc?T=(7+*{8$%&(EsmmOm9JBO(Keh;iF;oKD9d-+kv&xljE zhOIIo1^7e2>(sBw;vd1q@$S#gXV+Y>T-XYC5@Ml^*GZGXMlHG;*PO8UShTmdEW0pb z-9Emd>Zs2BrE)aSqCIDPvAH{`;8nVPIA9##T{~Sdoqj7PAYWpo$ij?zb(eLsR5fC_ zvDoFdS%Z%D8v@ifZksxigTjj9fT|*dOU)-wGb(us(TYFB2md?EN$*~%Yq(Hms)Na8m?CQO7+n=iEJjf{ zYr9E&q<`M)7B-&VgCxG2o!LLr4~%_@j=v>7Ow)l{CM~5#Ws2}C!8cyf+@|qy(UJ>? zoy)mJRgX^*xRdZx&EU|UOWS}wBZOhyQfRH^BgMBgY_D)?i)-FwN(XQ%cdh%fNPlGA zU;+vNl9Xv&u}r?}bsznO%>_3-f}c-x4ACDl=DYi2fmSa8;WuU0Jso1Blv=l$>9uQY zEMDnC$gK3qRx>PdDnhX+DGyk;4>44k@z7uelXeA6XDsfSo7H`&Weo)*Hyd# z_5ir%1|s1M*(P*kyew9Pq~i*a0rpCnz1I|7$xp46P5-2auxF^nN*UY5=*HN)Lb(JiYz-k=ziqy#kywmwcfOGxcx46&vFle>sYJzWw~Cj_xyUV zZ*k)p$?C_?OZcfadl>nwrYbL@1vqXwrC~bJJjRQ6o^!gUvS0B((Y*Asqb$B=8l*q> z7`Y*9k(ubqabxVI0ba@d9j}-Q0_%}1W60)|xa(vCsE<8WCm;FHy6oJONWiYC#f!V&oBobuW@-RMpqrn($0-80tp4ak4h%H7`G$_UeRY1HvEGn|IebV3s`^Xjj z5i)KbKt%c^$rHjKT|o-^(1 zz`-XOdLR%JRMjtMPNlZ}df?6>yzP&M=yx2R+DnIIfyae@E(@h6bh*bPd{eT+!5%VC z6uvAo)_5Dg6N5dgk9y#`S+Q;m>jZwxwW|9mks zrq{qSjyKD?_5AM_b9)A~W`DYv4F+KUqyXh^upgsY0t{tF?IZy*@9b)taZwe<*5Uel zP2VJA@MevQy>R zDRNj<4K`i-A0<^_Q; zjRsUu91pLYl|#G^BI{ifAQ@JprN;LaYaQU8pK~R@1QQP{*M-eH%-+C3z26Oc$L&jE zZG9KsB?8jcFmm77MNsG-&W*obBi3v;Y+15nO}2r2Ru;&bL>(9ccf~bPNOUpo!?uDE zZdSnmK-Z1uERgcs`n_=AZdf=SV+Sj{fOoEW*qSfecRZTjRupia?F77WRy9INa z7=J0hii=ddRVH}ZnD{))>U@Igw%yeC>&ZHl5~_fFmwOnz{-T5YcXJ0Pw0E`rHCu{G z({d&}W-o2S$^AKxah>QM-)HfdNE=j2Z=1lpw{=H5lj3xDa@Q<5G0{rzWG47ye>w+; zb=O5h`AOULx~?tsZezMrQ}H?7_D5Ss27_`bycpIir(HT+XE?UmeYBUSkIz)#Ue@o? zd1?i|zi3KK*YLKMEk-XumTRauYQ(@OVUp7FtT+G2XU!|D&cXzR$;oy5wX3WHkr5#Y zMcSw|O$=4hEza9q9%#4Y)@p{rqU49!q*4RQ0(#S}&V(H{AEX8d)=ZImt*oig$c;@P zumrz$w*|UDgFMEmh4_(jwU25y~q;=B6-~BPEeS9ENcb{ zN*+9`noM7{qrB5YQvS8t-6xV zoTe#U{je22}YTCIa5@9!H`3$e~v{fCgBLq26)W8h|}o;;o0Sg zj?M?|7e~(Hq13!Jq^9cJ5mXOj#;u|@VDR3%BZv$yqsyz_LzZ**-xzA-glfbYpwsHQ z-nn>MvN)!AE;$=B?aQ~DB(}=sZoPI1*Anyy`ua%1_`RFQ`SK$-Sc%i+7yBe3g(P=k zXEMZ}!{u|i=Oy%t7#G{!k$)@wtq^tWTXCAv8VuzYU0zObelDXhc{qmUV?0IG+wymu z?~>eM?zPS&NmT6Z;qj(ilQ((fozL4PTMZ}A+%+mhNX!P_s4Htz$Z;S>tbiD-82NOI zwvNrny=N(TXw|+xsB<^8(H(&RR?q`JSz_nZD+Q5kw%lsIDTo-#neUFXMJaFEU49Dk zbo-|;lqUJU#i~$|TwLi$obV;y081H((5%io?}LZm3y$9wv+Hsy=^@1EuHxpHX*^Vq zk-4N~I@%4y;W|1$=vZTxQg#U?;`Pg%*Xxd4NFl^?^dZ{cc*&%HwQwzd!Jsq0r`~^3 zy43mdzG_jr>&LoNy*xFT;>|>q0ckk&UfJ=vbLtuA_Cx4;WL5zt0jBz@vDB<<6PCAnmp_ZfbMgSsMyt;_B)+!AO{Pe}G9wl1+5Xs(GjCY<(ZQ(4M>sxY_ zuMqNKk96`U9mxjNYo|lm-Id(ffz%h>xpIvJ4HOGsvj(5Dtd!KDNoMyDle`kc(6S0= z-G5vF-Z|-8%cx`n|IygD>Nym*+PFmbfJe#rbzx=0M7WhC6xt)oNuMzl-^Se{;Pt;H zeyD0F5||f@mm?)0-MS`S{Ve0TO`w!Oy6SrjJ}c|O2b9Jp-f==@JYX*mDPQkHft*RN z_^1+8H=&*LBTmwL@hv>w!BFT;R>?1SPOaR|%cDJvY=JAQ zl31I;{xIAeQYT=Q5f-|HT00qpu&jG~v52 zl`m>jRTn=skUBuCm{fp`L9swOHA`MrsniFk-1|j#q9fc3*~xnnSDwXJ9Gbh8SM|u% z4R;3KVLHDirI=I+>EDP0F{^^a3?;Mj1X)gJp7l~BPwXB2VOhVwRmhiIXGM`Ub?TO68B3CH{k$!Q2Z6?@8Ie?V5Ff@mSSvf!;aISg^)| z+(W`>)sn~FkJXSUF-YYuBSOpRVRTD{KaP6)B0WP6 zIlB6CZxA4+wT|p+u3wokoOeUVo6ca-ayr3k^lhKi-Y0eY zCjYqb8w(gSP)6iF!XOU;=TX0as4DfO25gj4->*Z=139V0LW*H5qY@PuVq#dPF#nn{ z@r(7qlnQehGhS$PGxT7Dh7a?-RizAEXK$rSPC+TA(WA~gkTd2lWv|z z{*?awLmrb zBBLrhBm4ek;%jm9Jl+NHZ-%K$zaHneg!-DmsMS$Ng}Mwy;8?Vn(tYw=o~N}}QzNY$ z6)&h?Vx)JT@G04M{Kz=7)*Fw?=2-l#ZqBKapkaybVsHk7It6mM-Wo(juC5#TaBxA- zMM`zB_V$r$+C6AS6z318DuPQjd9CyFa&?@>7Pnfo`m7!0Fe!Vak%}nNfyy^9N}A8_ z*$b(BLkof3-k4ag!6Omv^ZOFXj^wod2lltxQ@UxeXm-sF*}L$C~fF zgE2%$do19eaU?Jjt=to#V&KyEyoz zW=6*1m;eZWi)T2Wa5Mmm$oyoVM()$|JLU-7TH%rnfok=wj79g1N77gE(xM z>-UedV_DL7J)61O@C<#}WO~b%TxNr6mSr_H;JrS!1aPS;jzsb%b*%MM_&knJhZwg%^cFAlgv0s_ z_ZkH`d=Gt+(vpVQVw$e*en@+!-vI_63=Buxqd2xRW|+Gyle4KpCnPDu+S{pWbt}2W zmF}V$R-F3zJgM#oc-U9OU=lwxsd-ks__i`zZ|wSfq-<|zBq;W530}py^$MFmM2eJR zi3h3Z!=1dlr*NWo4dT{C#c=ZnL5dVmaqcartNH_MzQp|7vi33H@fxUy2LU`3+pLgF zCySCN*dYmIt;2 zr7cA8x%Twg|J!oVO)Z zMlrb%h0}}CyCFlfkYuSzT}x|!O> zW_fM6N+>nUhhOAxNdwosPO4j(^}`9Jmg5r2D=$-=MrZ9hLPRBn35BtSBSq`ie-y8S z6foU5J@wn)r* zgMz%BtcyO@SPh0UOBZM~pNl{4<0QE3FVAg=B1`FU#-GoX~l zJZ-3;1~IrqXtWtqLMdu|W2aGc{qYD#)vg3`e(!z++yHZbWDxU5cLe#2mhtCK zeC`q1X7}?9BDxj+9@2EdGnNJA+o^WV0Y1X#b4a}87Xh@pZr@7`$<0x9GDYG9C8#M)^tJIw6J8| z*C0?YLIciD`3Fg@3;THlD&Ubf6t}Le*{^#NQ%(-l&<^?%j-V3kHn_Da><;9v7-Tg+ zRyuu3mYl?m+NiQm`}D3@zez;@ox6Tgd`t}1Rj?D~W2gKx%poN6Z%o}?9yTm30RQd& zj{oSn(wL>R)SQlwF_$jCw1LD&sOB;)O3gbNW))4)g^4nA#8_nFQ}_@HGmNn%Iw~C) zW`oC53F@A1Rd#REI~@m?Y#b}L6ijjxXXGQxnUj9YG5>-&z$m5Vl%9MyJ>#x2NDw+Q z@Xq3PI*lZcbi;^HGL{3VQbgYdr|`ecawuZXn8gNZ3>Ty^0=YlZ*t>s_#?T1!K>j;G z<2Br+horIL2OKYNY7t>Vs66Ad`<34T%I{L)OCyQxQ)_k^8U*maUjlB%g$&h?x)MY)_b&W5!~ zMA1Jm_t-x`1tRxGk>$u8L{i?_Ml-SQOyR)qkku&8y7=-PL&{0>(9WIH1#M4$cwtt* zV0VP%C^!OcD0#Hx&2oGOnI1@Ily}!aUdpU1hPi5OhX}#iv+3@oe1X3X(BYCH*_b zpLTsw-&UDoiDJ}TG(;~JGzLj-nC`g@yc|R_*JSM$y=UtPxfW-?UyFM}v`9bj0Q6_x zYe-kLaS@~N8on#y-9^1rk;Otowk<5D3Fyv4-aTqyzPgFWc4>F<;)qW5-fFGO2$jV$ zK3&uJ9DL^0#T#!Z-vX#tC|?LfmGN@;C^m1W-Vp>Wg!#8{&4`t98(_dry1HyU5Fj@0KRAiXC);Cyk(gREPI5^R{K-h@7X5uWiM%D<&*L2yeXGk}|EbP$ zQDW&AlIQo4j^z<}YYk`%Y)F4#H4&J7Mk#^DC(n`P?sFx!v*mu^%d+*rp@k;)A{5Lh zIA=qWBMH#y8Dt+6eO$Q$iHC?D_#qtxk;Ggq9|O}>s@+B1&<8$QfA>q&99U}<_46%` zcXZqn5DbhYPn(Hx?}mvI)FShwp-x2#Xat~E%P1+q>#$Z~xC zn<8S+?~vst#=np?k;8W}Na2K+&3Fe4_f`=@$7KlTk+#x+II#T@2NtqzK)zANEgL6s zTKrG>Q2+b#VT~jWdXF#;7~RTzNLlYwwLi(L+m-522Z2yhno|4O=lFY^;^gcZ8bUcE z%h8;^N!}2)Y<&qS=>Z0Q&F_S9PJ(c9L^0Z9(k;_Uc{cqa)dNj86dMu=xa8WogN`xt z6q$LiAp8gJRJ5lw1?6i8@Pq13%S`OwzrliO);!7DS3F1PXSPZcY|^In>c#x~(Ha+U zKG)wLogUXsmO6Oudfv34@yZJCVwM35g7EFPa!v!MhMQC33E}ew)un>80iV}}Vq2-? zQI@{K$N{>V4_kUluaIA{fB{2>51n{JC3eoE`meW?cCf_2V{%t`MRiBs%)OtlTJ=p) z<4s4fcFr%{783%Kg$r8EpHbJ+FTiJdvR;!=S8t(}4DgvQ%)$?A_DrxX?4mZHq?_R` zoy-_^^zL=)&wJ&Toi|O*o?Kz|HIO&jDHSa7PJQ;Ykl_BRCF#jVB{+6Ion3j|@-(;w zN@rey%{Ly_%fz4%E%I>Fr!2bR|EaflhkZA}M1t|e0=ic;2 zsz1^p^go~=eDC!l$&uH*kc#5y!UIiGPpjQE|A*g$Z3w?)m~y9|=jh2Bc1?-3(pZP@ zY4q2Lwy|diWD)!lpN9GdBtF>+iohqBnRm5BGfG902SIXTwbPm+9jH>#QPhl3m}lwQ zZItG+SV&Ov`=oES%dl0QHn`^Ud22~BaIgFA7Dw(cYxd1JfEv}7c*h=L!cP{aX@R#> z_7kai5(?}?OT3ry-(3o7nof8jIL^J7no6)|A2fT==YQ^JY3+*l0zb%JW-}{ZfuOgr zpBS}M^U72C7dU|m6(XQmq42H{v5daaZRLLqeXz)sor0^q9 z661ZjCN?1JM3UQegrR%_Cu8}AN_5&%2{=3hxQ6@Ra7{k>O_ICOnC|vMHay~e+3|KE zq!f|v{U7`Sw8G!>3lDjj0n@Y+#G|~UCw9XyFwNik%bRBiRq5WfmMe$$bdZPR1;_1a z91;?X+K&{l$)9-S)7aY{zDJ+kiPiWB0n$^qa@_+ir5SWcrbeLKc_JI(KSuA~8FyIA z)s5PT2>CJ=O4s78c!>yTgXEZE^DgOy4~tNmUy_VT;!+)qs#C{DN%OoYv)JA=KFNYB zIHbJ6%cXjH(r*D?hLcn+0>)^k(-176nfiai0uNtR0!EIwJvvJjFJ~xV%@BppwJ zyDTE-MBr?F^{f#Rjm}+9!${Ge(a4p-1YIS`=^|w}k2mfFBo^DytK^`i%-GUY3?w1v z5Tz}DQPb?+ZRS&XSPB3?pXk}?ke4x(yh`XfR}l}$L&ktnD+;NzRB_S)a~Zj75x@H~ zVltq{yzooyL>b-FJ&d#Wxk)@kpuqhHhuI7Xz)-FfsEf-Jo(JS5#&ZPy=u`5``Gn1i zM)`E#7fKxpKLA~LnARv#bYwtbO)jpn=F^p+{`7Vc8hm&^#&1zy9i^Hmq%NE?nL9U^1A$hxL(d8Gx_{iTqkKgj$Q(Q7i#Mh6M zP*`VaC6MG+f&*ytw`ghXVe$;nqg2W~&6AqZb39O!SZ$`1mlp|^=Ml0tjaw0rW(v3y zPO?pJYiwgVtGjMLVc(jl(_8~NCc=*8Z)^Plcy`(yfu#ft8wjTmyQBfXDLmO!1o%zc z2vt2_D{rXiStR4YQqc4gk}xzdPl66!A)_IfDui`^LB%vBfNI4oVQdccoAjfuXfj>_ z;c~$K_@0bkSas`Z*nZ(c(9Mx+|8nFkLzIvsR}dG%KM!~|8_yQ?^T-sKR7s7XDYcvH*HBo)d{ z`K+Lq8fy^I>jal@ssN0DyBTI3`B5;k$yuy0;)W zw=7<3o0^pil=6tyXi}BG%r&p@a_$-JOM1Kwc`nk&JF<>J z;=wy%Od@IepSAQepZgY6S5wwh>rFG*FdYBj?KNv=a#y_X;J zJb;uuj?VYz=@$M=r+eqI2smAz#~rhzs|sckP?52&Qvt>hMsW5a8KPiDhA;;5&u&4Q z@?Nj@(+Rm+b~ebDObPjtQ*d&?rwjT7t(!i+X4(BWH&1D$w%>;%o zLNMmMGl!6Zc9R<73H?L*5u)Zc&_h`XoDMAk8DHQ&1n_f_gzC^bmPBrSP3v{aa{tYuloK3R3(Ckq9W@JFTK z_TSMrfeYnm@PT-h7tGj^XHWwQikfVA)5-2E}t_E>JAz;1bL%{r)5WKm`g{U~Y zr>YI!kjej~oNbQm2}^=(;rqxA>-pi#XAFa@UC*8CBAhpS^l|^E+feX8F%pJyod7?>>?Q} z0-6=)2y9-_c>8;xF5JvX!a=|8aY~l@R+Y6Am`)?{2G9pe;?Cg$c|2sS1-Q!p2mvs| zSsA1V^(|TOSiVqAr5Glu{v4EK{XHe}NX(C#mn8|hZ{i-2oij4T(-ne#gq8oh-TVC3 z4_WR5Ug=}I`0!WCW+}~$pVVj?R2LRKxVRt)=&pVQMwu0NN=vq33Z?WzouD@Vos+^0 zSg|Y~Lm0{fA%Ql^Ivd0=cO#eGNSAT@;++=R9FKko5pqc9!uX-ESUly{&b;pW4jf+b zI2Av~@>k`O!v;4`!{J8Mbrl%Ld01|t8_eHNO(oE`NCTR^kzboVJ(~}Ckor)&h5D$L z>mfryD^F$9CoxdV37$|WzlU5Zd_PEMZ#Pf>SrX^jC9VBxrR19-V5>IW{N>e&Z_;e^ zH_4dVFPqs5vHE09it{}_y0tbQHshP{p4BS%zh9hZTMR~ah9kXl+@1d7Qf+HalhS+d zAtaD~wa9y5HmIt+Z3Knc((ZRZ16;aPa09Ja$qPAa+z||4yP;upkc68cf%2X~9)6mU zTBsX(Q``f7DLB-IU|?$1r%*2M(U3-yw$`!!gOA_L{d)qX)T;wcZdrNZ9WtR+`*;X= zG$$$Y0>wMxKlA@q7!fF8@H&fK`m>5wm^`EXT+aOSb3=UtvI>b={tGQlNbJ(zQ{7J% z9&CQ9BjX*peA_|o09h`u2{9b&eRK-W`fUbaC}+aUAVpLDh78;0u&HDu4F82d^5qFX z`@v_1MHfzkN06Q!d#A=y;~KRUYNWs6^!7vNZ}?57TY2AI;KCs)96ZyWGQM|xuz+EN zllpbSmEY9b1Yqo!l78GA*MWk2xjU{H;I`!*SF%W%mhqZ@xU5gSvdxB=cVb`Y<=JrM z08kZ%U=9Jek8`GS@vD?^1QVXq-?coS4E}T#>w+3>4cq3xq>^1cPZ9fxJzLt$NQ;ri3%?A8~DW}}D zf|Rty$chY=QfP37WDjQTTkk0yj&nA@Z{o(7zIr>oFul9xWqp)VgYk)brr~hvBRW}t zn*AucMN45nf?tjc0h)gtMcm?h1wCc>1PSvG%d(IEG=S`GZ*2wP$tlCa%Xve|9}vwH zzz~Qm?>LQ{b3AQr%I<34ZR}J%x2=(8C)I>@DJ@cgl zA4-zbR{jYGk8dTYm=L^T0*txw5h%pKEDKSr4spRV5HZZb+V!o2w|N*jL18U~A3oUM z;7mUUwjLGeD%ocHE~PhxYOpQRkFF@^U?L{M3O4i(m_$oQDTrCpQ_L=DBYL=Ro<6De zf;v{`9&rME2mMM3$Kv)$mJf)`Q_Knd6PAU~>8yxN{qbxB$6Tj+_RHInEj0#Gmo9$V zcuxRB|NpV}m0?w`-PQ_%q^N{6qI4tOf{28Kv{C}n4bt6GqI7q+bS@gCq@^3AS#-yD zFVyXO&e`WX`^Wz8rPp#k_lz;e7}LCj0`F4+Ww&ybNV>u={E;4~r4ek17x&HQsF{^6 ztU01sb+})~oRin?UCJN7eezMSA+D;muzcZNk`O=lB=uG^3} zpuUVhR3o!DE^RKSZC<_NxckH5il?fBJ+k@yM8G?jHopjMWAoxiL7j;7%6Qe|?u5O^ zFVANs?2i3x-ww@O(GH!>TiJNsB-nQ!yxe61rzPm2*7mfG1qoa_t(Owbwe|w`S3Kuj zlMY8++r62TUe4x4%LTb$A#VIRDqyC2#{mP^iM%_3erCZg{@F(&pgy4nD4wgi~)q|>K@3` z>L2(moEC^3Z`?bWACOeSTG}a+so83J@@1Wd{C>WjT`H>1dQd z;u`QUQT029dtO%1mKIo(g_lLRDk83=o>xYYRgPN(r|Ph^<+nWBjY{nKN?Tn5j3+(0 z4X{!lYdT6vw!M?7(fsX99Tixlqc5kppP$`rZ56rBLL$1anZrH;@(p$0e_KO2RJH|i z-|7<$zf4Nb`KsL7^VFNrf3yo-ejer0K%8T1S>k=;l5|tPZQWw<;8pdGKVR)2ex#?; zlzB5FX_ewi%`nHudefH+dc8RM)v~%630?PKSIzpl|&H}gD$4@)AFFz%( z+jE;z^;_T*+Dz8r5kYI5sggP-1gflJ;P>C* zHY9_s2RNaDn?jhcc(=Y}PJ=64&JSZy61~mu<|}Z@0-?@o8a(^PW;}ZtigBrFA(|Fg z=o*h9f{8%n)ZtME?7Ncy-yOxLX3aN_%ivqm+P120+?{E-X{2{0+lL@cj|!CvQdcXa z3BT#(F|dz~imzDzQYbp@13Z1@JWAI6*~e7(K*woBkn{w!pbp5ZwCugpqYsyUHZH~T z|2OifEc6aJXNS(b&F5~_g3;G3dkb)i(pRYS&q6K-Uku3LU>rEIi43r?E?=5sd7K?A z4babI>$M*xYs1S$D}{5hn^BQEX<05D3+!!vr?_P-osBr}UjcI2=Z6xp@-A=&9p_s4 zV^4A)j>VIushAo0Pt&O0IQ3@$T98;mDk1+rH3G@}-mGt+OigDU;r2wN!QQ*CnnWDhvZ3PswY{J-`j?Q!Z0(fBv>K6T@=< z&Ib>ObG28d`ex}=r+J&0Cq6f1e)Sm9X%WwbhjA?VdAlY7`};Vg7xA1F?k1C2nh9KM zn0DtKM{}-bE^G0;Y?$2dm2t~=rP5C?wk2cxl*l{5(7Hvn6p* z>0vr<)~A>sz0?3*zv0p3qaPxh^_Ac2x=a7hq)RtqvwnVS^Qhyp)$8>&g9c|HLl9)( z=O(g}(G5TQjc}!ZquXIt7gPQv;;F~67Qh}yaEz0+ui82JA}mygw87zE{n5#1-BQ8uQp2B-+ zIEBxtxw>MT)|?3t_j1iSbtNGr7PzBWk+{sOaqa|PZF5pcl&^4ha|Ec_Ey+!d`mL?y}zqxw&=ts<6R6@|;E4u*zow?@q`%`3$h^U6{N4 zV%BI#dqH?O=4?Ic6zT$*%R^EGlfP`1I^#3gSLyg2G3QBGZ_LQ0`8VzDhEdy2gMuBa zHShz;*d9_D3TeFhVqvX$y&vgw`?DX>tt?m5h$e*tf#0RU(}tn%28L27Sg(!Ilamx9aOggbS^0M}TGE+J9XJ zvXDGT;2#0_Sy9H3cya2TX-@H1xXuR$bd|?zndgIUB5}o%QH>o>y_1AD6wu_&>N&6v zIcI+ednY<(GJo9bmN~}fcS@hO<`8(W+t!#rvVoqPe~xO`&6B)RDYtbrf@oLxqHd!$ z-Z`Fq`qVP{CSH#qBd<-VtA9U9uM6(hp43|ues}k^@DY9=c%K<;7MwDs=Fs2-Vvb3H zs@2m8bvKDZdv4K#LM+6bq}kbg7X)9&!d?{sEqPEsZSJ#=Hw&R?ac4+ zYP~bYc=Hao@`Q2DgQa56Op14b6n8nEH~eyPqt4&rK*8nam6I+Up|fmP$>$HqBtzz( zlo|FYOp@>yqIUr$0bOzbvj1e3AF^2&GjNb;wA^~XP%p2Cxd7X&;1rB$)feJMGg?Uw z6Y%l_&^RpuB}5u|^?M#|6#Ys=`s$KY;F9R0JI7Xkt&W;6U|(|FDtTJrS7$T*?O%J+ zlYeD`R&XcNP7+EEccVhUGmDLP7mxO0=06j5zPKLJB28QV8lmy{F51$mI>H_x0^` zrhVE~p}uh zYoEsD9D+peTr)fN%7a4MLk)c3$Ee{Nh`6C-i8kskXfU||wId`EA3`$qaRirf-d(K- zcfaL_I{4|4)y$PY*o(m21BzL?$@i_qmy-nv?&}v~gP7~jj}=dbd*=@8HCXi|n_{jIv-f z`O*5c87^;j26TDTD4I_+dI4SQLf5V7w?C_Sb4c~?#?*3}fZO<29{l#N-5uik`;4{`|qa zp0`OtvO8-195T94gF`be$>0RJ)~KS3Ui)FrpJ{%rS_ z^8XEdR)Hc!6&@QUA1Loc9VhhBNhSCxqFoPIwK1-Nil?BwmgKqTru+bz^n}NmE zOJwoT3@2m~mwjv}CLQj)xoGkE!ufy)&4j!bhA`gm=^z~c+a6eKtw%ULly1zy?2= z9x;bG!F|oc5>5W*?a3<^>FLh;x`k<_*~x%JqzF-Tc~@S8ha2LEAV)U7vEqLn6<{|$&Z+*=rktgj24feFENfy3b+fBUn* z#b|K&{wZ+In1NzqHDf=sP6c`?JNz(mJDS(U;Rp55y?I)aCczg$AzRjUqt#fW`cq4D zIrUrjLrwv|j!8d~whr^FuCLX+dt;;oZ259?kWQkzzm*OwU*i5OUs?#!@$noTC|?}x zN_|=@bJAN`xEP!uI65rYQ8MmKlHLh?70RnUl-8lq6c()4Py=3l} zKr=LQ4U<$^TN(dH_GpZfH|4;GWe=p)a-*4>IIH_5szfmcH>DFD?Djv;ttV__^xBR= zaiAD;daRg1__XeDO6o-{#(;=fG{6kn#po>UrK!&WZh_e!Zo$|7 zB)m=zar;cs1EX4-LcODOr&O$%EPsBO{5RT8_gEzRh*HWEgSSN9JO>MMhvDjR8~72d zvU4x?tNCBm=>qkv?=znQj2CDVqnRaOp?AZ2=)@Qz=305YL39yT=R1YCUO0jJk^7zY z@$q1x=EPK?MA*1#u0|tR{jT>CxtvoSAMJ&Lj)McRnCZqx=QR#DQ68I(_nKL4_dlNV zjufCX%r2XTIP=(} z30C`oFR{()HFIv+V zk%Z{j->Gb16#tMfo%YByUdYxUjyI4E>rwq zYc-x?DV}V&P@2P4J$p7-Y>X$DJC2%m=cmV(rNHueu~(+uQ{}xAyftBV-a>RH+OGOS*%K!& zZ3<&ZGaD)7t@+o!gSW?m1g8~r>T?fnG#deC>W4yZymh>+`wua7Y0mR=H0GAy1+1mu z!-%O-fY8Kxs}xDnh!OZCq=GL;*2EuOet%T!l@~n_>{!8exz#H4b_qi`Q+l(qx95`N zdt`9N)>lFIb;c?5@2^u|AT6b_Z28_Map9|t#6W{!z{V`}O5N9%1!1``rAq#9rOI=p z1YGYnDyQLT%Y;{k&wH7MEo0;#tc+^THFfGsp{dvSjv$9-oKR3ZAtZiV??fRWhYO*Z z%l*oKxlfSqf|>%fQ@jU9Dotj#Z>C0Q?DFUDI8NON73fYFwOdRkXf7h9FKla7YFD$r zVA=jLk=Q(0wRhvH!Zsb-^^OYK%5BimNt}`B22Cukgo{79L!F{>B8+)9{0BwzyaOLOeQTM(>tP3%coaN z5nwg-*&CL~=B=6gIAqA5`h0S*(P%m|`&!uSsN{)L3*Wq3#zhg9LTm^7GO5Hb0>k$7 z)5>5~u)xw~dER6Q4Sbj@(F00!%VJ+vu4gg?zgl^)sjdB~3guJ{K$rgz62WT1=HNtl zm`;ec&m-v00~2Gf|0^Isl~4-cs$KU;Vii5tJrY*p#PeUDrE~>2nFe$sKR-)d+)(lN zp?F#9+i3E-YTd>68wNNc$RERFVB!{;IG@V<&9j)4ols1R zvFdH!O>sP{>(#8dD8zsU-2SbgdRLOC1(Cl8zRT^rU*DypAX1EuQ)<}JcpYTg=*WR# zxz4heMRG2#^R~tV-;69Vxr}DVpph--<1a_}{AN;{UL4^J+{`vKY^m;Rv)4Q%Q+w~k zm)THAB5JIuE!X+6_TggPu+nQBQwTSAItIG%8KF~65h1?c_IpMr^!SZE_oM1bq9X|D zJuTg&ru+Sn%bEVzMo3LzbXEWde0j}%$fd50Ee$d|RkFzf2a2 zm55ZqLfE1t)(!w}uUX>Q5Bera_p@bt5nvw|rv{iGttZt7$8!NqTu!W>JcxY_k;cJz z|K%!ewX--v*gqHqfOPUSEcS%o_8i-Ypp5Q8ny#&7g zuMuQ&DsA3OIsfFOYJ$C~mYoLg z?^f$!tPb{Gy8kR_we)_sT6LdvTp?a&{%gaW3N&_`)3OrpWoXaM3m&7*K8= zUvyV7y;b?*j)G}cZOM3Crk8fw&%?LTy+`bR8$~_1V$PwfS!yC5B{#p8?!9^r{5dPh zY*(RfQw`MhX7APVGdulrmF;lbC$i^O{bM{$x&#N_HJ6t(agO~9JL%?5o9Q*p!!}c1(k=<=KRO?cXz@)eTgdF&1Rbh(;$f_@Vpo2!kj>$HAgM;C9T^$o1CYifF}rth74u4ghcd#u5EG*3Cd z+O*@d?!bLV9YIlL^+Cc%B0eHl!+wjVA)k+Cdhc5>D-Wlg(Q!*p7@hB+(hng{$20YC z1k4=Gt~2dskQPlcM!3cMPR7}@>E46D=wf>lcJB}Q_ND4g@sFXwlS2ae>obf_H=3`Y zkp1Fu=VLbX+lKZruYQ1y>mp9<2l2oEtN|lg34GS-1bo1>iQOS%AA5?Q`qnV4l#@OT zWdLp?ZlOQjM#7bVd3j12xui-Eu}1irtf|>)d{P4m%(=<>A4ne}?!NXgI}n zIX?>&JDHM4lmCG-s)^aDsr&>u_Un(v8hW5o#Zag97vTix!0*O1Azx$zYljf^-Q*J#4$e7wK&W+ z1}lLk{dAm1DEdkV9_Yo)l?(5_j0dvR6jR7Q%$6lhEi0R3{Z~{{!ou{s@Fh%BBwVPH{3tY z8IRmO8-U(I@P+v?<>&qz;LvlwmeHr)LbSkOq|;ahtTJ`(<2fx!{sM;xs}=qe9BPTe z$^uCSo2fm5)>}~Qi+g9B0t34*Dn=0D76GCMPCef?J9IH@z1@QMF&( z@hphv@kw(n8PwT6c`)O1WC-uc7uQRwbI@*@c#;8@=PPXsd2yM|*Y%WEc2)V zB2@jT#~BtMx!4pG2^p-G$sr`b5=(R50OXf;boP7wK&UF4o`8xa8f#|`VV6NztE|f? z8v$bz|4}_Ts1?6!fY#sE0Gfi+KQ(~nFg+##)PTmv|6UDvMf&B5OmZL0>FoXl*r|(0 z3&Uwtar`7yZja;({Rj3-t(*29_Ee%YLpzgRKLHkq-^Bfc?JOjrWdaqdWvHmw$$J7qotG353JBdV0MN zm*O8S#nY4tUFkT5hOHSL@t36JR&a-P}j^utRMSLB1`Bd}4%8PsD zi!{xMrJjbM{P5qIP`t*#hsSP8Zl`zzB(%agLssrEFznk1V$M^dijmSo5QLVM!-|&4 zr_Y0f5~!V@S4g7^TEj3?q_1fb01cZZyH;$=9S#EyAC-aFpkivf(ji2CB-n+Ls!|wu zxtOZ`D@<|}vhTmJ51C36AaxEC^E&P%Sy|O<5v}(gX`{-gO>ZzWk<7(ayE zIEkMf99`&-Y|$$S&X-{d3bBL_=gJid6u#-oZO=1m;>*@#=*oR`5BFkr9k4^PuvbQE zPy-=4^)eqgrZ3SBIk$bb)y@3Q zG-71yVB=#(_BXe}McUKu=(AL_PlooJ(~(S#uA9^EqjvkzI*g9|b7BfG{j|pUIi!h{ zj96rn$<{XZZj}~(QW`VmhdG4gibeO_$08RTe*?&6ZfX3WPoL}4!n_Ae03Ru=RXv66 zjsGMvD|qbr_eUyPdPynmBE4adlnF}TByQLy?$)~ja=_g&|H<8<-ZKO~9$}?v2D$wU zv{o89o6qYpv7BHu|B8ZtLx~YdfB*h3aN+ArIiM4Fk~ujIpG&CK-+&Rx;54S3;1v$G z1F_H#r7sL8+c;kl#ag5hvtt4&+Ti;APt08?#okJ-A%I1hSD^e7sbz{R2K|z4i}UF- zxa%!J>>WrB9Hu+ZM{6B?gsmz~4dpMc6-A@v^>v*babB2j;D4)&>Rw0SSm(Zlsf!F` zR>tj_SAg4Mp;9kHAHmfQnyg*1{81ufav##$wvm!^y?wwoaBHCRE}V*;uXB-x_mO3+ zc?hI-42G3&Qi1MEMw=u%oM=qx>-V%MnCzaKW^m{&vcFGE01eD1q#89J79UN_&wz0J zH}T;Cg~obMMa%53_+Xm$?iE0b|U_5M=~bHu<)QqDui*f1EzYD9P~b=b_90eCp_9PdEn%v z+*IQ3r3!!m9;qY*3N8ocOINc+XqND$lDU=Q0z$NU;IiJQiQ`+vum8woZmL znW?bWjkJf_iV=uuy2EJ9JTMsK$kIRxR7V!Ikg2k2O_wi~3lZ*mJ zuW0{1Kh6w61+x@g+dHCUpPsg--gk$q(>kJb(sRkSP{nh=tq?=OFT&bK93$%07{*0X z(4zjv_KzOR8mCOZq6mx;kTIsMpPHkZ)gN(flwTdp)r~dGo?Y9FC22J2n=?8(wHqlnX}#)ow+oLh`Eg45q6{}ZqxlRov(Y!u?)klhhxpa>nJI;z0t@_imlT+RQ{u>?kJb`Gm*(13x#-h zQ^09_&hkpE_;~h-pb$vAlHqP&J#*N=qkCxY(e3~B0CRWbf9^<~ z$YQD;N7eqU_)TCB@YY}osQK_UO2?1J+bSdkK$Uq^)Hv+#1y)LrQ?@rA*JBVk^B?fw zR(6$L*DO(5^W`$f=1y7$OewSa5w-+(9S1uzcBWsFK>aA4XoI&Qt(YVb8#8YW26#T+ z=6JJ^U8(RlU#_0G?a`2c-T_4Dw0F3LTBGT9g5VlF6z}Y~q)=f1TdTNQM-Qu$^V*>? zIye^)eq}tJ4nGU+es)H%cOD!DGQz%6d}m?_nSIu58XwSpr*;D47NmC2e#`vTe*fo? zKM0y=jwv(be0P5w0%tZ3>@PIy7##~Rcchp95vHq_?X${&v}X zW7M)?Hv;#j%drK&aa9)|lht>O?`8TZmBT%E9_tx@4dmfxIe_^vCV#5>GabGE%n7XM zK*P7|2`t8brO9t2jEoAfG#P9P8a`MR>zU|1w}*8YC(2(H7e}eU?^T#44-R~-sLtlf zpP2>(IJrw$p>RoRle)8==9ketzR%67*9FYyu%*3^4w4if<~O)F79iA<@IQ>Z-1Ei& zT+B<%>Da$OPa56VKe$(P6+JPe1Dirqx5FLlYDYE?j-gcjXWjKpxx7ex8Q5w*YAbsPh+Oc@XQJ`*pPjwui7D>E z4CTbgIkvW*d5QhQMD?3%=4_vHQL8{dL zC#iD(82DBq@w&_qM^qNCE`S4PQWtym#i-%ked{7GJXzS^br28qGb`0neT$DrTfVzyW*#L=&Sha5$y{QNCob-P1XfB@6syc>JbnH97_ zn|0711XDy?=T-*jA$Jm~O?1Na2e~PZphz<}Q#_LW+x{Im#kH7SsmSUlJu%e|riVN$ z9S#(0C1sn55*7x8ttF zxlNs~FZ^X;=EQt z6=5bhFj!*A5IDHp{m9RL&+l)?UR%IuyJJ&NE{;gEz-}`-z$2{E6D5zYXf+jjUCB)U zBu5zy;8OOx7s)#EHsb>*(JcNyK#7w1AmK_Ia2#roeDaU;`+)xKb#r3oHKDS&SDoqB zTgx_|ys8D33A}3^?>mM+I$mtDZ@^Wn6y=lrT}FU~BHIQlXzGxE##FeD)o>4s4AH4v z|DawAHEC*(q}Wu@1TN+Hhm@$;RuKTBJ{)79+3qe*3)d#!1VeIO+A#`FKhw_k%H!s& z2O1}LfzCnx`i<>kRqlGkgX1?2-dz)yhcs7S$>vQCch4-dzYoA3SrSv1Z2DUg%JvZ; zm4?`hoc+vGo%AeE`;s`hTn$(U*q7IQMEGBqLuW zIM`CdZX^XfFvvf7VB>R+JN={)7sG?~C#DSNy2~}gm~kTGt3R;tcdp6@w3qVYxm13} z4Aw6G)Ls`nA_IJPnUzNmFLi|l&tY66CyL>7+5zdZdYIVIx|$75zV${RXEu#0?yr&A zyL%HpWK}%kHD^bvikqOR_#NZ*$du4MJ;3QVncA6GAV3i-Ex=(ts=$b&T2N1a1Bft+CY9p1MBeVS6$pO81O;{fLl`~nrI~{y&y0^>m(Cm zU&8q9zmz3X5#^qP>vk{GE0CRo+?oS)jrx!MwM@Nw!rf8ah1IY$Pc(I358P1~10AuA zg&X7T^D)=)d*w5R!{*jA&0Ah0)5mnzExtWUUe$Q9`5?BVSJx5n3L50a#J*_%-Qep- zJkQ5~xL|_k)$c5}vY>Xx29~ObG~vBKu7L`bj9H6K%Wz_ar$sG7fmT}*& z1bFRJyvwo#E@{eT?g+!+b&W#(oxSxLss6?!Eo}-ol9Lj$89$nZSXp%{e$_c-Em)%?@#VTZ$@03 z*F1^*%e+R3I7AjC#rMRYS}00yLSQ8fS!8LN$}i3>4X8I{Ag0vt3d}biOCjT#n2N8N zg2B391gmut$Cv>Cpe-+NmeAqt*aR@31iU|urW4ir29w(x5NS2~#Jj$JE8j2U2Rn)3f%MoN~@sRaREMIAxmWV2EIv|3$g8f>DL zOE=G7VbR+Pp1yQiicSMPq~yu{=_B=;qvQ$=yW*kl*H!@oxoV6r=CRs=3Gqvs^dS{> zeYiCq(;AdOPMz4OP z`3T?v{(gGpX9K(^u;%|CE%&UQbRgA?l51c^)vQ<({8Ab)5ermK9)efLRtYK_^Z%%9 z_d*6>l?_SM5Psa06@#0QiINSKY47|HxS!1nw0Dt(NK<`!2+fw0xfVsj&2xwkkP^3{ zz;b7&=Y#n`^q-++ZtEW|Lazi1a!VG3?&96BUFoD#yl@yUPYl_20$^bSYH;FRsruti zU-Q0KsZD1NGPE*j4JJxZ1fVzAV=~U~`3BFrUU`D+q`?N0(6jaw3**mazq&ZJ@l>DA zJv>+1ve%_{+EfP(3n@x(ch9jygxNbs*GCCdOR!C|1cFHROLG>nPkwPPB1#eBJlxmEA-;a1tcs&F7|t~e;+;II8r<0 zDgnF+9Za;eaRc{=w+htmSl7X{4lFZS6-Vsf~h3ae#G6wrOM+9>J4^kG(IQ|9cz@SVQbfmYZr{?@hky&5c70@i*df zr*V9HlLQ_cj^W|wdHKuyYbOh@-S=J0GT87;^TOpdKXa&PhKzc0ykac+@|}e6*Tj}* zT0dR929aTr6vkZza%%588u)u)#zwWBv3twuyu6|`w-Jzl1OxM*eui`9wU8LKHs442 z8h=!WGriZ%v-Q{GRH&oleU5U~II?v@2^dXN%_C6jH>#UQ+Y8e5K1X#*n{(M3cK-5R zMn@U&_*pF^d`|QD*u7u{141a5&QRMogqRbd*9fb6mG(5SgC!hwFLR1-=?JC8#Q}8W z)2a##hFsL{ayy{-+vyDgilU|589mr$WLJp!<@?ZwhdD~X+DisVhVsMzKEE;7fhz>R z;YgOL$RAy)pix2pCvaqU`$(IL!`x@mh=a{RN~ufyLtLABXVL+blj_gq%rtFy1o!7Z z_KNP`S7z>$gxP*l(1_uXs9KQGBhv7GCFPe8s;vBwreg(kdMRGQU*O1vSHO+%J}Igf z9KZz(R6fe$O}gwF3xWmVC*H!|z&R`?{&fnwj3zuRQUhL-xL_to-${qw{*6zrS}|Tw zPV(=DZ$pTOP_U?hS?YQNv#%+k50Ui%mEC!^ZL=c>fRA%wJ1|e(C#ceP&2nildVOA> ztHH{cGc^>Fs~5J0W-`GbPlcYa==~#WrOZ*TZZK_|&1n!_`b2!5_ErP)Phxd6P3yd8 z2D{AjUiXWFQKb)kf9FU^Rt?PiXmU&Ifi@=DlGJsp z5>QBu^K&!F@TXOIS+Mj6n|yhg&SeF#NuhtVnQT2qG%4pjUn;#BQD!hOf@eo7NjgBI zH6^No`(PmuUCg3gkD~T}6h1dHAh=k6`#l~mx|54Ow*9HXXHz^<9ZarA64%4q?F|$&&z)PAWiJQj5q9pn#r8)qN z*4a4|Bbvya2@$y{V6=X?0kdf~FCG>8^hFTRJN;f^u)ydlxH1G;Po8i^iyCPFP%^v2 zRYDY$0uxKt2<x|^B~cdM|6pcj6XdGRjx|ah0YZ48=0Kk=_u{du!3o;oos@z z|G*=pA!+U?ua(@S`--d3Tb?s)XbL9i zL$TkCDn^%Ym6j$(;F$t8_1&+RzSM2!slmLmP$F+{S<*Z4AJqH`R*}|~sd+E@nUALJ z%+ZrTPBT?IsLeGrg50#zLgmy-oIo+0O9^o)WZ8!<#M3NI!9XIG(8TVg2jKpscR$DsI{IA^m2NSmD{h5GZ#j8_@TVK}g zX>TjWoy!5M`&vb+JK^M6J`_Kx8QsM6|D%4LTvxASl=|aLIH&B09FOtR!JE#i?Qg~VtUe2;*d>v+bwF3n;tGKm0e}X1TkSq;Y zjByzin0<`d?T_3(bkwlR6zg%r=;K_fbHLE(XkUJO&mBXQE99pK+G5dEfntD&agxJS zswzE0Ma%=G3SgX=jGHbd3?im4+aY;JLdG;pRvsNhtO0mgl07zl)cLo~zXm92RUiWb z>Bor)N(+uQt!Ss(|NgeJ)N}tpj@jUCwfBR!Me$GGmdG(DUKWMZHueVBhC7bwJz^A}7^T)BNK=L8SjFDtmAk*8yYpG7kuxlS77mlp*SZO@8u zp#N<9{ox+?hF?D>EoSSW55N}=sUI}`d7!!dkvE`nm`Ew@aTrj#mpS8NMst4HFfl-S zQ0EP2t6Ia6*H=NS>eMr6zCOjMB0nF0dK~pE*=YGA|JUC7V;mR2-gx82W21bF+eQ@^ zTt85!WkmUY1z{+8NqGgE0)Av&0^wn9yY`o?ymzddUC=o`=q>6i`Rric(4nvhrESuy zmDFI`PI_%{h{*%-4?A0yD8>nR>*wEzWXWbjfw{gW-Bfza3PZD~W;w&isoLY{JAEz7 z(2jv^B%r!ID`l6_AatM9xffQzjObbB7P+=5rHm zzGtpAaj5O6C|i|nkp?QT^U@MNKrbJ&BtO2mSMNRnbw)O=JQzzc?{GLg^Z)UbmkU(C zVMmx^GvY`pvS|c5$0ENU&0z+ywH!i=T8U2Wqw=N{s}rz@;W#4Cs<&Yb$jvgVS_jM5 ztXF>&tHVjaTI!QATV-5F-s@3ta|S{3tN$EqMWAJgtVt&r-Y`-0oJxrRTysT;6Z+KX z<(iK!kIc0e8wO*FFaV}VnCM5-!SOv{fjYKm<_Fwx%7aom#f<&Msx)C}^U}PLKf?Wc zz~=W;z#kcV3N6N88CIhoQkq~5Fw8!Re=;SoH*`E@bG?)(ulaezq^;^>(nkI%f&h3ut(Opc3eNM ziI|3j^;z<(wK_kIhL#SE(@Zhv4{g-FOyMr&-4F}i*EFLBT0rji_Vu4QFQrn0*>r5z zf-7`1sR-tmj#z{(3-e3&ZV3@m_Mq{r5sdXw8|@K^W9IwjZ;Y-yd)n}bA*-0FlVbeNq%|y=n*h6 zxBO#e^tfjCPy5qxm~Nd9OVRxQAVuRtj#pe1Pr^Ec;IY}?UWa>gHZW+@hrN`gzVg4G zcF1YQ2B4Av^ZlJX9=;pnrsps_bJL90?!AfTbKAbB-if;wW%~*jw(HmDD&0*r(0@Mo zY04U(DX>pp1c4D#S@s;ok+teu}^guxXSp-9R=E>Uph5v&+)Yj zg0D+X0vuR7x%=Y$fEm|*#z?3Vlr$>Tlf^36ah&p#9u&=~p7MIKBWowS-9gf493H?I zjB)bW%Q!A024kj`ra(<^l?F()f1qp4$tt7q{grwN<3ES{<)o8WbDi~j^S)OHE{ZPyHz3jxQGo2Jh#$^~u- z-bKwC{q#|b>8=dc^PCTA#>!uww%m6-V-^YW^Apk5V*H{R*z!^BzVJOP;a6BG_inwq z%lgpY-y>zdex^#VYb-uGez#{U&gzIan5%?E!+ys0kg%`{8lT?YJ`p({n+c}UAR+m= z4=PHJykdQADU}e;sarLMCmGc17Zx?AwC`*5_dMoEMu(#xYqf$Av zuA8fZa~y_8P1(1R>+ViNAd`8FLk zNAI*vvht2LsI=F@RZR2oRoYn05@hw=*lT?-BUDkK(x6AH*m(Kkqq~_R`Bl0+ZdUPF zYZoIv+_O44n)4BL-)U8cmK4{``m^BmiP~YrOZnC_=F}~BuDuBRj4Vls;IZZx&}2ar z>98hSCo+w3)E;X)ODuj%4C(Ng_2FjQT9HtkBl4qr7z5bNUG@&I1?AS^M|Q-JKB0QQ z8(a*$Wn)A-mi!sKn6VA>*P-8&intv2P!P8fvhS&WPJT$bKu#&BljrVK1AlZ8Z3`FP z1^#F5Zy9JNh0IKx;^J}aBq4gc)5P+S7SsW|_MzmP${aGoW&L;g&JzYjrPBHo2PwiE z6cjLF2;Y~7vALB_*C)e{^_8Jpf7biTXR@(Y03%A4`#?izu`cdqZWV-MX=Lm*9`w$~ zCXo7`VypS9?5{ELIiC^1-F0BqPp^ElJ#L>h(KqxyH*!v1^3PZvSET5-^3$FX37?A_ z2_ZGL4hTtJIMcy_wi>wsWjM6iB1@0U4QVu*V zUpupEYzQ`m5tXW_xxn$RPQ+OC$o)L9I$0Z6C~;p4O{bmPHA?VQxpWd;MXbG;R+`J; z$p~-jzoJHyf5o;D*>xp|)eWx+tA=LVa4v@5+C9IoxTc*^ItOyjr!p zZYB{t(TthiN9dg?b|R8pUA>w(V&^(sND_2MU7{}UmZA}6!9wW6g#UFT2qu;EBGl}3eEI8FGz{GrnCb{XI&j7{FN z*qmaOao0=`mQvbq8l-6&!j`f8Ky2OCeqKB=HJ52D5 z>R;*Kl?gkK1WXSux4`)RYk$QEVJvf$1T3{T-dRoeDhh;=I7akIE80Y|rbKo1+oSGl zDxf_G_s<*4#y3dfecu7Dnm>a!1Xc86S(!@o=vXA>QCs;=A0;)_TI(r?%d>%MiVmQ88f7ClCT~CB>JgcL`cY7hhg$MTj5}%fB z03qo%scl0%2O%QQ(I_J1;_&w9)e5uQUVmhsd(N|o2=m3{dbeqwa`zq;HeYLe)@|bT zauoH%GF)Q2eR?~+Zv*;cZ)?ACqtDJ>*tmHfuA>l5n9TEq6x^&mn|@LWP3F*?U$kek zn55D#du>(exPex=RUYYCyE3acQRb0~v3|3TmpHcE7;(ns=vfEuKJ>x#9dCP>&M3z5p&505QB_dp?wl2xR4mmZwz;w19`HNKW zU@CH)7>0SMljfMWS25HHUG;!Lyi!5q(TazyZ{&=XzHMMsP5 zwbKbz8l4aEP>moOvFg+G$X#~vw-gXS^6nZBCm*sa>Fsp!l^_4>xi^#ldhT@T#6U&F z|3+L@w`^lQf{kBCq!an{O#EGv`0b?D4&%&6V|dmhrm69`b5tBKW@C?W(W>>F-jZ2T z$cX8R%hYV}0}@>0w`}KdjT|!0r(+yN?Sd7}hZE%LGrgnthwjQn`DBG!4GgV~0L4#q21aWKnb2R%_bVc$^0g-qH6>vLP z#I$kO2%60IN>q5ab-rZ2TNT{2JgtqQ=F*BTUw_g(Sfty7Vcr<+nLM1)lb*b=aAaC< zi%)m_wn{JNwDw)x>9<_%!+9ueMS+&TmR(i8I?e-@6OZ*{GNfg|-)H4|>^}A8gBmL! zkdYZZh-BmPLy0ZnD10hRu1MiQ`y>!y$!?V_i||0STnazy5?%VED+k`n*KYUe1uw=c zYt1CfcRX>P_c(SQHW(g5NtV5aZeWc-fcNS1q0^C1iuY|t^m8={fZlYwfDU#NQcLij zlEumOal7sQW2osLMDpA@`@$C1-O~wUf2_177pklhL9JqA7upng@{Fe~3@KNuGE4ql zkJPXz{OX)(UAf14At4=+8B5W~tn1fE+ZRnpx|D+9J5|^Dg0Z*<<=I)@hOKBit=B`< zm-Hr#4+&I3k-o0k=>yMtpSHe`@b0Sps5Z6Rkl8KDC1|FBj4r==qm(lms#ql?GF3LA zPf0_aW||~EqeOng<1HV;=xbBlti{q?U3lz-J8b$ZGvYN4t>li)m(R+5%Zyw-nqN%c zhSrf>4x7ig8?Hc(1IkI$xmolWcZlIRv8NBEVhxAPiB_hqB{*S%xz*a&1{X~;!M=Kl zv2yqeSI4>xgaXW$@ga?Cd)T>}?Ha}i%a=IBDNXuQm90WMkx>HB}@%L))Mw|EfCZ@O-2n(!s$HPJMp$H;tj_b?T|gR}XH7{jC2X%cFEYk`7&J z7#40R-dw&vnchOFs=o;lNU|ePvO!*dr{^Kbq4dEgPAu1oMtzKuIhc9^Fgxjj=K6((&p$N=rj zTzs#8-f#HA$AYu*v25m6WYP6kwwx8^^$4fc&%o7zu#nfna;X6gK7nCTNF?&OZZ(U3 zim?$dUY#`HgToPsrgmv#oW-(NUxO@5h6(IzFhgMSamAwhI0^0rS*UlT<@MGP#G+Aa zn52xS4WVrfp3|ntEckO+wM*PvoV07U4#I(uiZ;7_)(Z-WYw?;srwP8daSKX1(b=)c ztKY~eB($V4>e_{C@Rd=&*;9I2m&@E>GlNmle`$^1N8N<&m9mL2`QB&of&F2>wIU$| zr>R^kGZE_)Eoa^0!*s?L2G+P{ed|~xug1%eK=(S*!D0fP!wzKGU35xbG-9@k+cy?E zAD*G)ecFv~c1qMTYt}wlksUSq8KU)RKI6x-8YQ%l8CDY}*1%y;Mr>P96TbgTP4H!~ zPANlcyrXkR=}veMlIbJY9evZ3mgq!iM9sMCr8a5Koy z3sv7TcuWjZ0OwW9z+O4@E*jpp%c}iq+r4#lz?lJf3g8{`wMeO{!7T77PJQ@Nu$qos z&VP^^p8oF?y1xTF_kDzyF7FQCs%ZQQer}2lEci?a_~NcukmsL_Q}8X+S3kcTfG`uH<0gjS&uZ@gj(g-yhU-L$&rzU-Zu zOIraP;S;A!%H!G2-h4%N&>Dxy}Oi)SfZiP1dzPL*okmtky4|zVS>n+2ijakS@U<4g>{&JNBR2$)08-{Ng+c^ z7B#ks=Ubt$duQ+m0;Lz9=;UDC;fpOCD3!JARfu1ZonnJgrUFB}_%P*0xi{Tl1~6Hz zm};UqCf*-?&xUFj3+$}kn;mcSxy-5li3xc_pcv@7HFh+Utvg3Q^HuOU12DQhIsO@~IAegn@XX@T4Tb3_5naDuI zB4Knz%X<>ft4Nxoa7f)7pz}sr_NQrz_dXv+>|+b?@{@)Hh?NH?Nb`S55+%0_TiLT{ZhDgOPPR7{xhAu)bz} zCBs}FmN5Me_C;Gzs1dRe+DiB|fe3*}ljIX~{oV!eG+eN~MGQ5QK$G9>lcyPb+{-Z4 z_T-R-Vj}&5Yu`@gM9;_Pdv&&Zj`cbK*^|YgWc-oQZUY;cNZPruShbMun)erVL4FBG zAL3;5L!Eip6lYv2n*L3eNDX+VXZ>FtU&b|d zAvY4}rQi%3Z;zB%aq}eydwk<-oNEfNm=_$t#&!oP8lzhJtaW&@&-$J01*^eDC3v#W z&zH{g3B;oten+fcaIe{TV-5xuZdM%=UlsowlM0UXT&qP>Qi94k;h%h%J@ow$2#NOz zbGlv(h_wwDMS-fZ_2xlMt4$9XWZdjB`c{L?YO5s6Y?IL@Q{nL?AnG@fPp^Udp>i1) z=#xu|jMLgyH6oAQ*E9OhaH|yk1TVMA6TGCn?rm-*(SPhMa+^x{vdswgTghG8a8Nom z^`3Lg36j@JU2bYFF{!tF#vx&EG{wM~%C_jUD}G>eK>hN_c%{bVaCmD(loBi6TIH~- z?&cfL7$GZ>1c8%?{?0JbBIAcj@@DRxM5=_XU7z>Lav(Cr3-=ow&=Qj0(c{ZYysM!% zdAu6G)SqfL;A-^qdtn7r%I)Nbh&3McJ_LkzMCu47q!@%Q76%*xNo`jcPew7F*V5n%0s$A+mFDkWR1f%5cQ~bhFNQ z%ja;{p0$3Sf%?bNCI17~ZHEXsozqorB`ZuQtLmkt*@oZnNbVDS5^5`6%Ln=q*wc}y zu(`pzcjlSdlEJaJR{SBLac$tpobE)=z$VjznhWRTK>oPS^0$4W@8DcMK`5)R*=^o% zj@fz929(RBy<75aXY|juZ1Evv*;kAJ=>#jMadPDOwOk&*>#u`yGdEEC7Wx4V3FiYs zsZ{_#2-lFiuT$FcFuEcD)*eWlENSy8$spXU5#H-GWy+hDg^@cXv_R|a8Za{Q8D8s0 znB-NWuUMN*B@*JR>>+)fe;DS5T~z0UFL%vk$%RqrR+B&Oh>zVNHTuRxxwm3e(QD*T za%7W)N%T-rL+PhvIT!1~4L0mhPS5Rug866ZXnBp3T&NeGmlRuT_Gm520cU9rJA_GM zZEo8*kZ9d%M#{38Yq`gDHAO(&J@({y)>MgD&~U1Q4Uiv|PSqjxvh!{-9{af=d(01< zrEl6;y^1gK802Ho?U&BO2qZZRx0%!*E90=g@9#=edRXKS`az8!fAoXerV?>Q^H?{= zDPsXVcp9LOqW;V@J6b`FQGDh4R|dv#7Sd+}(cd$pa3P7~Hb{c|qwULtjC(}ylfB(F>@{(=haM1uMFh{2Z`tr&@rEdF+tM=8|_EyH7l77805kW3jq3I{$u6l`Tb zT5H|6*R6}bOIU}5DAh)M>kH+iZ^`uFc3eo%~`2!*a_o@RLrn$VUPgU7CWUa6Ifk5E$P-Z)r2zuJ9M)&il^F8 z5|iBmFPV#W5oLSHw-aChKyM`DuDZ zd-rMkH$P%eGZIhg{t}cmSP5C=bJawY`Zr3@Iu+BbCXnT!sr|E_>AF``o-j5rQSZK5 zB1+~1y7&aKqNm~VGaAua;IVHCqq#QLSF$JWy!E;nerR#Lod5J}*M4>k(_V;ssK0LR z&S6-*ONp34ib|9+%dH}heQ@>2Q)w}Hz;1^deB-EX&=3?Nkay{S^ z72cP#yR9d}R(z07k~hHS5la7_@4bGF-*lQ(&*kiq0Z!YzI?G5CHM-~{WoAuUea!bR zvfQAa7&*f0iN2;(8~+uQy!#7EdS8nMC(hv1liHpVm(sS+XRWw}Kq9(^f~)@GC_Xs? zRGFqm!SZ{@U)!Nq972qeKbVkNTq&V%l45|=4kn6KC}+G1YQ6s?zG@sH$!op9zr3NG_OcVu0p(;t zF(1N&(-?JZT`&8`r&~8)g7ogZke9Q`&EA|p1b%IWDHvfFPed*IiZ!L8wrz2-*54(Uf0kDrs`%;w8{s?o z_uTlSg?`n33>hoTMb}fiBVhEg(~%^gm7H8xAddJSu0>eBK>GAboX>++*St-Px5P%8 zbSd`Cc`8?a<@FGT1Ol^f)=fdtc1a1r}PG>Bh^kvw!_S46e zSMFToAkkpv?6gP=gu0zrxg2eesqF?Jz@P~$4urY3h=yXMp$4eA4}O1I@pAw9)4HQP z1^cvo%h?4MV4s!<+7I$Xm=izs|MF?Y^ID<2Prk23YE*V~5uo1`!6;&^a$A^RA5-8c z0kp2G@YYqNCo22#go$zE1FW_Wh4u(E?-6j>z%;Fd5v@TlS1t!bBs|ruKCd=xyQ?#N z1y0txd;7%N(5}~mFG~`eG=v-8s+39)xgrxqWj8-T{9u>bPw)OZS(Z3GcR%;OyG`Q@ zyFSdzcV{`umpDbblpwm5GnGU_w#%G-P3cENozSPPxN#h~kit5B((}_f{U}dP-t&Dw z+s>C^^a`owrOK)IUWOYrIRD@8eb(@lz>WVr`FYpK>JxsSUZoYBu&aFawT zWXJu8%`M3ulUvx$i%BEZ%Sw+n&hnG31Qo0LpH{4@$;@$Fi0*wGG?Ikxjq?!2C~p^h z!V8^~tV7fKFydnGFrfuP^0>$PrfK8P*Fv7g53|aKVXco@S%~>Y{`AYvnSOD|vh{`F z<6JGT_2pd(K!g>yh|!Ph)>Kp<3;_e571v49fO&f4=PBE9b29S|;}5NHBhlS(=c{67 z_;wZC`*jM;@c1MEFJ^X6M`n3|k?0K}3<=l#FC;9!x)te#8z2=jEEA%NS-rT)Z}3fY z=84Srux@<`G$(+C?XIwJSm_kL>J>^-{f&|Y*ubgB9oV}ev)GD7A) z|1iUzwK2+St-}-Xb*#U1Sy@apbnMCXNKHKaLde69D|+nd;;fh0jJ{A@=U_8x(_2G* zC~|~$c7DM>yJj=o)FWt(yqr9YH*P(E)Sy{`Hf%F|&kl)bDcSJ_&C%jkq8$dH-+Z*| z^+i(OT7?{TWy|xMJ#ihJO7WyJs8uMO4PV$~ZToa2+8tMfJ;0biE#_w29>B3$;6OXQ z!nhxxs_;{_)6Jyka`sJxGdgb?vQUM2xJlOPK<$GS2j;raM$kuT-A^=scbL;CuzNwG zA5|B1{z1Bv2}Y+-tQbowX;IgJH0b$H(_lT@5ZLV6dhscHpH(<7jFC9*oU!g6&Gc5V zDvgWi$n*Vi^B~;%YG7-s4-@I86wvP?zCvW9L zpxz+;y?PUVU&wSuVJqI=SuR8lyGi$gl-1(oSnL2Uvu(653zu-C^2FQ}_?fkdS)nr?706=Lmq4J}U=p`i9b5J7(Uu+9}? zj~Xm7Nom=6KKiUmE=w-chgs0FjB?&?MBlO6M0SiVhMH&3#@lOXb5#x$-fTHxfddq1 zgxy+H&MbSJKNk)pWW)-?tHzRsbh4N`nkz01fG#qZl}J1m!!5#GPJS9hs)>q%n2sPA zyBoimfMzAUJJeV2)y|_dC-d0rs5`vrb>tnDq}kX;mu=171v5;%DPbYg)7b^?xt;t) zYE*&sS!&zuPj1bTBckYdLOW7QzWid{uKSj2WO?_a6|!62=gqSVg{&S&FS&*t$D?yU zXG0Mxl)a$eWeQVMg|*}S16_f)DqL3Xi(syPQhLNE-}C5c74bZATzFP~wZv;a>815< zmeDzqW+Jljl}yzk8KwIV%f4d%z(R}NE0jVeBL850-gT>Q`ZSjFLhEE@WZG!w0$EY$ zbf%v+16)_sU+5ijgO=)k&GFAxE!DepabY;yUy3I5x-e8rOAZ1(*#m==w2@df(4B99 zzQF2N;ndL9h)XYwN_Ena61Xz4BE7ug^<<)QsKA^fqs(};z#_aWBRt|Qe+)jO`PY9d z0^Z~mS~=RBrqOctb=-;|#{z7FC;BPPzUc~H8BxFKgQ1%P2TM=v0d_0A!fw^^Y&s=C z+(Ex3u0!}s7)%KZ>KAK^R-}UWV04vWVUQu}UHxALbZ%++Sqc{7*5)-gwPBYzduyJ6lF;~88l4auagcxLkJSR z=;W4X^)3yoLrpGz8sE7^BEv{s%e^j;!fjc4>|fF;Xop3U`zmbx6gp{ayIFkFVkfSQkGv{>)SBVmgpkxo@MNH-#;b+t4vOlTfjDVlwO4xWB~ZOzd0J< zdqp_y8=s;nUHphm-E^~+vQ6Y`8pxbZ*pDFYU`wppqTXMQ&8;H`#V^UU;xGMNc4NQD zVlWoG{r7j(#3_%;(g6&T;2#Xqqy#~~0}(KSo~08*k%tx7N7niq7~0_c=TiFc?Ks%P6z>Q$MtH-XUfsK}F2i@t z5RmX$O;^IN1i`c!i4e;B>>foqTK$fJ95h#{JmC{-biqSQWEU;9JwHa}dOmyQ6^A^T zq*yG)JYWn@exVQrmwj^eh|x>^%m4+f)bj@gT-EoQN4JgWcDVqTiH%SLXH8OGg1EgHXL{?z;*d$x`&_*f}&o5 z`$%Jm`;`{l`CAJfv>OASL>Sd`R}K&CC!%>&kSSE8VJP*B>UrgiSGi%kqe!-KJv)T7 z!X;Amoh7^#8YK7#ZqcLV7!8c^>5+iVGlG`P?lsOc;yCa+Ia;qQ>mRa4~QDHM1dDc)E^T3ex!o{zRLcMMB0czbs6x5o(H9+z{Nv zJN2{wmDwj})BeTmhpdS|hxe=>T8ZR3x2}5D$F@ykk)DT4FK#!?!8u%3PC;OCX;85u zltV1N>JGFmCvo)1z4We&yc|cmXS7Gq?8teC@R925g<$9bwTH&x5g2sQKWy-lmHX;I zrI@xl^s&$+X9pz9LZS~!sH4jQkjCFy&|3DR}a9PXBq(FK9+iu7&C z*xQ86LLr@g>cD9cgN3ZdCrB{T0E$*l_7wEf(+(J6hRV8tJZ`R$*kDNc(S8KBJX|BZ z{VFyI_!WS`+PIhDp-BX1QB^Zk+vZ@gk^28FHbQLizhkp1ZVro0<&U%w;2(%B(hi+1 z-vc~*`0N`Wtg45>T6N}ba&Y7-!l?}p(1wnVj{}(A7=0!H7B7cDjIkdD^wh1LqXC4OZC;z^Y+Ha46P{$sEwk21pTB(041Jx)mbezIuiTXXq?jr3F>jk- zA{LEg&OS!s5y^vcM56*yy`q%pHd7n3PDgkAa{JV9%eaJyCTrHutUR~m)$RN+tU|wy z#jBUJvIEmY`G8z@-uo1XH_zS^d?CX5a{465$9%HBLrrLBGcG>6sUELRyhxfFwYYX3 zfpoA+wa>LB2-0?v^u1>3l9dKRyDE5%5+V3aghI!H6v8aVd6ShcG?~ zRIXD9g-aqg!>;UZr1a(!Koa46bo$P`4z?XHTRc}*6=raMb6xG;{BR`3+!8tKkKs{_ z3W~2d8>FhY3j*iTR3dl<)o5{X0*V%Pe+poJmr+`DYc{sT_znhK$%tmIM3A!IB8Y%a z4m>s56HSj8aOX1!63;&i z(xcNSzCL-~!xXIpc)=Jhy_d7xqHH}{X zhXOmmNMbOIWCbwNDZofWJ%>7m@W({2bxKe^RKn~bNt6E(di9vTTs@{z{0acw&}O&WBCjQFx@72?I0>);LBRI>3{_h0usn`1n>IHj5EinMqN zOrI@`a_TR=_G_+cG_vc0F(^fJ+S)uR1)^`PCdJTfiZsXvpWuGd1Wi?8<2Kj4R59$ zrRQfh+qtm^uS)W*U2e3CoISVI#lb>#!TL-y^rAU4to7*a<)WXU@JxZ3(NAb>Zl4lw z)2WH?(i;6%Pi)mU!9;WF$8lVE)3LiUhQge4UYvBqqXd9IzU``MiNg0BNRZ6}|EO?z z7ufKU=FCgI^AZvw0Oj-<7p~47LQ%ifz%@N@bn3)N!Sd<@j2xKw$ZEH-2HXS{nU_gM zn=wx)3hAD^2|hO4w)3ei7lZpu)UJFcBuvVp0OsnxE@#iYg1Kmed3PgW>H)^zs0Twf zB`_}^|MDi5?`ehKejMK`NAjQh+O-Fa8s{5$TU+n#!SP_K)5K6}di~pSP|zvbUvbFE z)2v2th3VUGh3So*G4MjeH3bWpzBEc)V%PTSMID?#R>7y_QOcb0U`n_)u3Ry7T=Br;`0B3i_P8x|R5P34C}-@jN8c2^FNkSNPy|7SF8< z^T$5`gR#3`hTmN%4 z(q1FXyEDeC$J@fjL!i3H;yUOJuc_leq^SOS=V4zg22}Xo*m6|d%MWiV??|R8`7ne~v~(>f?ozvrln@>^xAe|> zr(ZC9%N=fmp+1GIJZ@Eh$s}L3=M7oZz0X~0C4?q_ofc(jyeQ(5+NLcc)!WRBR>K@z zii9z$|Kbw-KWKoYhlOa!Lju_cemA6{gtm!1`yTh!S{Px0pFFHePnqa#NscaRu;ZFM z?E5yE+a@oB@r4L^h%DX7SGi+Dr9Ve|#zM8CW})VRK{VAwQ~aeSQpe?LYT(iP&>2(( zQM;;s9q287#EUB3>Eh~xePAP49q{PIJXFaK0U|P*RRvDP0#~Pj4{UE0@t0b-ExDIP zxe>g0Dj(|$;&Ao!4iX=&g$LsvnfP!8x#GV$4dsiOsqZ*8O;gRi+dX+`zR3NVAn)M* z`dq(^+NYa+@B6qQ09Xjr!tI8N(BV?J#dPU6tQf5>1A{c8eD69n*RBE$nGa;We+2{W z@G1FV@0(JAYzqFqTNS>|z}`0@#T!N?US%*Y=PUmiy4r>3K^FnS$>j1e%q)AmMTgaZ-vcz-2JCKDT6JQC%npcG!N~l$GMZUTd9;mcVT1ic| z-5*%z>W$?IcFhTRX6$o?D`28;YTuJqzJGHP#VuG=?`mm4V}7i7<=a?dSj^~m*g%Y+ zOEr?HsfGTLD=bpm!<(b>Q!rRqi~ip@a|Zp2iC#Wm(M#)_<(8#-bTf%_6dy0pm-TjT z7idLp(`bE>i%Hdhyx-feTYG92Nvc9&{kr;rd zuJ{b~dkuUx(fGZ>g)|AaKSGJZbvT(y%biiR4N~%|jbGH3092v1G-IzaZ(8wPcD^O` zKTv|*TSJO~5H!h(FK)PmgZQwI2Qy&VpTx)i-P+m>Erd-r3u0E9&`qDu$t<5u2o5=E zI*GO6KMzPxdk+X@j4MJ}z4UuO$rTUt-%`FMyi9JHqlID@1&ODM>G&|VCm{e22Sye;rLFMY%k}u#8c&>-UY4ZlzI+pk zpHe+Qa&veUjXh z^H!Ua7Cqz%X~R65qb4K!S$6*3FK8|*EtV%(wf8Xdf=90~N=wKx+c?lak)snDZvrJ? zkLAY}^?c`mnBV6IbjoDpVp*`vdFKw>xQ0?_v?Z@S3ZX?|sGcJ_#Vftidj*o0(5S68w5Y4AUx}W_ocW>h0LQFH5_56_RP=SJt zLtW$M!Xdnt7&aH9e26l#Z_#v7H*b=wpB$PLYc2@$MZBg1VA3ZVDBRy5&}InKqb)k0 zfb#;S*0-_KZKP{nEj`&8SY;Rfu*%wD%Rd@W)43%PPYau!Sl(5=KyF+z* z><7vVROH15n6i^bb5{$o5ggyuxHx7uo@S%NS)aI3RQHSq>d@mzU<>fQ#JkTA?U2Af zIt=T{Vv7U)mr1)UkLoRcJu`o+pDZt$Ys;=$TS-`JJJhP)2>5`+B#&l|uQ!+1rWtxS=_AK4#M za8yNgFhrTD)G8t>F%V&azo)J{g)-b@6%)f4`xH@zFbYfdnK8dI41z=w7@{#xA}y+n zZD?avx<{CRfjD{HG&eM6!9$%%vCJ7sZQG6Bwk=vGAM9Rg{2w#BO%z)r@!2RNZ7E7k z>a(x7Pu(tkNU3Gc0vazUs9k>GdVQj92ofy@-iapA(Y(5aTqD-IS(qxbAVoxe4(eWv zz$vZEG$7bMnC%*TpC=+(bGfw{j=`?@(|9}Ydv7ghYwi9~TkE4TV-AY?cS*ShZ|)1| z_Pbcww=O-+9XM-<%Wh$tLCHdkt;{%(2K=+b7O}PwhOWqUkb`8QZVH-sFy&3hw0wwb zFtqDV0DRI}<0ce%-16=Ncdg%e?%EPdk83t;>7U;xzGWEl&;DQOF|*>L)(Y9{V(O-; znC`s_dp<62O?thb(kTdQ{b#yXr7Snj$JIyJ}&b1Ayr{7;_N*vw&zehh|CLHszLQioR59%N^rmS%r}or2_buF!bxg-v1eOcZLZPQb0>W>&g$Cg0jo~MWfkUXN2nEA zF{|afm|iD|_k_rFV1-wztL|PIX-LJ#&rH`)DINE0Q zL5bL#ud2(CL@@AZ0Td6?KXYq5+6RK>km{u;$pKZJ?iM4xoJb?xx8TOZJ(%%OjT*#whqu-F4= zSS?0U*D2#)7kzdr=8etfLD{Z&W&_$#9+Be34?R?TzTl1z1dPJtOx0RPhQAnE<=xuZ zL*@7i=$^d8hWW0cx1<-Z(bzmWu~~pLk&^JoIO_k!Avj(I4q%(INzi@)Kz~7ap8q)d zn`y?$a=J~k>cR|DqCzC|t2S>D!74vmymQp`2D#eTc32Y)+$Ky3bLZQVG&biuK?hjj zgy0kj)@BNal3gYyabGpRi2nqp2%okze(n$N~1qxPxLNgDI)CH=V<0<6zziDNLAq zhFUQ(q%JJFT6(E;-q1ONy9=!JZz0$BE13rK zh26`7Rd68vf(1AEjB{eLTq5z&^Pfmf5lvJB;*pg|hVzFax6+C;XGgnte2jU2^^Llt zZvrLayZf>hN2C$Arj5=9gUR2PwLJ{E1Afbp*>O0h@3DZ5E9`Ojspr%$sVDal?`^F2 z{_V@WQDralaqIMzoV(QG>P}@52UxwKD^xOFF!6Z-3|8ohM<0-r;1SXk`R}MF>{}`ecA(O%fJoJ++!e(mI$m>P~#pb+_M_}SyB7PM-^v_rs zq=L7NK*crm4?&C;aQu3?fh|p0XH?>}7Nb5pT$_y!+NBF-ju$S)fzo9{JA>M`W07r` z#_NI-3%i{%W-$D?GKGk?zkySGxQW5aXC7xN02Gz2SI%5Ra;nR%1?!5{#l@#Hnh9Zn3D&a8mQ*d?9mX(rCr$1kORi18`rWMDz7iGYiyqHlDVHX7Q4*# z@0!l94jK@cj%3mAP3MM~%uf5iWRB9m-mQWs%t>KgV?>_P+~q}t#;lKd?5vAC^leOT z_VoaDo~gsTLzlJz#mPdR5w|b$u`wIW2pnwlho3XOT&D%qtgg}G%K`zfA2P^8gj*z! zOvLs0GAU>^MfeKtJo-;?hq*o4Jf($e9^W&a+$|fNRx6yg#%dOpY9v5OxlO}~>5hMk zFy9}M8>JKxgf%09AM4mkI;R9^&AZbdwwW(pE#e3?$I50KN z%NxLo_0Au~+A!gIR6m_E=NcyX3VufXqvzhVu8j@miTy?GHQ)Jucdo zamSfWYtwH+4-yGruOmp^qH*^)lgTW_@(LZTQ%e-EFzO8txhw~(O*SSf3F9);&ZE2< zu#)zunU4AvKE}2eR%>Rtyw-;ZAGi$K3AU1@pL`&89@}NmIJepV( z4Rg9c@N^VkOkdCYF4iV!#@s1zzepEs<0ACxm2~7Fzrs;qH1XeY)Z)T>E+qppPs~Oc z+=c^Qzu&9~a2+5iMTEtmh`hay_4q6KCtd}K+!`|Y>Iqh5mjEY}Y2blR!+G^2-@lpqyar{hjS2KU`%bpM<_-}rqq7_FvJ+09f(q|~ zW$La+q;lVR6bJ2KZC!XL`{Q9y`PO#^5pwr$^IZcZE@5Y}c&c>+xh)-b%sksc#wW1W zoAaNw-uNCCZDK_9!-Z?awm)t)f;wZ#Vr3h+q#Ckao~y2>j{-9TInOViW=ijGo0Fh1 zCvlw}KfpT@I6JsRi$=O8I7hQJecE;0Jl(k)mW&c_RVD)Rn%C^1x?;hbLSp10i(+>F z^7mQHZzS2a@Z6VrNGu33qp7W{r^8B&cQamYq_b1B=0WQ_tci*xeB#u+FQLP6nU)b6 zzPR<5(xs7y6icHP8~9MSXO5N);UZb@u%p|us!OmTq=8dB>N~k!-2vH*bvAlmWKr9% zac4a&d^y)E>O^N*El!|pUaw1GJBz&4o%f^nTgIy`KL7H!=A5u*uKJ1>-q*_ss`^)E zI1AAdndnJ3Ni;a(7q-=fm<*B2y*XgT{iRsgT}TQX?D-H#5)rO^pCiJ|O9IeR<`lY8 zQ>x>TWFM?UdOt#=H898qTJ(>k;jyZ~xrG=uDafqRdimb9_ra#^{Eh2~Ifmh}NG@8< z+<3tV?&U$39Ib*=IWAxCq+IBxo$UKk@!3=$?u}(4uM3m}9gZgQO|xsUP;DG_ zDZ1CqV5?61%1kd@Y-M0o>66!dlDY%u4`YS=USP}Ty#5>0A(4m0cdq0i z9kVM-CVDnfmKByFrG+ZpXk>1-wJS8vTYxf-a02>@Ma=Nl} zbq?D{!KTE09RVox-Jx{fn> zH%G*82^IGm*1tG@h@=gN7+m3~blKNj)4{3PYKq!euzwSZMZuanX*tofH^ca>`E!$ zv&M$ojE&jg?RFu>O|S!a$ldlUS#-yvD)-y&#N0u92hX;u8gtbFK%VjUtaaSMQJav6 zAD+`YX^Qr`zZEc!mIwYVax#)C2Nrz8mQU;J<5 zWy)Zc2w9GcMEVV5-zE8!wsyz%m7goAF}tl{qRnNB>QVjb?xkR1+KY-x<-mYc4yEl6 zH+r3+HT07n3mh8GQ~us)sg397YA&8TLK?s{T;ln$eY*FBb}JLDlix=DK!@i}5`yD2 zy<+P_8{vyQkb_khTHk+kJ#&|%=N?+KVf6tk3#hZL-RmuCi=Td0_$rO8$89XAmcC%zhaCED5#={X6|kKL1m z#Ts~gLz+`9Q#jI-=i&cuknwae0QaLIRl^orqW!)(x6eXS^Q2WeKu`AkH>V>0Cr(8{ z46NqLe;y_`Ef$F0%J#ZiD`Pymk@Z`H2go>iz_=D|GN$9FH|b9A9+zQ#PHlNA~jh2Ht6tITW@r{b!Y zg<~`@LsB1MdJev&$rPY5l;4=^rE@67n!O3r6`2p;O!{6gT)wN|t=l+Ov$fA}@pNvU z{praX_FS{w$Jv42hB>}wQO~1p0pvLrC}F-ZUIX&5d$JI!U%aK+ElchIeOfA0c7p#7&oUUS)Qqdj|wh4>8Iw!0U2 zdgr-V#VSw|1b*|;wExOSYtf5=Rj_IwVOyCB_i-SwL0cl>4@Q|_X#-PLmK=D3U)})b zV=+TO4!wUPz=0n21|0~xn}Tbk$G?EZq$+gE?^Ek}IQg)UBO8zmEo|HtC7t z^>1HRi>@Ttfv1+Ei^_JOkaU0Yls@<}PQZqR%@a`;~6QdZRV?$*wjk|${dHE zey)h-Rgy%M?1s>=9+y!Ix3K3)Z26HSX3)T4iedJ@!xS~?in$)q71)3MFhQ992(trr zxAm6%N#N^w0iDh(5`!h}uXNSCK^sBNb0KFTn@=%^gkQkvuuhhBBPWVQ5F3x^Qi0mk z_Nq{ip$+FpMB;FCqQxf$rcl*BHb(-tE$vq{eZK}3*34JTozLBXs`D9*`GV?m-;}Z4 zX8=`k@-kG(9NDYD4myw)GxEL=Em%kcbwJ%aOg>bb%X~mSu2mH;VKq^rT(9J4t?LrC z_wgNtTUaQ$&Eg|$@vRl@?t z59&{^X-9s8_?}o}TWM82TJPBDZS?s%O?#mS+%2w-?Ezr%1`R%^6T_aySaX^t@09>9 zFS1zPB4(VWAEA3^wgw5Tvr;PGi5~Mgb@1!*5~d6PE@}UG^3nY5b}_MTpM1)N>To^Q z)#6W9PX^}4(|uOIZrh)Q6}^B0<2y#*L&_W!x2%Bav3jeE_A<(aaL#Y&!o6rR!!$EggieI|H0)rgCttiuf z;*Yry!Gf~_a~d#>7Z~&#VsPOSy8Y8%# zh?3|8AfKGF7U#hns=0NvF-u8!FC<{#~SIQ4WdUYX#xz^bapq4Zl)|XsfF6kx+?w;UaZ=yS1 z5*LkMPN3`M9dUe0Gkk{rqW3D4B+Ro|d~UUKQj66Gj%axT)YUc6r|J!F^MQPI8W&*>Uje|+@>gqD zK+vF=nxc*7D)in-?dyg#KfC~6`d@n6yv$#=gXZ1=lP5%KzQR3VzhQ~WK}5*pK>;w3 zWLz0YvYnx$usLjI`zt@KvN!BF=Xh(TAxL_q0b%*MFq96^1a^gw;xs&9T7Lwr)AO(& z6M|0HO#+@%CWSYI=#ydOIG8F~VNrT3ABrcM=Qc8I3!MqYqh9fk$WG$Fmeo)ho(w5~ zBqIG9qoIuB)#Y!xm|#ivkxq7HseX=U3gveS(@GlZQ{4nyUL~HH|~dXH>8|Tn&qvW_g|(YR>W%EJ{Pb7 zm~Ko=mry=211@ep7o9kgLPThd8YP=}VlL}F_ zI`vW{m;O;upH>oiDql7k4hzc7!fhk-h#Th&n`%M%zmr^4SIcSkpUaaazNg77Sd{=4 zT@0>Z&(`va(isji{@BVL>E@ulDown&KXD+VBZML3PRFL|c3-(U-txf4uTVrq`N2HG zj}DXicX)TAZsmfGaKmHrkxCF6wYosN-JHU3+QoC{oW%9&gGe;ybb40x@Z_JS-TLhjUy-^_xooTU+BLe=2hvwS=|lDd1{OJlUFXXR&=i zH_}%?k{~q-?cQkWa3U&ReFC$Cw3fEIqR~Am)I$!S^2(m49sRjkh484J+!Wr(={?aG z&i9y*fAv1s)yX1pRFX%r{%jQ~hHKv==0|K^pHAkbN=Nogm&)_27JbLv3~VbMK?xDE z-hZTSm&^VAD+h>yIJ&c|0@!sElN7D?@E`>!Pv_I^A#@d{vv!e2lq8$htgDJ%BXR1% z7RfwH24OYO>h;DI3C|(36s!vDSPgPBtI#L-(FlLdUOruMK6y#gWfzS!Io71G1a_N9 zy=tvGR~t4$;P~OsXjVgYdNO!9)ET)f{Z0ZHag+-7_@;j!)O=$*viOe_=I(N1>Qi9B z>5bR${Y49iJfP&u2FZ_xP@TE8pKP>>=hMtQRKQP;jbFJ`WJQ~Fk&1xvHK zWFQfo0C(7!O}|lwILZfdmsqy;^0h)Cf*}m(4Vw_;u}x}0!fzL&QQk<%-oy~dUP0{%9HHm>mjS<=zeMMe`H|~ z7RjLeWpYi#OUE5~=zfWl=L7qmV^yBz6dfOcVtMHv=qqccb71MLMybQ<%Y~<_7T7FHfkCTEPj|cHS|1qsM?Yp0neRwWL?yYLGrLq- zNZj-sFx5k5`jw%0hq?l-G2*gM_BIjDoz^gXg;a^+^5=`eNMh4#lI143>GTUY#39y+ zUmzgtea>`6|2mvFffS{VE`MKd7en1Hmiv9~Q&w|DwhB z!szje(2i&X8gWeQ7Hu{em_)0RUHtz@`wF)%*Jf);r3Iu#6a)k$q@^W98tFzrLK^87 zkQR{clm_{cf;0#s-6h@K-QWG-_Pl%Vckk6NtQC^LV&x(0vCBpJB-Cw+ zm6hNsxE^1!X7H=w z)WVlz3@k^3D8X7FJ^b;Gp(oQeP?*rIym}g7vH-)(I4)PX=}%WpjA|~kT2V^B@&tPi zY|u8=<{CArtSD(Vi?qlpv_gB>*nAgdP(14H*&47z&(%RKT+=_kSB!uRtpo3sX)W|# zSwQcVs_MVIS4+Nh69OVObqk`sjc%<`>41O>GSb%1$j;$}tQ@KT!HTVFS3w8tE<7*< zS1c2Y%2qy@iUR4Ux#ilaJ{tu{RXhFQDSQm0g@|Ys}<01Q`rSy|3#lv{}-A0OgvUE?0`kFB3WHMu2<&8{9 zS28NcOj=guB5k|vB4^dOU)o)t?qP5Q#{(nlCNVNg}>alU6<}w*zxPMr=#d$VmlPX=Nb6rpVH9lSvUDxpu>TT4@ ziTEQviu2jADo}i={vkfx766B5Yy|^g{=R$Ur;XAV3g{8r_~Q|C{>vja_C!`kokc?d z=y7paTyh$V;UPoKqFh5(W!_^WaEvw&s^=fr>3%*3^_=*#o}OgCrcsL8GEsIZuu=Yb z8x36Li0TGT`9SvmdJyc75jrouSRU75sg|q;hmvNfr?9~O2}6;RWJN|jlHsARp6@~a zje|b`ah`71x!{!>%a$e@9_#+KFGgT)G-VaVu~D4|==*<{m+fBno#BqrK%L!z6Q-T! zukS)G@?1unl}FqA6n|BD)7nE&<(2U@V*N@KKa~~5!1ZaM%YBXVUqb4HfdY@C(m|qb z(k)~j(U+W{JWPbCuf2-{W2&`TW_Cl4f#alNSS2tkB)14YZ*?z@l%U3IE)ga9=S7r;dr`vg8>VCI^_hRlb8ioR{RssT} zW5_8u7-p4uJgf2oRuamI{1o_*<4Wu>fQ5P;Z6a1NmqSC1X8q)+b`Szx@Knin^SAO2Z2@`){^Ef z`Z_qIr81E|!z zF`_Nfw_l(wFun7)u-ILPrRLwl0t3?24iFZ*>#%e~VJZICuwX`4UWX+(&HJL4{&!f! zqiGcL1Ic3X@prpu{hxO6b<`JtLcXk4m=b0m zzZlqg(yS000R{=_eUY3)W-j|+`Ysb!Vsn2d^G5_O&|b9-aQOFbF@W3j4v_VglyJ@u zeUj`CFBAu4s(R!F7)(YQxEn35EVQZKQzpBhfYTAUU4(2Yx~|YZ_;UMq0;*h8#od|_ zYXQTG(_&XR8QeW>VDa-FxBJ}iZSuT1M%{<`s>rmk8j}Z-Li~_K$&-*Eb-1 z*^~ahhR9o0CLM8Z-igI@aey`BO|$o^ZQw}fWNGT5Zmuplfqys%P^!}?=*MBVr2Od4 zLh~w$Up8JlvPe?=;mFbl6&kLy`(1x7G&yPm+AcR2ONfWH04GwhRy(&08W$D>?;%>k^hbl*9O>TI5mF{;`7u2Ol!e=z<@% zeZx((=x>gO=ssXQag{N0a_3<#31dplsI zph^6t)Z@XJ%s-MyxaM&iX}#zf#{Rt>aF0n8=p5{N^54t}pFpimJB;C-fB2%)lzKAt zP-4;#ky&s>M>5fP6g0(*SW=VRzy{IO=E+~5wo-uABD?PSS%Yn7HP-ElwkN@8_PO{6 z1XCU-`QOWi!59ky13xV)Wy626L4=Db{l5?{8*_cvMdy%4ZG@md3>pkzZ{+0&E5<@v zW#<2OVKTn~A!lk(2?({3juOIe1Hn=)oW^%0$|DU`u}F@y+%a(b2(q|QdCA2Mp0vmo zec**GN*)3e6b?triIRIp^$6X1qR9}nmT$#CYsor}m}mnHX{7lh?;dQn0gUl!GE-8J z`=tn?K|YYa(2Tz7Uu*1I1@^dLgpSzn_bz1VZ14oDeqd$mrjy3u+Qm#Ef-~YUXUtP) zl!PazC@Loh_IP{EB6g^ES@Lgw;IkGG`IgbH)QC;7<++fYk?`YNEgP+IjP5S|^8DyZ%Yi@H-au@8*9dxy{%8%d>VM@-E zTLCw8k^?w1@W6k;oDdd$?>vE-q)OUUZ1k~8v0%TwT_~Q2eY60jm(_`y$kC*xZ zke|9R{!$(N?N|$7skBD;dWhBb1egt6lLldi*>QY&53Urx z2peGHetnT(N}SvZzB}jJqT%0anba!-0#Tw|`k)u^tz3rZZ&TVgP>mwpXntx%Ax2N^ zps_&M;?1oXcpA7>@1ivKGag*36q>NV+X+CO*ais%>W2Oe)E!#Jl4SdBayZ|iU%#m+ zrq)+F=yw@X#x+CjfJtMdSmMEt3R~ch_VZ{*hls&2lQt?!8R+b zIBm8n+2r2=@P=1VYYuOXLEU{hc%O4;gb!~GIJy%{bDd!euqf`dJ@-KCTE}X^TvP2u zmy)NDJ`+7{mB&+^^q$1PgW*(tkz*bD6!jbK1%8f>90X}KfrIQsEswD}JbD&9M!VzC z2eun;^lM+;hQ@MnfOqRYj(sbxu2lcY^=&BUC@WVu%mcOAKg~ZN@@Pa+V{}>fnv%}^ z9kR}6P{=0!HDqA!D>`AHZ~}$wf(d#OJO1@aoKAZJ;c&Z0Y9nZEe>{nF85)Z6fdGeR z`~I)SbgwwUsU*?v>*_Uy_KQ=XYtKG5xLyyAfLt9u0#gAZf5_HhmI8ZDVgfhu2J|v= zP58eZZ-@rY;QHZubHLn8jq0PVWI@_nCnfO$>frf{N|+2Y77T5z&Ee{P(~hp-{KBB1Q2P(D_UUNF4fH zR@r7h;;|mm1#9=dz)B>KZZU&#-#j~FS1BNKKR-hspn;lMP$sBv60@$6ALHxB)K$yUcqq+&V7LpMN?-BCvF;RW+2bj* zbH!X+fxr1}1fFs0Y(7XStb@2P+N%DLF59L~3{_MPMxFe$7xj{~JT? zq+x?hn|2nIl;-W4@{9iIt(B8d!aD$)ah`Vn1vCEZ1l<2-DCJQX10%SsM52lwVo< z3N_Yy;1=5ckjrpVj&pO~Ii1X+tUE~)92Vn!WYyR{p=VehWG^Yfrt{?4op8bH71V;N zS%DGY<4HHG6}tnMz;=qgQj_;0SSx!{wpU|wMEs?B`A_vf$kfM0T1s|j^8PTe-B>6A z`@-~tJ24l?6MmL1oT5BBK5i#~gn@t5vJ-b-MY$K#Wh|kl0W4ta{G%04GAXG-US)tp zq_0*rWWVh6qrVvN5Z_Ak*M|AWUXY0w@N66}GAD+PN&KE&IZy5u{}pwSDhk6qdkIa$W+P0Vb~v zefru@h8@GfKH_^580TZF;&!lg@M>Sb8=mhc%%S&@B@nYi2V5Y}=>Sh$sv0x`ja`+| z^#{%z3K7}W_aD7fy$#F1BlRU`l<1FC6JGqo;w7W647bFmzr=kx3Sh;KRCr;X=|`UWj3})kfkrRFagn(4 zT=QGAt>)fiAz^XBN6c760pxNt8L!)J%f($Bacx<4Id@Git?O)9AD*2~PRST1*91{ii|U+qSnMdB^nX#L*eZKxrfwz|rhXt^ zhx4@5Vs$_Zi=oPrae3Gz9_Is_$xtINRvp3-@4obM`dv@M;2UZ0^X>JJSk*Fh4S%83 zZaPpvC)p|YOomGN_Fq%WZ;aN^ulJaj{5YBqh|B|I7ScAebLUhO*5Z>-D`ES~dKvTh zkGE;)1E^&+=RSDQvb=m~!!RgCo|-1uQNRy73_qtT$@Ldg3HoCl5IY*Pm+Nf9{P z^oi7vHaJh$;jY4~PE6yJcL1rnCJa9!j0Y@&z z#3x3hg<+Lh$Y?y`}?4Wkzn{(*22U%J|PaKD>-bU=q46G zEWu+vWo0~NaP`?(vYg0h}Y({_dTP*h;-a(C7T`)`8k(f{$(xf0hP) zhH)=59Hy1fMiZy3MJLGk+lLiMt-g7{wHu#@Z~x(8KyHwiPVLb|q|G}R z$~iTQTxu%q@ySZG{&pSrlqUgI$1Q2)AS6`q=cvHF9S+XYsl!k|nq-&G4tc$Y(hVs5 z7}(kKDDZwp*mNnq%y`_Nel;LkZ))=QzlbGjcM=b#T4ya5QiD=!vZT~g@p9tU1QHqn z3kx`br|7O-A0bnVl88)z!VxcP(U6}Mok+I|Zl9tUkO#akDA)~4k-n`9f(ZYNmd4Ngmx|7zA8_^_f~njjIG!HweUqBGm0M) zTZh9aXzQvB&UqSc-G6+`f++0E8#Pwb#CyHPDZ%wsIq}_XWGG-rh7F7ZUn`CH0pq~C z8=Uf18hGF4Qs7POWD$^nap0cb##6CgF}V}N27U7vy|!+SM0kvcRmIv5iWXE*zlxND z@A74^@(@_+6H{4GdHJn@^+=8~!_(;4C^fyC5!|)@zJmLaF&2(vMe4&6ejTl*FiT-+ zB_3G1qoe;+ugLx6i_ce&w(J}g^O^R>#QJrnQ8 z=GlGe%aLxkb}xPRW-8;geI3#8>2xj=J$D$%yZAqGPm6KRbPI*lVU>>`#CeK&z0yXx z-{?wsj&{%cRK3f{Gyvi^-3azU?g_HE9Xr*TYpSsb4Mz2RQT%qx%*AY_>1YXfBzGGO zJ5H{>qAp#?e0mS#^Ftkk zQX>_gdoN#rqefv-VgipJrFFLhWzpE+lJcFv8)<%u>up^uP&DC ziZ-%S3cd%&FJtl8b;0pVQSL5SRY5B%XOpO{ z^}IRoqF`P5h3V5MK{iY99g!*`5TGkOrQ-3{6Iq~)=@tXY$Gnsl^pT`Ay4~;6&O`tcXgDun1_#Y7=rZk+_h7rYg|g8x zn~54(<;EoO;p!wl*B1-olO*+`w``J0l{d89T=6B(UnMp9TcM)%l%~kuj`1*dt}u9! ztlOnO9PCvz$4575$p1s&PEMxg0;R|#=Z|VTptT-51|(oArV6@Xp73MUTHU#{doCN&b0gp`!n7 z9dMM$z&l6<93|=vX2EMwe8PiCTWD~TO%}qv{6k6McM=~)y5nms`rOf6ijID{qgzLJ zhKHjboLXpbLaVa3v?}aZijZrsiclt_fk#ud??YT@H&hww7?106a$Lgh_~U{u297Z! zvwyAy807Tt-@0QP%0NS^@?P5Fb~nA-AbY!pEwG(4eO4v5AzWYyTC7i*72^)!)TCob zUHq<$lQ#llVDsk2mq}JRH0`yc`fV{LyYr5*o2Po9@4^n49FlkSTdEq73i1oTLU96qPgb2NvD~SU96x zs`Pxjw1T1Pi)YfrPXT2+jJn1@YBxPYr_kRl%Y z9A2h;r_kHQlwJ}G0fd3Mu!+-}jwv9YTawI>_7dmY64se?|zYyDmBkbu$f$&vnoBJ|t;5p7(|5Z)+s8kqt)1^O(`v2T>(>eDw!@<;BIgP(RNts|Iahru z-1!KCIdO=O`ub+5nPhbkR&GBE6$c6W3dMzs14>XcmVD$PzzKQUh5z)&o-qPrJ1LP0 zZ|dNuX)GE}o3%45_0>mCdfMpOkfy`tfn~{ zABW4oI?m2UW{jub>P7*tyNYDU)}^AtzR{R}N;x0NF`{07C$EDATh<(fY@fSN## z!BE~O27)-Q@lQe2g;J7~ch0);d6+mLz<=t+5Ns+?u996L8k7(Z@$n+y9mbypMEyU@R-AR26ZN_?cIUmEs)-l(?_oj2_xwCGPC{!T?!I7k_6YndtsktyGYzr|3{ zA6_cepO$L5?ljtdj?Vjohg--kb0kC$Yeq;e>AY>Ang$1197!m~(m&0JU-M@U) zTcA}0Eh#GRQ`xg~U37&Py?h>ixBDnF5GW|uWtt$Y)4rKz>Re?qKh=XOTrL^f-EaTjN`l%-~aOnt;|!%{Bp4AqB+rgn*0ZhZ+C_&i-!$h7D$ z{GSW+U%pp2bqOxm-6aBN;q1X*omB^bPLDJ_sRG}1=MnX9okucIM>u!6w(QicxJZHQ zt;N55B*wO^vUV~NEAFoY-1Io!m_9xh*40VVIkq+Frj`4^u zK;vQ5_?(3UYCH_Y{7c7C6nckYp@5AHgi=!k3Eao|5J&r#4&CWs9NE13wC9J(H0oNk z#tAFW)ohlxx_{nR^J?-$J7c)4^h()XrhIqSI>mTBox&P-P8s&<` z8swrpXJ0>`gEqY|Y*@5a>$nZpj@~k-_XvgobEHfGA!#heHhOkGD`m$Mbl`{$HIx0? ze>9WE5ekuj-fKBd_!AQ1R`fq@;rAHL_bHQ^0=hj=Hq)SH66CUWVBgCG{YqGM@>K6a@Ei>PP$TkL;{7e_Abe&z)25$6 zuY>IpaySbDW~^jA*toMj-~r2bQgoP*zWgxfykwf0BYl~xuKGg&!I|bL?BmGWcY-+} zrU-%l0wAVre~u|L_UJu+lz)zC>-$pZTBrzABxT@$LD{EF9`j?-Fvry--zgvNP1hPi zMt-J#`hqUZjkretmW}Tni0WwH+)nk0c)C9*%#HA~7+yX4U~QYa*QH+XQ8VTU+sjqe z(`4w}{~+J6i+Cn}1N(IZiTXbj#+ALix|e3l#U^yit;hnQWMVw zLbXpiF47|}&8VlKJf6x`u9)Jtic1RY1l|HN$hMY*L%;3wXHK2Kc}Ysy&H2-Z#jLe5~QFUsaWTzb-QmJi$Nk>*3$= z>z$CbLhiH1sLv$zq(c0jEu!vSXis9oAL__9JRSt30QWCa;L(4P0ts2SL62i_c&@?z zpXm9Ae5kp>ef|(bVRoZ*m`NyV6DVA0HTfKP%8wQK(ppUc!S^t4BHfOBgiV%+4T%&~ zDy%6hjd|Aa##%n+U4-LqdPc``C)8zqyj5z=a`Q1nX_5i@p%>nSMk!7Uouk{J0|5+= zh;)*qH?@@Qh#SlDc+S&(18Qlu$=3)vXUDm|qHUw1Zw&N3I}lSO0+YwU?mr_}`N(YdbKICtW0f=DH#g!A zv`JT)du%z(vL|ZWqCA7gq0dYHIRzgkDSrVe$dQyBaUb!voNWSXnpqq^hIg8%jkuf1 z>pxNu=f(e|AQ#QoGjpk#%64bL&bV{!R}Ayr+Q-~?oz7z#KhH)&gbzB`rvJB;m*2Ry zw|{g`cb)O0GUAR)e7v8XhBX5)ZtO3Ni~e62*WeD=wD0JMN(OGZMS?`jRG@@D+6gTp z5a^a^5TKltcE(_Ny^@rH@VRfns|D211&Y-!1KkwC;-6Bh(D{@VHt)q8XA9zb-Wo(~ zuSJ^bmXIWPC)KY3Z{5F`4c-b~uVdLC%_0SCfRbrnF~71SmFE$^#tm>-kg23UXGqhY z)TrE+V!7`t(t5R?ywQ|7%k4x~MI)nz#%3m`bp?m8*sLDm$PM4?U=yqSL-Lw$k9oL; zfbvOvxc=o=`MeC{SE`TicyX{;rQN8$Zj-C;Ua+tCP~B+cl`G>?miD|B0WEM8lq@x} z`JNSX`GcO_?dqS(>A>CVa%%Ul<@7T+H1NZ<#k50t!YYVbRq zi^>@i;y1-3GcW=G!yw-B5cs)%NtsA@(gn!AEHkV_zPpAMgW+VDWxP{KSs;j{JbV6O z()Yd^33bkF3+F@QJod)$GEd7u_cPo~sVhu;mp!_U_&UNx#$#_ycQ_ZM`-3-S!j1di z>KXM`!?BvEb(55jRid!KK1Zv-V_?o{C1L8d$av9^xhE1Po4=dvmu(Eak%rh^RRm8= zFJHv+OIp1YIRrY_`0?5DlT4ClA?9W}SO(cYGlT$*`=A!yrmfU_dv~p5n%*G$RHqjw z=gN#{1K8~^Uvk$YMe`yY=hmmoRC}P7e5w>N49gwSun!EH%E_yC@c}2kCgLeZRv7E) zm`dd(Zk7=P_-kYH?{5HDuMpY{M}ZL8>S4Uk6r zB#J`22$b?Z+Thog;qUMvkdffSy?o4=Y$~0bu5g=(()K==8!<3nln@oDbX*DR^XSW1 zfuH-@4C^cWF(BYgZ^V%k6_ey4UXY{INzyncBy%TefOY1ed#16yWm|hMV#|f=!zyo`TAE&Z}86BI+Tu24y&eW zOlGinq;jo3jnf^m8)TJCi^;LY#OCRjBQ?}3V_Eqt>aQ76p8O2@c{WE4pP&oYF2j9De!4I6jm ze1weTumIlFow%%fm3y25*4SGVdP%hNt#qhrXeZa*{pKwY#xUW8;biYKG{hGAX% zW<2dp?e3$=`LEkEU?$V$tj)C@z!%wd3nH@GMo^7PC7Zi`Z675mt1;5mn7xfBOBxtX zy;v-i>HhpGWMYhI&v3$zb;{+6r225k)Q)-Z?p9=$5qYyrRIr<-7lcR)AO_B@JpDX^TOE~|j zOTOX#V2X$UngW_o@a^0-mzqlw5=3a$3IGi0(l3VeiPc{j(&;kL+|B4d_8t+rSK6D9 z;6WQ&ihXnNb*Sy z%3H5l^+7}T6mU!QZS<`?Y;W3>nU>dQil}9f6!v_2X=iRt)@b2liP;xWvV^6^=E}Di z^c1lyL;FX_Hft?MY$$3cn{y#<{^@}+fqyLT5jCg%4?;WRso5WK;HQ;` zN(wopT!LRQaNaAh9GW)wzYEZ&o9LuA&ah2M(5wAIk9r;{rdQjam<%VoDc8K?9T4!I zi#X!F^&0;C(-eOADvzwxyvWM3@^v*h6<)FE4y#9F{OX)0i=tykG3?4o=U@>mEAWli z_3g-xsZ3rGFDa%r>S5_^GItDsT<5IUVRGQKkc~9YME_ydUFnoYd3fqz{+dV45pSmI zQ4BxOPDY>IkTG_3?097~a{p**?D%w@_jF=TSX~Dkh|gt~1rj!$jR~;&hWwRrazgza z6T$wHhP*Av!VFdWaV}{rEKUGP?v#ukLOhLT8GjpHCP#xVE^VpPqSw={KoDv(fi9sy z+#-?ynr9yXCg?$dupiT~(Swr4=lNc(mB_gyuu0rX+e!F>ic5Njl>^5f!!0GtAD8M4 zQJ*<{%1o|2W3AnMT9OmG+>#D$3pHM8be@eiz`3e@gF7qJ=g-T*I+m~~VcN>+o+&FQ zxFwT9`_6Bm?(DnP`W8=I{Wl6e?<%r5wOfo|G3yN7jrxoE#-Hp{5Oz77CL6CuYpWHP zJCzb1its{Opx-yy8_8??iWjD4tleKoNM#Jg%;gWvQS{|Um%R!0z-w`m(gDzhzy^s@cx;Iu z1FD|1lkZ8=Mw}+C->Jx44(<`7E_PnER&~XmQFNTG8g99bCeul!kaki+d~-IZlE5c@ zTD#}JF2DqoE;(4BReKO{3D0G}}q6^k0%8$mV*m}|GdKYeewKod>Vc?!-b zlQvq$<%n4`hT>J^=P`453No%PI)}y;nRK+&b5Vb{ zQ<1w;N%#hsyTm2Ex>a-+(27JD&$DG_th+uIZJ&;5!#h&=|N8>1gimT9R>ihV2x^~|73yADj zf2FPQp4flzCO%UHtgY0I*7f=Uxm*)Oo&Gst(4d65X}*TRU24*SE-s%!!GdACS)mG7 zJb#)zHt9>9oT$p|%Q2V-Lm1ZXMQ~c5d|d2<+x;QA6J1S;m!)3`9qJ&Ew6MLn4gd80(^v9QgK!E@FIwrVDOn35FDOz8a&ys0%#NTcKTcoW8}N z)z@8*D7GSvR{A1ZxFQaa^ba+!=Pm@3CSRQ){^<5Pt8PkTGlVmq8GR~>yRH-j|6M5# zPJnepA)YJzPeG_s3}mJy6M|ujA}lw-1GUIZVaalc0XI1&(StUN^crh87*R4I#KvTy z(tf9t^+VM@C~kaoxM_X9eV{ZL>z^XM5hn|C+vHf{Fe%m%8)Y-O)P+50y*O-^;iuQB zds#%>!*kHzEg>;`d5`0oOB($7Psk%NSp|g$TOZ3HbET_8!C_Y+@uvgx>s`a;?W0jF z+ewBbgKU64mRfy7eCgR?H{Bm=qIh)^q4XPG)<+ta zOLxv(F{~n8gpesIA=6qNjk6<#U)G|+<7BO1D5x+4=pgw}k49in0FPB_W=#k!xmCWd zfLRu=>D4f9$O__8QW%TgENkuL=Eu2vIxrh8Y(LsMoh(eLnc8?P`X}>Ab`69voNsDz zJKsz3ya2paWY^I9GW&i3qz-|y^i@RK4N>yn;6cIj@8BWVqY5w?(E=Rsx4^=vPddPz zU_+6fZkdV)yz%=hV6G~t@gL}*SDfQve6U)UL}Wah?rk}YAU~2LQTNPugScT(=;!9LYCCep8eI#B4M)v`nWPxk zZBT93o4Hn3VxcD^e`@LSq+DNm(aAA&+v&&{!%Th1i-plG;|JQ!o9n~G40VNQXHTcK zx10J|roR#_6>^xJH%uPC#0AGG?n;x4V6*3|BTTxvKS*#NHKF{9gfLjFpO+$?crdMM zKwP!vks}+F*fdyq@_c7fX<*g|>xuUWp6Obs*@eq__dCQE6a z=<2o#W=?(HQSx7R@n*Z#C?7&|3ffKwOI|l&$mCx1er?WsMX1w4K{9&`u`G&96hLZh zy1EKq`%}NkUzIrf?P3n@`^B8Ed+t7PUiV(PKb2p-B*@0)rdPVpAjL?B8EV&Q>sC6^ zmx{go{08<$%Rhdb+Qm3*CQ807o80(cjB#C?$r#USutik5Rb#NdYtr(qWX@BxBr8Li%eEsKn+1^@Ik%@a?j`HwEh2=- zAFOzfwe(X^bK#O2j5;VZteT!h{eBo@N4FjD*2z86DD!2ut2i=4$EEp zpVpM^-niM8Z|7N9roVIZy{o(26{_4Cx?^5xU||8Ty?4~uZXFoNW}J_P`<$#n8U+Ry zKAN{9U1cd~g>my3wTc9`ijrvGmS`OLI;Aloa%iZx#Hly&D&iXQpJ3VvBK1fsZZYZSGsK~T;>&_RI zx4TUyX?t%k&GGM?&sxi?*0oWcV)Ur`crsDFl=miJuD@ zeb-$XlJZj}(9wT<`=%1n)(va|nF=Mov)Y3uVnH-H2+%}KF)tHriJ7*oKG7&^-^MLr zmYsR?K*)kWnAB_a>Wh1!39AeSj~*d6SZn04H5b35Rx~a_xMXD?^05C+G(G z&v3jRqu7ANUu(NOuu?50r?GjiItR+_K{wD>v++GD4anL}v|b@J>Nmy(f`QHQVW#5-G~LX-J0{w$J(`Rfhcv2FwtRl z%Z?fD2D>rSHm&j_f{ug>1Rkzkp~FhpQ%6Z{N*+Gf#u)jLyoS}r@~JD#8muar9p9IH zoq(md@pj5KYq6)I7r77<;c6v1V|%6rZN@(<(^96a^5E1f<;?u^bn?|btU2u@xQj!x zn-^H7-CDN8Kh8Fq?jD7}k6$=(_O%{W9Tk0<$SpbwXiOZp1VL^9*4PkL~A9Z zd`iA-;%4g$VGvpF{fu$9_{y%3x1U7DKz+ZT>>cdBv%~Sjt%&;_+{NxUEB42EUHy7) z9hEvyagQbyV1CXXM+V@7_ST&u;EZ6iMMPJf#OTl$k!=6~M6TpgV)?r>i%sp~!s&SJ z(LBr~ox0}gir13|@t?5PZV(hJA0cTY1!n&A3cj}(Yoa+r#=dhO2BlFI?ocgw(StWf z6~tEDOG_asg?{>9=mWuAzq8*@xZI39+^1hpxO{JK89CT3>rI99Ojf@~3quCEpr=g1lKt6rJL=~Ci}=nuiW%E#bMsa~P@EkaodYfq;txNUkH)FGcpsO< zQO@_Ji;E+*4wm3#d=CNJQlvT9_j?6^8sI((J=;eI^PRliNZ_L4C#A^ik!2Taq>GPC z%PKSBy!T}NVocqVq)aD?_D%q;tcrits($l>zJjk^Az#$FSm7stSn=YYxa)#FTso_t zVw%(YxK#lNh;)Dv^R|L@yt{~flerBH-E@>776OjCup6&k-2qnsYViJi(Uc-4Z+2x7vm+8aRv} z@5{Q0vJIG;KGcpQ)+p38%H033Ya@P^3ys0EZ~S%s#w^nI4NTu~pz1>9@~gUFZUia;v7=XjeXgGUf?Goz9wD=T#R z8lBjG`vaX|l>v03^nw+_CZui#5H@j&{~X(_?8l#{D##!O)eH?@x|h4>j{(A_aD;z- zApsEf!%tLLcOZma5CFOt*oDj9g+<}}ixebntiY@g8`G)Mm|TFC z2S9@utLv|D^DA!lTUbjtn=Ia~SsKYt_qZmjcxU!oVvDBZ8|7NdUZphlXKr&GPCB|X zjJs`(G1*@-_UQO_j?xvMHhg!;#o;c>9Zo%Jgsn$Jk7p6zbrNu{m`&4~+&GC2@>ZTa zPD4~*T&(9CgRtnHV3wr%Eqf-G0YjEr-&Io!`w?>%&ZPm~5r4UO2Oujrfd8NeTc&kE zMa~|~8y2)Z|11=8#_hNnk5mCO7~j$vm(Zp$4GZc1@yxZ{i;i)knBkqUQltEp_^2re2gbi_-uLw3*8Hwy+sEhvQv${u)X1~_51^F zX57Jhl;HL}zV+e-`qkGB+v91W^NrW#e8)e(H?-LM2%VV`%xvt^r~$esR}HhKvwOBBdoUNRS@Z;Wfy`uJ;S;~GE@>aV<8GR8Q z5}n}!XYGqa9kb(z*i7UkzDDjgUc$SiAqKl?yKm}1E@o0D^Q z^E1MDOSC0Nr#2vCbQriw^zwER>&2q{BqKQ?HEPkdYys_j$kJSk=?PqII z7^8IO?6S0)w(yG88fW`PXv12QB*sH395{Z@b6b*636n_p6KmYwO1?hI>u+A^J*Jcf?fveO!r8=GIY(q8J+sJn^u+rI(0P#%RjgC(t4fR;91AJ!* z!65!?MX5l%7jLw$C8_Eef5B0@`7a#7;-@B5>_2$RkiLWDsA;ZJn(_pweOrhk%6xS0 z51S(Yn8B#{+X8Pl_k=;BU``{Ft$7+A58Bh#H_EKCybY4lLayQRthF}CGAV*{QGmz~ zT^%UEyt!}Q-tki1>G|UX^%5{coze`SZZ$NV`F!+s-E(3jr`D{7uky&bnu*>u1E@Df znH?5?DRivonai0S7k9;THP-XYvph>7UeV~JmoOVgEYGya>M`II^R0?FZ$KoxmEvO< z%4qtSX`|rZtm^%p~hm?SO6b}dOL`>Pg=kVek!H}a>LVG)C7 z(15&Q>1A6>gOGpdUyy&4L87&7Xy6gyEQ=h z$_jnAZx8Z?oA*jgQyPP3QC|00r@TfUhaa5tg=UYD=CRxhZ ztf-5xVTr^~(D~v|%u;waGT{kZg=%P>R9j86$u*Wl2dUXGuRq;_fBkfO;er0+_owTP zh@numY0bjIlppn6iA}cVcvZ4uIbf;cxI2gtv2!$U;rWMH)ZvMJ@h6K3@>L~dZMKJ- zy-jS^>~Yx(`~(T32*Lc!hV`qZOZ4ldByR3wX8nlw>aGZ}j@wA6>gDya9OpdYXj^!l z0&tOeIcC#u94XgSH!_n?I(Xk})9xvb28W&mGfBy+<%)bWTifw&p zP021zNw<>VBanYeASYec%LaeeiufUbCmjAn9!Q%!1DZpe?MyI)y2euo#S9fgos`uQ zd%B9%zRi1e*1py7TP}r6jd(I=Zks!ovi4rY+e}FUiVmGg?-PW;@WF1p;7K+22?^(t z+?AoQH#wV00ovRMs3H04xQ(!Fx+X*zq3=$N{St!w^bGb_ZN9Y{Wr-nC4#xfbKy9BR z{!@mSD9$gS6cyu;Qx=!p{e`VL8vnr7-6a>#J;Q0znvS zZA!fXRmbD5GZhqe3yW!vs}Xx-Ko!F{oo~Y4{45~8FE1?`uf^;ChX71|kAp(r12nVp zK>GCDll$3=0fDlB_7LTOJ^{AHUffiv_Mp+1tI73)SBbKZIkuNIr>px9w>M>~Ua?A^ zPv_0XbxfbqoeCzqe(`9oyF_u`uab}H%br2rZez)ES}UJCV&~a@(dGA0?;Y{pa{Y~? zXbIz(`Ku|g%6E0SA+asYVT4{augzF*V$pdhSkQhH1bet{J#ukUI-m8}73c;a#obJd2V=vdnby{?OwEkA~r05RNb+=zEV6Yd2Isv@>XQr`8A;Pe@f%>^<+T&`3^Fzi??>Lx*fX2a@44lc5?jCsCHW1GS%0aK@L60=ttwvD6iR@!i_+x_ zzu#L6mgH-|%nE~Kz{lznrmt;X>F+OR5?d6k>RNUG-M)mbEAHWTx+ zu6BkIQcPXgkUAK1?UOJO<1=b$HNg~1xW+B@vFviU7bg=wcoBtzEZ41T0qI5o5s(H22}uE^1O%j|yE{ar^AV6x1VKPRQu3j@J0t|8Ln)P# zlt#kux(W9_`}lrmxX-)aUwaIH?7>*iy4IR&&bihtC%YqIRje=LtS{=-qsFzoA@<+H66$!ByJ9YY|Rqammves#G`>r z`(Rj8Vo(~bk4KKsn=6Jfg;8q@K5u;OJv){|T!OyaP#^ju8t;Ho(_if7R&>jW1im5y z&hFEMt!vW}<8a{a$z@r@`tEx5145Ha=K4D1snygl|z>Kv0aImWAL%x(=46o^a}jt4_q)B+|gc+ z)T9E&EZlhRtqFh3sf9T~pW%t4z6I5-Ku(NUXSUo9Av(pUjsn>pz!+euc?9ZVlvUz- zg>jR-P_fhfBf`cSdZ%fVpavq-mcZs!rH4>>0ipU3p#nAsNJ49LA| z8|8m$%|JcVR}9rbF%%I|#a%$D*|Au*BNcGv!=l(DxvpJ`;W$x%{@QJf<$d+Sll*7n z!}=!h0APDF__9>kIs0I-#LaCaq3ZxYcNbubrsUKmCAj#5mCUMqU4tyttmxiM*DVJr z*~H4Nv6`un)GWONCf&woqjmMGb$Q-0Kr3aSsH0i>P(*jIMO@#T{*1Y{5mypW8>ly@ zGnQ*KAdc|k&Kkqo9O#%r3a+7x>ICQz)?C-|;I{|hwZDXy z@fZOJ{ErC0tN~CVrwD-57kstI-LpZ_{89$@SUyqp-a&MJH{ak?KgncMuMdUs#V^X0 zON|~=Yd(&8dHMU8eB0&iRVZ#(pM5C%aPi5cTd|W{djxBJd6cQM;RU3Nh_AjRc(qh3fy`eDc=DsUaD5GtJ>6Pz@+k(2`{ zs;o<0ZmX?z<#DDM$m7h{Fz+{P*0uylvA<1pv3R>3TL4%+9B>*Kac!^YFuF|dM)i+r z_w63UUGGDmbghUD1~3fiFfNeTx!5+2F@OtNq)!2?Eck+@Bv7_Vf)Nlk_~^74!sVXM z3OY4DjwlzRrbZ74t87PsKOB*R#-NwJPSmf!7*zbwdFAzpC=UAfxT%W@@#~O|9dKs+ z5E)`1@4o`1H-&N?H6iRGCZ>AyRy@rZIVTP7%nxT_bI5yi=uGp_5fJYrydC~A zc_rUzhp3l~+viD6Yiu^|{!(vpvyj88%)ZFmZJBc3n|tp+_d}v}WcKI4R#mM5zvu>y zhsQ4T;I zsEnJuafYaaHzJbl5Oom7sIJ926IBQ-S&Vdg1@|d5Kx!t2#Eo5r>>6@m;PmoH;h@JA z4H`f8QY@var2#~6`oNjRgHul1dG9_OFjrPA9!UD7?VeLCa#h|eOhJ2b9+1l^l9-fG z*AXQx`lWM;A?bWNG7xCLTx7l+_hKrSgupiO(+1PavBE8SHrEmKiRDE5cyCDx4{bHZ z3Y@>#*&?zDZAA0dnzl6a1kqd_trz`p1Wak&*YIomRAp0}a3;W=3_S|godL{vUnjv= ztHDiPWNyvfYavCh&i(sab$PqMgN}6ZarBp+aVO34m34tD>1;bGDmJPq9}4cGX_nfc$>DS!mW@u?i=*!hyiK}-3?z}4%79sEYb3~gg~Bu{L}*i` z@5ASvC;c(m{PqaEi#}cwTenFyecN^Vee*uJA8@tyXqCw%CWhw+@hiS%(t6b`4BOXI3E4*-j18-gwTxry(oRYed9W*(@d5U|CdZIu6+12lT-Yh=tIvkd9)1= z|9c!7;rq&C3sdM>CTk73E!86Lj|$^vym(N_8jn(9S})}AS=miwXS~!~!O*lZxXi1* zrFOs7Lmzk&>hI8`HH=ez#-|_1)Fwy4F~fCZf7729JmjCcM64w6eb?<$E7pCEk!!N1 z356VF{dMG!S;^TqPQK;PRv-3ycdQ1%-)4~{zjP#<<+^SK%9?M+TX9+cYY9i^h~vgd zaF)v={14}^y3^rHQIiEx3X?>^=SAo$gngf6a&x{c(4KEw z4K4<35+pX0!XyG+uA$sK-fEXQvHvAZ6j|3X6=AfZz?*aWKbsB zB)i#5if-<4E1F9@UyaBL>+&gZd!9E@JP{L2LxDSL@|dLGAxGNPgiW$)ATq@BHo9?< zhp6sb^Y~e^EFzg5?M=U>dv6wwJ(b$a;8x-M^(;p8R+Ogn1}J#Z%gNSY40fNcYNq47RO!(ePCPc5cU}Cw08`*SM9*^smP&gNlj>1%*$F0_pO*ZJ^cM0a>1uwhvA3v`#nJ% zQZ8L~N5HGZmeL{Ag5S}oq~-?BM1)DMx`}o{ZzLqiud5x4oo?`0Jd8*Y+eqNoZ;;ZW z#D8&KR7%?gNtt(v0cw+qjr@e7fC1Lvz2zipZQ_k}D0{xX#2=!)&i~DG2z_}%28mK1 z`5ZjK`QX45LZ{K|uc38?Y(!;OX!+mk4f&c}(jDJY9TYr5#v(sLsNSBn+FjYFldt*C zw=}35JhgVm(bvPxW~OGvHo<2VT-v$h^{v9KvG>saN8C4Po23S~2DNDJ==@?qwJdpT zgG>4{0&~pZ&O6DsuMaN0dsTzhUmX&NfPo;r(Ib#bip5u2^wt>cKs?w%T5a5no@|oZ zj*Y_R(V-Z#9``*=GbMG@kfXV|S?*s`-bgWgq)RdX!BTV8aeyPCo`#0L$w}~FCGM;J zdi{9f&cuiM#npE(dsdgy&`%^?^tF#nJmrWR_U^=Yt(tR`rrQU(X-MaDqusKFQHk-| zgIuJfC+t@P0=D>TI336^`7lV5#uZm{;{uORdd^LB97-^MP=q6NB3>%>L;mEK&xyLc zR(z3}>|mmz1fil1gIG#4`3X>$qs3U&ItR^GGix7t%aU9~Ad)KcUr4Ioyxg$K7z)Uw zGTC5VK1c-%shUFA6OQ~^43#KloA2L1iCTSU zLw^h@ul#Dm8{$J>*ir!>&ch(EbpRSR9{cX@_*8boI046zS|vf{P7S$Ao{lELen^p9 zV}bvw7V!6tfB)G1TvB(X>poCT<|RxX^Cd)QSlnoeocGCF{yrIJTmNcKfceRQnyq&E zk*){yb@%JteyAgpEvf>zwsrhvM(qRVjAKH61V8E$++n($B-Ms&vqor)isMYlhLo>A zuJNF!%l}5W^5?Lb_!8KuB>fGi2$-5nPQ7cp@>iMK`}-btpFmvcYxWLTU83C3t*&t z2L09|W9ag^8}||uM%j;l>+S#Pw{Fmo7#8w-oeX^9wB`4nY%UF<*p#oI%TRygYSr3j z%oKg?E4NAF_bgf*IWNAgW|sFMagTiSMjOkWCK52Cbhbpk6(?)v@}s#vGDniTb(=7^ zZf`K`pt0+)j2tJ<(Fz5yRRSMfe(?J(v=QpIJB`5j8&~2qUGri;B+6o|z0(;k0k;F3 zmzQ}bnC8|lUY{`SS+O4V1P73<8;7@Z)GA_XFxH%$7i(CjzcHlOvp$Uy>$9m?0j$n2 z_2NytAJ+ae6<&DLHZi(aM^f!EZ)U7+zpouPd7tQMz58@;#B~E->KL@zAX@)^u!r z=g}3c3JWbeIn3SdJOS43y2~0f3*fUJ0`+oFWgaSm(xOhI)BNi0b8v=nv0-${w*(vj z-Vk9lU;&UX4KAA~Wop?pmX#o+JY^0rAK)Sn9)4V6zdkQ-K73klK2rWG{U{=~2}Xa@ zsHo8VO+*AiL^Sit?(@eR($ru>nx;mX`efTygoO6*U5goD429T1+2^{zD)!5o!{3Pm zboTH* zWgT=6YG1{ezqqW_?%>%jMb;+GG>o-yAFFz4%x-Pz=8s2jJ|Qkp!ZjZ~DNdw*1E(@wK&g0i?C_IPa|0l3y=3P$HK%;d==s{+f>K{K zUYqSpQu0?ngr5B_=>Ph=Xo-P20L?UnI4XOc7W!R`$D$eDL!0ZL-qV<{xG{Fx>>gi8_|GC0X zwf`7sOw+3`taHn!rjy^TY-V5y_fn-(+oN*T-rMsU#)qna!q%^=Knv4!oX}QJF&J{L zfuDgszG_?<9P6m5?C3N#vo|{4EIUF3n`LntKp!#Emtai8kHS{+3Hg8w+#jlHpd_^J z1B=|{BaaQscaQku%B&m!+q6}o?2%PJiXKr@=9lHar1`QDT=ZgdtiAgVTSD>wZmzEn)2`nL}6FhYz|M3kL2-D@-9P{sA|Al}5&9gcc7(-Y}fttiUtY9gD z+Pp=Z8*>g&i(FYRLzw}!cr^)cx$q9qq^={uQo!zM-%993jay|?7T~E|+~FLdWzswX zU&JcLlw{ayHeO$a(-vvH(ovP7V`P5?N$45Hzn0LOrHp`5CkvUb4OX^Q!JhZd;$Qc? zl`TiXWRr$jT>6 zC%)V4kE5HVNp0LWP6X>Rqn;D<;D>y59t%3op%@W%q~FGs+aB%DGuqb8L0G(xb4!Qh9oNIt!_*B_h`7rT+ zDgUWr+5)=8K^-5f7;D$C#~uNQO*#G=^1jZX4xs+Pqho=tQ+~?4XPU_9 ze@F|oy5xf^meAf{$8?3g!`lVm{<;4z?w{YhBNE7za$JqC)`5fECzIbTxV-qmuBb?t zB(mSbd0TQW`HE^g61(t;{aw_>sqM~b!Tr2|L~{OWZs{0Z8g@B;{GQ-!BBuN5D2z(< z;<#KtS4d)%)0Tv+?VCAr%pDDdXriPCWS!b8~q{C#Y~_;^AKe2S4P% zxw?Nn_|Y*?2>en+K`90SRVIlRm80TpHeUj-eAZm?K)pgH!287Gk@@HE4pUQ}9~yGw zVu1UJ^iB=7B{+GTr8o3iY;C|kp#gBd;^FHYq}jSi&jqrPmTKNczOOdFy?Q)pzHsmX*pwjKcU%U6Va)m$(0wA9yM`8u#C!E;xeQYy-I>t7 zb4Vy+B3>m=nbg9nTt6r#T|ufk@8uvQHz}+?fBP^__tyTB%CX$EZTm~PsYms(W#VOE z!Hh1(1C;5vigdw;;2=QVUk?IE!y|w#NBwGO5Y=)F>}z7}@)Z1@tIIQ7-WB{;9IJDe zwo~t!dAojV7Y6fFOe!XS&k4=DgQ63bqA%h;5z@V-Mw_JB>TDEtQX_wNy+^4NpcjU7LIU zgrvv|OV*Sf2P~V3f+`u81Aa$vvPs}w-CZD?x!cTQ^^dZa!Bb9t#iZ(Dvm<+k>uQ0R zwA3*^Knd>97wmGN*}cr#lpZ5gCNz9JT_eXhSxA5>YZ632`ClCS{Og+yg@&dry@Fw9LTL!pzTk0-9_?0p3FEVU>-!aPyxF8?9p zfhkLizd+JU@Mz~vOQnxXp~tUFAuk@t`9egRknq=E?pam@)O;ku zf~c0jFW1OX)ns>f=}X+l0rS-l`paW=1|v}{Nr4NQ`fnSa=5;+De&u4ma?rB&mV!yI zNQTFk19cgv#?@wFdd20v#~LZeHDp2DNtc_Cz@4b;M_Y2cJ6(AV{Ht9)4#V31aX2M6 zmL}aa%|^2Yux@R%8%Q+>`CS0(T?jlA--x80JxZMr2P@JY{B&-YZW_qlG`uJsy)APC z7xhOCoOP+Q{9t!Ov3zf(Ouz3grru~mmOhZoU>o4;PLRuaqfQ44^$Le{=8rIHQ6BJ) z8&ya$0-9yK(T}gv(!Q&`3ktcrjS1ET-`tUzGgy7?PZDF75J(Xy0Um8!xr-RE?v@Ri zEx;@89wa{&u08%NT>s{|J!K6lFv5Qtn%M>G<)=e-D!*F&rye4e94%W%1%)P+_PTu6h1 zcU&95>8OUDr%}Q^NGrkmxur@)CJxT4Ega``1<{u7Azz;io>@E+qqA=C(>_*qsckZ>H)WIy*+ydRhm)BnYc z_?t&+*O`otd$Yw<{2931=fBiE-Gf5Y_7;-6<};y>wZ&p1>^*0nVgR(Pe64n2o1)DM z7;768ZH$;X5|d#aHY8FVL2BE@m;}9$fhF70X^Bs;YJBm{1;{Ht^UDI=#o8<6Ct}ymjkN8K#dHv1Jv_NVp@US+Y? zaJu46WqoIJj+e=repqGUeD49>c!=$W1ucQ_XfeOmW`uBNNAT z7}HzgVL9F;j@Nd5D{J3OCmZb2Z!5gU#ko?RBM2FyK5k99J?Oc!iW;Rz0X!uViO@DB zw{J-q`08c+CU}sf;6b`V71=54tRfHmsUm-cfzw$LO`cyDRMsyM2)&$&Xu&=uJS!^O z|7*JQAt5_xt5(`uES5>zfmzgW<{JImYW$YtZSJlYww=UFiNPV5?CWVNuK~GEnX{fu zyNw}u3kF}4Ob|*c{K$pm32~q^8g#+y70}HHdJmhI%u$yzmLif;vSG$|tJv_N2Rc2r zy`nv5nrF{pbS%f*{?(|kvK|i33do=ISxH;sHxU54ZrDde^}L@wz8lMb2+4ob8l%Ac zA%>O7)?Qy@i2{c%+TsZ2--ae$$I-d%bNBbAbNP9EJojyoKG;@W<1{Zu7=Tw?QNnEF z_!2`ry%%M25y7@*<=p&e372n|Y|FXsM7_ky-3~jpqX_jE0r$F>(UEY*@patXa9;C& zsrd9ATXh?Dxcw3COu=*M+veK`<1%?~{nT_ZW1aK$B48brOFA&{D8c3}_Zn-EQ7o{k zyW4!lq9e_m&p)fN%zvt}gTmlP2Q_xk;pwf%=kf5R=NL|*QuiQs8srZ8uZk=-JC}Tm zmG;Vc_#l1@Xq_#g&+|(J8@$AKi&RD>fVxKghJ;<7%BJ%C0Drr80(6mOt2CJ7;m40) zxyW#{QVdJUvE$Ne5bwDf$6KumqAy84t9 zf)8k6B4koFydMG8wH@pnfCjo!@UiTN{O*cB9aZZmO-@N|7fIHe8FKt~c$(;>85j%# z!LE*%wd_A<6;$}O&>{^2Go!cRcPH=R$vuMZibqyd*ejLa^ybGZ#J=fps#R^XmLCoA zOaaRm%}prrbRa*S>ISnW6`> z;WmIp*2XdCAS^E0lin>F6Eh-!`eM7%y=T+F`^9h@F%YW)fn+Tl@PKX0?^cYs@JKSA zljxAr_vGo9xnJkYvC#rwu1ROU@Ik@#=>lge-~zMyitptm6f@#4F##e_^H)&mwx<*d z<3+}BqGYi*91F_^#bJQ=^ZYCCmoLwx2{fFkP{z>DTH4^`>Vm?~xO>Li&7dFESaO0t zNc_3H;I?_zQ5o8{diCvQTpBczrZRx5ZGHDeatMxD!tP%Uq?!jW zv6ZeW(KCwzmwexc7Bf1)5FY&XoG;Z-2k?_wPx2Pq->ALS-*c6=ZmAGOnGA!h9v@ky9`^FLM zBOhQKK6ej5T^`T^)XSG+`c^@0{}E7B-+bJW07rNdV#%5wZD+av956Qj)Xq9!DV7jF z@UowIy8w9nTAUufI5SavR1yyY%X55xy#g~XF$=Cz1$~BJx`IlmR^)T}D)6&IW-CZf!F4-b}ydRXvxF=>dj6_bb)eg?ysUb^s} zYI)A6UJmlzOv+-s0lq{gng{^cwAvzhWwyXV=(ddbW_omDFH7K4AmU`xvOHSM-FUP3 zk|^+)DUkcs55s>@3_im9pMIDmQea!SDa0s#ZWx>o;o7}ihe{EPRrYZMr_2ZJCf9?G zoRqS1iK+T(pMkMXu7h9O0r*SUer8l5la;fLE}7&g1A6nU-S zde7r){k7LJ%ZwMFuzfj*f6z!GM>OXEOy~s{N>{oP@*UP)Q5Az@CS-)HVOrlJJ4R+E9nFtp2rL1dW{L)70V%u z=bz)|l!JC3|C^t$H^MgYp=g3X+--DuNsA~mHh&(RLmH#Qn@Z+= zchbAMCIO%xs{je8@d?ULq3-zqzB<;j& z3QxYd@|cjR@V3TnV9Q4UPq^i6{a4Ct4~TfYapXqJ4`vDG_@qH=M#Hr;0E77_0P|V6 z@CJlQTNmlK%JGFH2JILF&K~jDyK^MK3FU2x3xOCk`oD7rI-`n_OP)8G)UvP|OX>N1 zq*vr_51NeqEeQ4XCu;wc0yM##G7bQLJ{Qvk_N;p3vW;XSUon%&XdJr zoY+w-NvipJtb1WOR40-y>1KZJ#%Fm)gP>zs;NmYH@BQtAXaD)}TFrwUCw`o@&uCM? zSZba;y3m@n4^-3`d$qZ=NLF2Jp79OtTi*uWPMn{8=DDi|wLFRLgm>q*28Zh!xvhBu zUkmv)fF)|Im4nrWY@1+-72TyDupg_rWm7L01Q>HckHgd3km1>sO|mF;siD?!_O5YQ zbR*_?mV?fk>Iydb^}a#22~E5q0pRl7W&#g)2t3>i9MYzB9Ytr}H5(-6m>(a}F;zZ+ zTS5k*;2W1fLsA){U=@bk6%lJ{#54a=q`LmE1vj!8l82FGHz4)?K!e)J0qZkp8|3HV@D zhO|ZiQE+!k+0$Mrn}Tn96@OOF+;vbl%~4fxN6XYuplghBtP`djYkPi+RThbiYfE4# z*jy;#;t#gC4=#Fy+yI&Wkf($FB{Ic@Jf5?qn7}xZS{sRTNmk@f`t@AC;hY>qWtz&2fcO*rl}@5 zBG=YT^Zq*4KrfTsZ|@DBet$4a*Hh2G>Y-ftgeUz5PI`Pk)2+_!qaV4kceZ?0!^9Yha0UM zc+bH-Y;lK-lZ@9g)1Za+a>73~<#l23xi;{g*B$P=z5^cJue|uuXXXkkYX9?xvJZl; z${iDbqJPI;A@9(_BX67+3#ctgYNWwRoK>d5?yCZLuOC2HMj7I4q#)cxz<>-sjMjHS z-XQkU>l5lHP&?*)25?EKl)l@7Gm&Hz+V&aUGkmyJ{1o8}%L1tGp9u2V7x)C3WG;9^ zyZHFl&A(VD?|4oT2*dE}`2W#>Z#%(>O2>D@T@FYQaW!y}2xZED+5Ifyk=GaOUBw6F zvq0I^J4GJ5Zbs>+G37Oo4qe{^ws+j1vntXq7N5Kt6hab+W$E@%(M@0mS^BzEylDD2R$r z7M4`^R3%T8&_?E@Kg>P_7n`vmDZw<;Mk9n6!B=HmI{b7(X6f&GdQG0)y;aFZh-Ol?9z5Cf#rmdJiOySaJnk-2GgB|d3tXq_ec7MYdx~aqD3v>`bI z&OZ=WTeiXPw))P4ox@SoNOa|9dQaKV#+UAZ-M6eqF5MoRIn{F;0YiJPq=Bp-GanFV zjO~k82@S^MdfoaM-r!VkGAp@Wr6!|t1y09^ZY5YDG{a#YR%{h2N>_f4qLPkJVIX=B zQ>m8x9m-uXI}U^L6=mX#S?0C}){R8nRb!IQ+Rn-)*}JZb?z@s>CK$W)lrOrosbfk< z$H<>}H4_-Pu5#wV$8VH;z7PJ-!4^CskFJ~dKVp!wtt}S2&|20(h{mP5)j!N6(OpJD zoN>_1H0em3K`ZCAUp&P6Z5Q1M{JpO?DtES7bWKD#4+EEi)^|=jUAf!JyiU~*<t3G2I{!3o_t?EBJJzI@H?S3J;)9`o8nnm^;KQF0bsx zZeuit7Yv?byNRh}y=Qi}iI+qJ)ygrRw(jYm(M*y?a#+xEIHr<7IK5;iOIQXn(bSzX zQHG!jpDLl54-Hlil(5PuIVWqrBMw$0BXci)*qD%%u3v1-3Y%&%SDR~+=@qzF&w~*7 z$cC`DxNB&I?SLi{uiq`*MS1yoCU(LYGNY|hEdJ1QTI-mV>f(L3l zJQRGt^A5oI3 z0wY_jH|G+(&p#PZdA{_%&|>16itNkTp@KL<*6k}6KB_86FFyHj8I}P)BVmw&YQ?109 zvU5{KWRGjYsplM~l_hWVEUL}LCg??DAxxg9?Hg4V?dR64YFZ0X6Omqxn^i91r}q#T z#8jHNdWg^d_64_$6T5L&sa3CULC!;DkuK%K%`FUq4MJ9V7dz5`@Ea6|5j*xjzAfn9 zSXpLy`%GntC=O{c%DMVl)s94LS!?BvBdh%Qgm&Whx#o+c#2L4SzT)cmcpcEkkA5)w zaybh-E5ocHJI0nKPtCWCAcM?h3tMTwowHLnaa|&!iSE9nE!rBogoIpb9s@|;m;@ai zg~|JvzO2W6QzMw4Mt+6G5oR&*m_$5ly3i@CxtgV#QPM`OlaE5W zPD|-Hdp-X>dnKdf4iO`Gq?~*k6;fpS<3!BEtu;CIjk2_0^7hJt9yKD%?hDB9;d0gL z@7BVOF3t6QIiLd2J1$)rB2%kt{@hfBsbooi?RKu)4{$;%$E{_x`c5XPuHzQd!F3R@ zqMV~CuI;z1lbdM~!CHnT`hzTq**O^3hsuM-#O+$E-VrrRN&BZHzj|&lkoeF%E|0W_ zHd!*`s75cki$-H^(VDhaFa48tV&9JSHsauQ#36*_g2B^xel4IvP`anomxAdG>oD!3 zH6OhYMvr?M&)3P|FFuZ^-_xtzPQ*1rT($_0`wgTf_{|k{h;<@3-PC*dbfeuz1H5e! z2{KU`lg(pu#`SmaUZ+aik==lgk%wQ=1$AcPY7M@(p+syNzfgs18R`Z7q&jHeRUhE$M=EVaa}-`xDH zZGve)mv%={LHaJ2g?t6b#9&i`URtFeI{EKr@pCq|xCwOG?tf#IU-M_w zq1i)yimRMxE}$Jak1W(a9=&Dxjg6w0cE=%znyTV(5g z`WC*zB45J0>af~`%s4sOMnOs5KC6|8Q9Eka!(rVaM>DKuttKY+*?7>M)TM>GI^vw+ z7Z6{NgY9fyhaNPP1uW)2)PLrn{(q5!?_`vnU{XCio5*l=UtZLJCqbznraQvFIJLC) zphGPQXF!2C!<}9yEZ#$?Z}Z3dG<;#GD;4JNf`8_Jh5fwn0lHZK3M16eDc3Zl;#||k zT0v9li=i4U>5d}!FoM4(BSgI=BF1T5RKkz-BY>`XbHZFlxymqX&e9duK}six*mzWI zUg;C6aIXOL^WvZV{K2dbsFp1OOd1beB?q!~6Tb&f9x?4imeuNtxTY5%1S0t4^+zCwSvW8TTTZg(6!t&>u%bVR-@7RLc) z*ObJaFems{xd!K)du5?H7uz@HLU0_=JHH6%jAotC7HQtWy&Ym(kA#(*g*5ryYt>?rz24lp zE*OYop6)J)quvG-$4IB1BCD~}+-yM#{aGJhtX0xI+>Nfm05x$%lV3EO=eCE4%2gze zagI1kWM^9Z5OfmJuL(tke|H?Gjq zZ1qFo3P~xdsO3qIzM1p0M+-f#b|KE-p1$>B_RcCH0=mS6iS%ilMsF!+c^y63xvNG< zE}C-DG7Ir3S8j5t!s~A=MaTsN{ZyG()81U>%FqIhqm?7ji~#P%s%CPA$SX3xu*kQ6 zZ-pvgsJ*vYvean>YzY#+I7lE%4gSy?{dSm*bE+|}^0Lke;7MKv(LKhM7lS*cKiYqV z5>Bs>ReR_(P-OopP)}@~VDRz4Wxi!HwMN)FGNasu<1jshs@o&CVavI5lh8lsRlKL5 z)HdBk9BdaGt>#$k=_s4|=(AvTm$ahQqKT1lj5%xeLmLy(bk2D^nkM3m>-$eG+4S1u zO+Uf+9H2OmDLI`qCMjSvgg$ysX-($-RBf zxkqr~tIb{;ujDIwjp9Il+J~^COSUeH`{QmCI||?f*zY&M|8AY#%3EE*ti>dn?J-xW z)k*rz=lx8-S0pYVlZ_`$o@gFmo!>oAOH>BKqJ*&FOb^oNd@J%g1JwWRMTMs0;Wa18_lPJeF8@0U zd{DQeNG#v)9(Lf2;YvL{0?mOrgJ$v^U*5sNAnWtkS6~g72u@kp0FJC4u{!Tv{ zIa-ad?rtRZP&nKt*1Ye^WzY}jq)p#Z`l{BJIE8qdahII-j{cv$R)RIk;He4#F^r}~#JJpYc^PV8Qs4w-Ve{A=N{foG1vPq{rLwXYZL34hsZ z3;KfChj5jy%&%29v5)sY?*$Mx2f62->Z#(n1!MU^L5>~pJ?`}&F=r-NW7{sKQltkH zmT8My;7;rozH)UWxrR#D`ke3#+j+4WIT1vbzlWuFGdIC>f2r1%8j9PlyN<@{TO3s| zT4&AOO@C&=D+32m3^hioJ6NJK{(g7}YrVfspzQUrWP4agna}8y8GaNw8mNGyBQisn znz$7cx-%7B^3Zrf7+aV;v{(2Zh5Hx@2LA#H{x3w&Ck>1Or_r;Qd+zRX7QM(nqW7+? z7>Zseh~5qo4uSvz`u)g6JtO}}p4IeqQ)tN4QtA@f;VY(@85a!R|YyC^(;X zPQ2Dhj4?Ij(O|XW{o-m{GRJ)ff-eKvQocDGboJug$4S`r&x8?{_D2%h$vq!?qIim> zHGg91`mr{^zeIXyl6D8p(f9-Ip*f)F1}4;Gssq=9NbNb56S+MwmGqU#F8uCDSG{YS zSefh!3!00a2c__Q)||z0i=nGNoX^aN%%Uy8R4Q6cFv7ZMtTIj-XjBps1<-? za7=vOptHEqfN`#;)uvQu#G-Ah7T#n1)Z^g6K=ACY4~CuwkMK8xCt8bD*C^-3sDb(o1nKVG&v(X{ zLQRgtM|i3FI?SSCP83W7mz5^*V4oRC|CIvU&FlGQmN>_rlX>p@8qgTe7%TYS#Elr2;W&7Vi1o6*+E?I@c_-|LGeG zf*=lw*qGj2yWTX`%%{fOf&sTE)L&=`@tsRGx;}_~EIY&!FV+PINX&tX!0>RW1jWHKHh72F2 zvUBGsW%ONsFaro}4Ds{r(UD-Xb>E4uMOf1l>(pVgSvz60ztyLMQQ&w09wKLQhgrnu z{nd;KSnsweelE1s#Tx4Yz0N~lGzEJ#kHDT{b}~K40fi> zB%-n!VfydRA+V?|Kx?PP?8s~(4ladmxO=AtQSocJgdOB2Q%&8KUk3lW&k*g5U`T*s zc2fG1E!|)iN7~*D{@wJ!UAmxc+*6L`*SN!OXVfu<)dEr5-;m!J#Nl!@5%3=8UwGEP zBkQ3(JlX5)B4eE6!ueULBgyE78Z#KaFB21)hZTS zo5B(~dO&#$`Vbb*y$qX4GG>uqc%At=kZJPEcsNaQ)<7GV3aN@huZ23-q_|E2nl0sn zHEgAjyc!|nQJ%%QYoPGyPvuC6hMu4on3?^?BaniZsQyk0Uato88%V)znL{XYY`P8I zC?AfQRc&QM3}$G8g&-g1OUVhvWBmMy-~$Mj7x7e^x#{yNQ1QeUF^nv+(2FfESa4j- z!_0#R+txmHsCATm&xa0GJobMiY{p45Kf`7;9{#2%=PYbCr(vsmAhZI_9N7u!P@iqI z6%%(mo#rm7@G!ps)7-(|sdqOv6f1=WP2h#LG5`pCd=bm&9xi&Z1@TG9EIw3Q^2lY$BF-^VzL3rO zCptu=Ph^cys(so+`ds&L0P^0|o}rV@Q*?6h7-1B`CPkj{i0+64n6-q_ImQ6r6&<+f zjg4nZAJNjjM*@%20smUd7`)yfI4i^YqG@%fm2h_RBMHW!g$!|Q#;Bpa%5T!tF}`0X zF(XHBB|Fqkw3ZOhBPz#cuGeybbm2FOx9w_0zH(CK;Nm$YRu5qo+lS%O)#B03Q4?z3 zxZ?z}S}TZy2UX|j)8lx-)4fHS!yn4bOZz^}I^+MYyrF3PQQlf_^TNC2El#D6s?)hv z_bTO|I;ufZnSq$*X@)Ugw^d{WG~USH8N>`X*#WuHrIcwa1D+pF^tu=kOL_4zjR(I> zRAL2G3@Bh^3iLNHkKbhE1)!gC{b0Eo-rxP&6ZC^%@pDG^u+fXnC{EvGod3|?7_aam zEd=2@exYyv_ZTGCf2iUt!?K*@o}1afynMp3Xt17gEW~K@T7UFWwW%DnQN@$V)nDqv zU?((!@&276wxr7jWL9aet(-lmkEXldCysJ2JP8=zP}vfT{CN4~I+7%5L}ZSInu3EHFCoLZ?;}qVRX~q(3KK^|ZS)wtDaS2pY=ePTPWhz|HzTv=#fx;MKu|Z1 zG5ZW2=RPytUGmmf%}_bx=FZd}z)}C8n_BySIJRyiIRNeDq;c-9w7;;5KdopjG-v!U zHc|_wlAuSM_MRp>-ZAXB1u-W7ORz(QTM=rV7Be3VK$!fCU2{(q$-yf5xgX*uk@Nmj zIp7&80+HLLv_N4w*`#f3!eZ-m*iw%`)115K9c*L!RVbK_}Q`=ZA{48ky z7ZYkU&iL#Z+znodCu^8xJRKBnVVok4NlKvhNm&^kXBv(!n6eBKM_;Q#EumRJDb}9M zAO-N8Fh~UdEv?adL!k}^=h60n)8N*8lAUliH{+>|cj?A=nj!apYdVPR{76rp5R>Rc z>1pKnmK+U=Sq9a)z$$WLbW3R+&{H2qn5_aC8}|z0^XId2MC=gVL@#4`<>sBCO-scO z$Hh+h!UvofwSRhUh(;L)xa?$Z2%e4C+UZg`ZLH2@r^BiauXm*o9e1JfWcEXBe^zMH ze{a>D1z9uWiiXOUE-R$DJ3A z^*~~IgUj~5kFU4T|H`qxQ|kT>Y2}gN_d#L;rYk=_U04ZT6^H~L9dCc{H}@3*#?*=J z^XL$9wHSEPtQ7b0B=t(@%n%mc=Y=mb99yt(a{h_J*D73Ach+Z{Dj0?x_|N+6m8Yke zP8B1RMLsatYLF*Ot7#e&^ja*=*bPQVsu=ONuz!B%nGytqp(*vZfbi{Fpiewiwz_;j z8c1bsk1pfvrj-buG>oxK|L--6t8SkK4x;;!F9{tmIqU+FigIY*J4x(rI*Dq?d0 z>RTpYVu+Vn^6(>9%+|+DI^i}o%1giM|I;kV7nk`zrqtQ-@Wt}mXTyGo_$f`obiR!^ zqglN4Ypina^cpe{c~D}yTp|ESky*M^!uys=90J56~rIJ z94SJvr35F9wqyhNRQMUp;*J^N=zmvt=oj757>G!yfMJbtWKa=Usc!sXrQ+KV)9O`B zC%!vKd(kwMo9m7C=VTdOMdD5?PdpcaLh1_dN9Uy4*)|^%XFTdw>TZs(&3Ah^UV6sL zefrjRDoaeCTSSZ)X;bki>fj=)h2~VDBHp~hJDu=Aj|}d)o6QmsD2CiiEK5#f8ftRuVgA<^gkD@V9OdPV3p*faZ1lBz1pVqv` z-R{6$GO*C1z=hsIk|NV(He7DjA2raz9!nt_ACfJ>LP_qe_z=VT^I4Z=c96?$+Wv{` z7*CNMD_+Jw(q%i>BUt4J3kGG8brboD%WWsfcjqn0Z_X#Kd7ZpgG8$+~B^W`%dU!L4 zt5~*p$>4rTJ)*lMGY^1sg3n5*hPoMut?fZ$u*Qz~@rpDo&m`rH18&v$rvZu!hV|T8 z=&ZlSzy9vXbOwr9PD7_lf(MK=|NB_3^IHRyZWd`Vb)Y@WW{G*$Q#B+?xWxw?JMg0T zEcZ@xjuG{h+@feF3Tf7P;;E+^Ho!*gh1ZK0ZLc0u3K5u*4Kvm`xb63Es0^N95q_VX zjS~CELz0ju^ria0dz}iq{T~>-!0$_2z>UVIpQ<4#}LovV4 zF~-F*wn^tu@NO3M#T*S&7^Vbj;!Cnb>z|q{^3Io+WxA(=&8HXbC#_*O$a@5tvEW6{ zcasRqn}D)F2!xr~>p+a$g?)MJZo7aN9SOeYHGbDLq4mTT*el6NofrYE<>S_6UPr<~ zM-dy_5IxDbm+I31p`kA!pj;y>s(>Iv|Ac7sg|N8hOtdKrzV(pz!mG2^;Bhwl zzw@5|C&Fjd<6i~xt@YSV|GZ1}>4Ep1$HFhRZ{eSmI>({C)9@9LW!%zW(BQ@p;xtF7 z&7GkU+<5G^Vz?qrzZV}xVV`%f`1$Y%(F$F`9La<rRP5}?S5FFhH9chI`D484L1g<1*bywy#`B$vXCFQ^>w1A(WlTzMEt>_I)2@UuGD~7_;WS_ecY7aU-sbTr?;w8 zk=9$Yie?7IJO`jqBOe>5?V_oAAX)#f=+TaDz{TNU8JaRpt(|UpbqrTIj~_E{Il2XInwxyU z9s(8IJokTnED3;{kQ=hW16avvDVD+ah-;)hsVw9fMqB~{YHJmrZ)wqFcKT6%0*^{D zFs6wl#4)|?t11?K%2D(F$d>NB|4ROyU> zjS@p!glk99oAm;eW3M|7slr7Np^K@vF49_Sg3)#@RRdoULxW}fp({^08m{wqZ}z9I z`8uP0-T10KOw5}|l1=en-=WTYB>KhLy(hG*mP@vk&Y0kAScLRWRPC2H(kRF>%DMX? zAwR2Udro6u@lMq1x@orW z%ECVlVt;<;B5!*PkI|+>L!e1<`__J|s_3WQ+ME}uKK+YB%YqR@b1}A}XGu9wc3Tv2 ztfQX%G~u9L9KO*p#tL}V@YB9u9u%tMZd+AZ-rTok{PR4i$5}5PTNk+h+~(Bxb;`ef z>RS~YyYii(M5q)KDT^8KAeGk-XS0SMG|1B7)?b_djNZPs?|xlduNNDe*A~y5p4V{Y zFm(d(Ta|#S8`{`4C%)}Ww5C#Pjeo{6ZXiVl*EYW>WmXVW-2Za0O-&8JT171f7i%kq z6Q~Cp*Xz0A))QSiMxJ+VNBFv--<`GT)7Ptuv)cyis5HxO0A~F=wq0BY{%86pCcpPe z+Tks1dig+jX+x^Bvvc*XlSOUgRQ~Pg7S(SNX7Tx7W=e2zbD&|*g3rgw&^ z_LxQ82s)i;xwJcVqCUy;OBQdvU%y)5tlhw-Q6Uw#EA3%4gM|Ft^-Zs8%3q*nbk(;I zvvDN^eW*>m9kQjxLxIcB~ zK@N-T$pxq*X8NQ0Y3DlF$KL zTwP;`c`l9L2*_yf5)id~Lh;DCo9rrjWp=wRH2uQ3o;Nz^HH|ogFnYr(Y5KGof9glh zEE7y(QY>hDRx)0ab{CGvn(IUfch=LO6}|V-ti)tZRbF zHx-19d_Rj-1R#u=hSPg`iG+Z-)<_aNGC40pR$qmnquH+q&nL0ESegsXHv0%rft!HR zF!gjhLsI@m4E8M;E@{(8T2CMgr;uJl4Hi5m1fW_=0_HWt7oSXDMfx;d8ufbmtZloa zJ=*SQvHLCqYq=;kyWAvwz5vW3s;JHg+NR0U24Mf1Gzirm{FIY&Hg84`u&}Yvf5LCA z9}@30vJrSx{o>VnOTxp=uC{u*UjMVW+N%pfv^TUqZGwhM4ef+VT&|GB z)HC8MrG5Q=2$vtEHWZuk+A^!SCEl=eNK(5P6zp&=>&`ND*4g^biGoe#No$JkYriSH&AnoBUQy>!9Fl#TF`LX>My9;sY-dS8aSDDurwer3t+%{+VU zZTSwq8%&+S`P!Ce^cAi>3A6bAFDt;dZkq=?mNLFwfMcENWDg(U?pqM0^4$F;Jt$nw z3^bwVYB;8i|5e4uOa%d|>TaG`ezpbop{2ZoG_4J}Qy06|@EC0ZbN;kwmULZjXZ7G! z+p$my$JHyf_E_+qI_fo5M)qR?SYXchv3ert}UEp6)WUiphb+EUGSo7*7((|@Plwsi-DVYxCp}jT!R1}fI@)w{8 zdu$JEO#qFQo>=3goIu#A;wnVuP~ld)#N$?3*ZM9TH5Is$)wf+Lw6;qHijKJqTxDBV z)TEn1H8|syf7Kah#i)X%47R9PMGW;fP>g8;4*hO*ccBwNIp|50>~`Dr+M>uIfZFTC zFRA36LUr-14aLGRZ2PL%DWn+JcBRbygz50Ba`gM`@+m}2pI;Iu8JmDo z7nqOH=4d=Riguh0b{*|0mr#J!z6&V9z`DwUN#EjHm|fJh>9gYcGlSJqIe*(J8ZWyzdoX9B3S_&j*%z@gk5Puowsr~2@;47Jjv8308v2NQjr zd1xBHAHeA~H|WfP6Xle}x*RmCG{$x(P7>kJScZiMsN$$)MuWty3KliH_E>HPBH2nm z3H8{b07)+`BTX9J}+srAFl! zyX-o_(iM!|34Fl0zz1AybW`|@?Oh1rh29{7fMwv)6>{q^7*r*-Nd}W<-U<%nvaFh) z71bQjI>Hwwo`0v@;F4d<)9y>*yVK(>T@mNg5)(eWmR_rtAL>$-ihLurQE4{x6*^Al z2q1oWY{zKM7{sXXG%IQGP>_+{4AoVn9;2XDI_M~R4#|}^IeNm!H&`diXPA{ooKfz|o z%SkUqAD@@Kxu3N%ANgE@T)Wh{2A{6V6JJ!9J2roZ{@Gb}8%`q^YazIgqv(}B;MLAq z5L7q0o9&XhgXM6;f#lq;^y+X!_~*y^za{(C*Sqq+jWzN<5P9WGf79mtc`(ww4Mw^~ zS)Y$5OMRjc3!x?8y}S+c}Gaz_rk5Nz&tKPNov!b2vL z0fMs56}D=Jbq<`wSSIP^Xw=NDm9<#ODM8}Winiz5Wa5{Ee6L)uIxo(=UW52lhxW-L zMHqG>$(Z+&;(F3R?upZOQ1AU1tzh$&y9`%BJidc?@Mm4`Ka(gQ)_PB#Y4*;0oyobr zt<1UHl9%I`?f2lP%)s8aQhp1)+6In1<=mtrkrFY^RSO8n7+AaJXzd+S%(~*WV>^Rv zIX8er^|+`xA>`rn#^497z|X<8{^X>Cn|5q36hfF3!v=thW97XHAtP}|uV9Gp$ME2)VgCh{(aaon<^`23fKgImLv5IC89zY+_s^LtV z+W(v;uJMJUUh(18+135xHNR~Tn$mY3((^a_zPiFuS9thXL~wTFq**AKcQMoZ&~%Sp z$9721#*pfwLi)wZaBoVMde9;Bm8{v8&xM}a|Ifwk>UWGm-V}PnPMaa%=UksQYNnZ_ zxZy{9{G&p~qg@>$s|#L@3f7$$RPPcuU)KLBjmK(SI(CAK*kRRwAfTv3))U89f7vCG z?h`PiKYS~c6ZYV=)!~i=#V08V`yIYiUsztXynQ(7cn8nNss6s(eYewX;;eSvVy|@^ ztB)AWdY5kSdG@q5rTfPa-5v$qSC5tEc0q6Ky2!itW>|J5Q%Ek5$VfgCJmi-ZoF%5O z!EoE4vN~;I*}VlJK1Xh1NrXJYVG-i<<(P??9{m6}YGl-lhjxOMyZ+E$ahY2g_(ok+ zywM@cC0BjJQn!__=b~IB{M3o31a12@EllxOzmmtRO;LP9o}~<(!*W zpJPPwC2k!_?HBZWP4;N^w|gdQ!?jz51%GdiZQKN4z{d1g`iYx0o}UXtL&5%20@#1b zdZ2b7kYP#(f|tT2x7O=eu^q4iimjiW1tRVzF;?H+%wuveaA)bPO}%e=9bMrimVSfyk9JQ4 zpHah-v=tV+ByE2&tNS$%0zkwvBxIaKL1>PGb+#8L${U&OkN*J%!tpMm99|l}Ga3_T z_eQXqux8bGE)E{CUA9b$acpD5=gzRy>Eox+$fR=BWzco3Vw8W-s8PGl=k#Z-hk9i}` z|I>-x7PkX!&hiR!nM5|V@PegCDpH%STtehy0%EZ$(Ant~A+fUWN67xR@BUYD+t>$qGAH(aI1HL|{2 zEf;ivA(kz6)Ds{B>0ij8L{@9=OOss~c^s))uVx&&s9Inya-Dkx1zY4Bi>%1_#wU7n z+f;sAP0w_Bof@ahynj45_Pe-gI`924v6(?<9-Y?g#h%KJ}} zcYWl(FI{2Tg*{GlnC5^{XPE8$bLU{-GcV2fO!rW2MeRxSlfL-RyuznZbBH-dT-J=3 zZV6B6_#4+s6cj;!Y~v<)XG3Nv)CgcVEt!)htPW-ck68SV&IWGeA}zVX^~@x$@?Bvefe% zu7-x7*KZ|KuC6qAy5oYPiXkUlJT}-heQurJHO|9E@cxTHK$4{^v=6FHF~+6kcYC0T zmABB%ES@m^p!=Cjn$ok-4{{(RBk8$@uMTE{r8j4@n+)GSPZv=Un%qrwqs!nG3YU5k zT6yZo1cL)CVzG6~wEQDq{k$mkeTE{z23KmT+^%HRr~7d_*x*6!`_yNZ)K`*r)-s13 zW1`J6zX`0a$4ts?jguE3ZQd3RBMCmdy+O=_GE!rAzy4fO@CeE$(1zL@ooKhZ0X{dwjKBr)kF z>t-|3+{#CISg|4g*mLdY&T#~H8bQ5NyA`6Q_(=5;vB7b5yrZ$tI!v7!hq(AkwG|TE zL?lOY8z*T*+#)louuoopIISh4#HN+ZAz&H_Hxqevwfcip+x4Di(FRc?KYA;U;~N_J z2@w0fXt#SC&;wH*tKUl2`)A;|nERJ>Tf(QI$+s?kk6?S~oM{3S7>yeY-ye40LvvH7 zyT~ed!V;}{sRp8|65Qd{VjUESqa@cWvFoZ z8Eiwn0A^RmdZa!2?77uc)T8iYp!MgpyX-^S3V`v11ij0SJ#sCcREz6=pCgsal4!f; z5;I9Yl6Xl06c%`W%`<7pWS;W;HYi{5++oVEK;OThklLLrQF5^4BAb?5(m__R(7HeO zj^;hh167H;fvl$yif;&t%ZJJFWOls_;ER7Kult-H@5RB`;p*zFm79}NpWpoMgB8@9 z?{RRK-R{B{YNj{73K)2~th(%G`}unzJ(ZpFna;BVr2wOm6UHv}-iA!t)SJ8yYUhoN(0*}PB(yhPA; zMAvcR|EVnUeYeaNYad0JVI`Zpoo0qQBDCfhh1QL6L3SPRZuYTN__F1yWa0i_62ah7 z+U)$ML~#Ef62Xb;4wTD}==I2S9d`Q~CJO2~!<@ogKRprIyrHOEQ4;s} zNbY!@rMUW$N_7s(Gk;%_Br%!|9c2$C$6@0nJ`vidAi#}7R-x(1j@lJ{C#JZ32OvAE zLytUf5A|8~dM@^!Yukp@%zrPW2GT$|p^1kaO?Wfcj(Fm<6a}|waUQBwV0(BosqsGV zlfqwkt-m#^wPCaBHL_(;lPf;4<7@iIo=lDFwg?V%Kl{}yp7SxyB=T~m{~NjB%nUmvQ3<^s z;ecYzU9+344JbrfM|tos=r&X&P{UD3@}LTd~^m;}mOF$5kz0AvK&)ZffB zda8ub1(XuES~m20&}E!6TzV`9w-J)topLwsbo7Jdp24@E4su8IJo^RYL@-W={%&p> z$Z&m<%x*(z;gI@ps&xV_-RX{Rfdvz$M08O=aBs}1K7q{mCFrmSw{CSP;olu9O>>?s zQEvbv&!T&r?xti87Gs`~&=P}W&lTx!$LN%HYBX``=bSw!aPFRnT)rcy*B11TI{xTY zd+Cb8`*Ztrtw(Ht_IA-s&=_cM-?p_kdU2XRp3?dawNtQ%-ypZ7H>YQb`ZxpuzLE7F z-RjV>K|-VM4w6IBtmZ+8ay=Ly>5vB9B~>t4X!OeKe~Qd=eA&Rz$9%?uAJoPi+d*ZZ z@Q6luL&RFNH<(jJSfX9mTRu6mm%Ec4C*N3?o5cF7e5xyO-ejte{=H1~E^TeVdOhncGYY_beent|RQ&Rr=Fo%ctrtzU6`s7f$8lks^7RJ^U25HvQ%+LSxdLy} zzV6Ay?^k60$W> z`elZ>o@UN3IMJEjuCN6saKGWiNyyUl6uV82n>J`fYc1kXq=vO!rfUWvDAsxr;F0Ln)TZ7| zkf%0KsDju6d6$*{PLSt{E)Izp;zvwi2Cvi#xDhmoF}yOh3iSUdX*MnYxupH%HzcHY zpzBs=U{|lrCa>H0d*BxDoEdEuYE^ZTrT_Nbl_`Y#tXf2i*-vei zi!bR&hi)uu?cIiK#rj}nm-wJ~2k%c%!@PoPx!ZtbkafV;*`%E3`gEyl4Tqqqp5!PO z&mb#V%C3Yjsw`jUS-rA;n#Iyy1{(Q1{K-vm?I~-|%=W-7@$Z}JjOkXC!AnLwmZK;Y zY%OjntM5^6ey+`PQYy30`Ruzt^M{Tr{p$Y{em8ly208~H{T}FCuTDcyawQxoD|*Sz zlzKVnq**glpE)3?wdB7>Ft|;6ET-?s^Xv{qxaup;5s^Yb)#6U9TM`=>?M&lPkM^7) z)LJGBe`k3ZA9k8$Y-iY1E3H@Jn+Q@7y9OEg@VId**=Pe$+srNnd;)SZWPfHYKzN(l$U46Kz>Nte`R(0B#7z|)_ z2Do&h*c@t2!)&Np%z!VuV<$)$lHC8CFoP7)H<<4Y2cCh=*uC4Y{T;t)^?&jd{GZ1N zDT8t7)0H!3hPJLe?Y)sx?2ZwrQZnvZr59&6j#GpLG@^;d@)jUPFjcrG}TDBcv-n0thu1EGvTO6 zUcVkt;0(f*(crPddp?ux^w4G&X7d-;I5O1{Hb?Vv45^nUyzgv`fzyl=4HE_1%H6O=bn{G|1cnyK1{z?mI#o6c4g3RteYyVN(Wa( zXV9EVN}||wmQDLb@<;d0H=354C>tf-cclkUWC$X;yQ3vJOVkdOUFh6&g=od(z5mKMZi zDX?ViTGCM5r~o}9rrHLc|@f@JJ4U{LZ`*EN`SOO zkQQRI&CeC+WrUfNc`e98He078Fx#xztXFd zKjr;lcmSCeAFZsM?;urW3I4+;LegXSzwdr?iI&f5My4~ZhkyF`KOP|_op~vcepO_D zx9^#sGHUvY4VR)~)ngbE)@^$9?S=3)(2|l^6-3*FEe^Urz`4zRPWU zxpE4E+vPCcG)yIX6Gar){zef`e0WYfH%60dh|>GZ)-#pRYi7}Q1QsksIPt2Q@EPfu zUd6v)*nReCRTisY$x*Q{u$GZ1{q+t>D0xZ=knG2ced}R1uqPQPnpuy-wA(X?Q!HRv znqBG83#%i52K5Qpc~TvR`qD#Xp%{9p(RkNUvEfLPmWP?3IL-m#)Lypy`h&FB{&90; zf0azxr0Dfsr@F?m{oAs)!CH>yueSjHes{v_W2$UrV;(aQ#DM!otv$>p5RY%`8EPsU zZ-UNo1l~(5oay!#$YM3Ar%u2xKgoKu)xkplNHrxyLrdBx7-=_ja;k;!wH3IoI6nN( z8tebg%v0sHDbq>k5f*eJg+3Io7)~`yl@P`v?0WBmru9{dHNVpGG}!0c%&JkN&8*s? zd14o+iK+Q>)zmPp8g8_lM=3+>nZ2hC?|tNUk#Bbl-=CcDFM- z4`y-YCtT10cAk(u0-{@5s(()4O~QX^ET8s*S{du3f% zDLEg4g+NH*utB>3*pe1nhV0LD=$e&I@~!_TqEnE$z5rQ2i(7y!2BpVg5DQ*}Vn{i> zWTAOb`iHJ|gW`qUqQ^?U@;cc7{c#`Ewd~z=T(Oz_2Ix-JWhL`P7O-jHQ0N(q1ELFKbbC&pp z^`+zyl^6DbxR`xiJu+L!2R`eOHM>LBmxl5C=R1U(Z$OKZTzP^MpD5X=DtE0eh_+#e zS&@YfdJwGM4M8cBDdMH(N;l}E_da>z2@Jof)t9G5H=EO`J(_M-TS&d>$lrz3Uyo_K z^;@B9PdnIk*CB^snuJ71QGx3~(~vX^+y3B2qcioEh^)s-*Z+(btrTx|%{P!xOhwce zLO+eg%`p^}5JzUvkgTa?A(Uil^ehmpO5bx@^;iO z1@A)Q5K~;Zb{+uM*RT=EK=$T91O2<+;)Ei~Rmnxz|l48T+6NXyW zs~zO0Y&Z$~@4u_JlWSV`#w~upfYk*OZx(DSN23=%k6CQ%tKcJhe~Y>CX9-~jiAG3~ z*#{*vi$7h#6reo9TsP7%ku^Sht8b*XxtZ05Kk&~s1_mwVlexX$l(_LayQ7Uk0pv5H zJ^*!94(2^OYb~KeT2s` zk&$##@647p_}lVVXXU7`3rZ3o>A1`e6Q~B%!CyH2)|vkqr~BBkdyFta$1DU(DsjAt zh3~EB1yxBu7z-ff`D%iKwdZs)WF=^I+L`{Zg=SkhOz>xY> z_+arC{Ch{k1lcw|=KMXjt;dq6BnQ;>)ef;z)X?%rVnI$R8lzGSBk195!PlrvVEYG- zSoV3Gi;{c7xC(@ptx0>Q_|Xqtj`bhiPg8|)A2Uv{mNIgT1Ya(hbX6^?gf4if-Wi<& zt|90Y26DCV&O|eFaO=QT!Cd`Mydcw#Xn3asi||t`kZHXw=N(@h}^Tz6P2Xep6^*kut|FpIFk^M{-df48YP>6r{*{T-S>L|KV!HSU=f zFdJvZYRs=}`C5DN?WKuL?Q377f$K9^#LFFMxi`Q9%chpwdiL-i-_iQ*)Zg53*_3jh zVbBEh`eUJz#|)8pRQFIsMGUFB65Y<;LS(y@7xL1NuNq$E*p9iVv~yeHxE}FiH=i`~ z=^IVEfRWPY997$;+QBr+lcdMeUB_NyAuX7RVUOh)SFDn15yRm9rFXr#TsOQ`c3sYu zp*r=9PTFr_`$M#R<@sB-ebc{5;1x%Ouwx(Lq8ZA*K50e4#=Ts};KQ}<mV< z+eQozlWu8rTjMHi4oWJ(sd_J`bJ!n;*=8n6iQ$F^Kho9&2@*R7!IicqrXW;DET3u4+C)5`2WZxTb5IFnSk^jGTm;P5? zOB=T&e?uF}C_lO0eIhCP{K@4wk#~bVBrH!MOzL&%^((wgAc}Fe6+IyRr2dTJT8{3* zku zPQQ9ybT&UNT4JL}doYL&!%qBIUZkY)nlS=3HCPlYIhI+9SiL~>AT~UjEz%|(vfEW8 zZFmZhQjpVg_PK`0>2?B5?zd@Tr-OyT#df3 zDO-K{5_ zdsYn?>4MDZL#6IYEaX-;eiE5F1?zE#^pvkTV9I*(x}mV1a%~KnyQvIkXyM*t=8h|R z*c>@TamG!krnyY9K*+eM3k+$tUH*9<#&P@PWLs-xgj29Od*AHx{xq#!BfinPgI(9yUHHA1KO zpPwz;uP>8)>2pVrkSxLl@hZUPgm(VQjA!!OH@b9veQQjYII_53e%Y=5iHj-HDl)4X z*92MaL&g%DVbAdm40)842?&7>Q$k#l#^pt*4wLFN9ONomOmB*u@$%cRod3f-jH`fC z>uKA=s+;=R-35x!-Pt?%p2pjCg^P+-_eibvPuzly&_>|M+&^PedpPvn5`-ix0yS~=a{=YHn8Ptu&{d`OIr4jvZ|xKRJG+YqgM5o zWE|h~eQ^yhROHJKlV(Z#rD{y{``VLO;!hrV%4Tdfpk3!%^>J4)v#d?Hrg6SW4F?M9 z@l!~jybK#P6U3B|;_hi3EvFpCAczE^fFyF8-YNnm&3B*6|6S87(~$?1z#(IPOKlxn zrF&nQ58ggi#Z^MNKQ#E_!V8~|9M8ddJ64O8FZm(gkymjB!|T0nce+ZGPy9OL-$!nL zb+MbFyx0v5b0J~TJPQ=(vV@HIV^bCUOb>dFQ4S?>o_lrtdf1v$vfV+K8+pE3bc?Ko z@zl%gbKJuioODe}YXb+$ny?-fK|wJq>BzuLkQ@pM@A0BwZ`^r8}0k5$ODRq`eU$`JUzI7l1Mi}r|!@@n5ld9to1bHcY zyegU4^NH-;G3gz(yXi&UHSVi@`(w4j2ZJ?Je!X1J4L#E*#pKLm7_UA?3Jmkf+#+OhjhoaI|ZHPhnVg#h5lyr2Jl8}Bp ze1y`+4)0V!|8bwWdcMvc)#tCoX8$Tuxcou0W zeihP14gsGWg%Oer%dUTMK}`@S(xZ7=^mD!0VXL;8D#tFD%3O*%wQAIFPv`J%;JfF* z3xCAp-fw~r!k#c|1@mzm4ZKn>%0J)lworG!gq(U5Gh3DMKDoDz*-b|3=bf6BF2nQ& zM={C1HvF-iCV5S!koe)W?_6*AXvNv^GAn5~{`KP#HYQ53hF(waBs&B~TS3l>9I-fZ zNB3~G&OPD2@^N>JK6%6%UxZ}e$Ur#ZM_l`1)|9mpxFBj3=7FD3C5^~;zWu=SjQKL{ zQ)Wa}{e7pj?D6m~iUKEnuX-to&d0)TGT)GEqMt|=uzFstjd6EyCb1eKN-+fp8|M}= z@C&Ijh=Pns{3`N~;<0_PkE6d2NRzNnX6XzKhRJae6jIejEO?0Lvg-R${i%aCqNUhR zv*DwEoVf#;pn_j3D2YuHr_$V4zOhd zt!2UgeA!2e*qo*^kQ3mE3OowpD|;4lWqcsYdrYU6~5ssF~bI z;(&O0ta|Kb|9L6Xa;Ae`{oua5L)keC{KmJ9ly@r7$6r;NU9v=A#N0Np7?OW%iQ7D~ z{JD514mL)Lpv;$0mXJwO7V89@gw}EuwRC6xnd-=G{;fM=s(zT-- zHClS);!*x*uq)*o@!ApEkTvY*StZEn`|h530asvi8)*bw7cw?*eTDK9e^DqMrs@R0 zC4aKNadBVGxQ~K^^&I>_gX`>Zf)6x|!@KK)pn{1odslkJQ6X)NjPCIx4XbcZDA=V{ zo9%!LV#s4kQ7t=`lY(=fPgGZdjJT&X`$s;AWztE0)~(t9(AVqCo)nxBDD{c2QmYip z;rQ$VA=Ii6Yz?an=^#I*h|LI<5}W#BNqTSt@;JnWGLa;mK`i;6J;4pdrKyyrv1Wz! zjVFttKBJ$r7Pbx)vXF!=AF!k=UiRZtU^<#*RgtVeaO|%s`L*BNk@C`Z_@9VnGa=Nv zg(0~`MwLv5*IrWy-m3JS9%`1^Ot;f66mg~8d%uU{&{(kFh8bh8G)laO#0+`*Hd<_%M9rv3^aMfV<1t)U$EjHy!icJsa<& zE1WUEdCW|~?=j&ZWVHy1SZ;C0VoS=&IehDgr4URRQJXRVFCx~p@RGgE!^Q;aH>=de zR;RBj`9F02M3w543p)w&r}a^VPmvHYH@RkrpTGVwbDzDnsdr7J;u{)YgbQQBNYU7& zUB_M?nO20$-HMtKp5ovu)0Q)BmGC3>=wZK&8BFkg)n=|)@sU}mlh5nkC-J_qAba=C z>qe)bA8>|RH~Ws<*L6D48uvbDG)!0jA2>+SX^}S7Bz;E>2uz@hP`*mOC10{)dNVFa z$YTo2PKs$U@Sup5W!%#_eUH?I!1YfE5f@n_5bMxkeoBhwYIvB`Y?WdLE(k<`9eI21 z5W_x}_SONJ&Caal+8wd?FYnDBmdJz@YYLCY47LO|WF|-%*N&!mYanG~H|CMCM@a7M z<-|w|0og-?cQdU9*#3L*r$f>8_dg{4(VlOUqn7g{19z*bhrCS7&mH9#9aW~07xcL- zS2ga%?JO1FUdTC7RjR!PZHPUhwoCC#RLJ97QT4pe_8>$<7c*ZE&p7yijCe@R2m>!+ zgWv`usZ^cU%_hd>VFG){7=ISdmF}{2R?B}A#ynnh!uBewVamiB=DFgzO>!0RW(T!h z?>x?N&g$w293 zb)L?DR#1x6;u-Gp>us>K?ToVCg9Grv$*}u`?|QNA22Cq+F8^XdY**ai3R>`F;Py{j94k=f1(l zD^~r|@`(R@GD4E)1d{`Xu=9^HlWcKW+%T10=#sdMAkJ6y$4WAn}#qs2rmO`Z`nY{k?- zRImOHgriI#6|vIzGBQ@3Sv9nbw(QeX3wsb{ji)O@;hU@t$-Nk-IqZ^90VRqPHX9)r zfpN!&q?Av|qY8;50cAGMt^|heg>YyU;8ewodXdWhF3SgJ4;8$mFY|M4W3PPcP?0Lz zksPck%s9a8+mNT+HfbTB-@mFI?WE1~%s{r)g z)DOp24R;Hk)jZKUQ^yhyDT7qh7W(q*ZLG*>-jd09J#R_a9~tx@OsFPlLJ!<|LfdG&rM(qjh?T>Eqo-f2sKUgZK|7)iM-a<=s!Wy)FTHcySsqgxGb z$XltH^%^lD%A_=*dm?t@%Gx_k`VKQgauY3zPzi^4O!Ghx#42#*@NKH)f|NOO`$W!f*5_G<017sq-|Yh$z*g#~{$giDnj z?g~_!J0merE@R5s%^8?`#wX`Xza_FVnE^IU9|0$}>P5iG!3BmMsB&UBoFpHCT5D@D z7}mzqMqQDm5K#D$2?U8BVuJ@y4ZQj`}O-ueP z{pa|ngo(hk$%NiFV!PKv64yX4xg%pF05Zpr=kYK<0Xe0*k9Q~6`obZr#M(~*$t#9T zkvB0b4JRV4Xwnz8{P!bsXdk=WKQG{}`PD!F!SDK&j9JY+LCa#GIAyyN5Z>64^ScW*^uuvE}4;cWP z?V6~Ck-H|E3Lpkj6i@AlSkeS55Hs+3$SG7a|G7*P)cBJs=N;TmcM1=`$PM43*YUK6 zf{hUGb|oQ@4wf^vVfP)|WfrBl3rR_Ya z3ILLa>n_)zx~j@7A#oxPiGCs*%4~i)UtAL`2Ngs$Tkrn@60xz#*=5@?sHfIVu?Ni zv#x9nks`h%*J_G3M@s${t$qtCTN>7s;|Pz(s2?(x1S?;kSn7;0B#$PcI`E%Uzm+O}q!)mzB^GudyBQ(gN0B@cf`gDr5 z|L*Pj1Ryw}-`cRPsK7O3P4#y0yM=Mg$oS3#YcemZH=VQ>g_c&)({S0M6r zHdlJ?nUy3W=vwVJoP43s(!E{9^^xuFiW@6rary`5fW_K@X0hLkVRn|A^ zO<1=)c^pNDT1HRcNT7m(K4A?hU+4iBzCkG4A-eCs$e7y)vEDWLokwc5W`d3~OeYA# zA7w8kLcrT@J+Qp8Sh`*mM(O${$U2k9ek{t;vyD&bnL=u3e1+HRLgPwuB)>6@W@o8d zW`FxzIJH2XDgu3kF@)peINnR~XK?7ze{}YsXDa>&t+*4$+wfj|(8|I?E=fJ-&*ccb zU@C72vOim6ufX>npKN+iJR%5xKmUxEyzkG<aTc8S5td)kdMg+ZjHO36L$s>KbvW~f9pq+lFw$tLnkBd3Os@*hm_CzCpgPb1cedE~Amizbx z>g+_usS*Wp;Wr(=^JC-1)AMX7eTGvnl)gs;0!$Gr%+IQr(cj@_& zO(gi?R2yfDyynS>FP}c(8ptYmjh#L>yzT95EuV;-;0kD#*DPYKacGq&Q(@e0YG3Gu z6P51iG|FGGXf5*n&5fcXZU{0ognw&)bzSV%A+t*Uyg@RXiUOdcPJC9%b*I$?zCMl` zcu4!rd#_Qe=&V9MXlsNodAFPnps>#WY#iK#ifbI9Wq(LL8@~oT+jhQ)E`?g~kr0O}h=zitoFN+VIs{Pr5Vn zI9V$KbSvE<_?k!s*V)U>S0H;Kt2TmR(J|0$+xu$@H!w%;>3(~6e}-G`^0ry%yFdDW=Au8pW5t6FPF0hMF5)1`j6%4^nrg{IWkxJF+`jC)n4C@ zep*0mM-<4+g`fMGsFyD;Lt~o8Z8m&XmdBb?2jFJKV&C3PjV16=vv}`Z^~buB*71906brkSTXl}qbuLvx2A>49qIzodNCJ%XHZ|b z`7gGJ;LaH{=D(ov$7o`C{eGIi3{Z3bzxJ+#oyv6$lQNXOgihO zMuSor6BVLNiO5tbYnd}ec7-A=mavQ!Wmr+B3}GA2`+eWyw6ANQE3I>!)7iei@Lc!% zKKFCq_w&BQ(F#7JN)4#74G8V+75)<^HX02lz{BD|3s>`=Kv^E$?%zcu!K4@_CE2pX z_(Kxs>f6?ICBw;jCKHL;Tn-s?hu3=Ot-L(Ug-;1kxkFsoVq%sHXGzC@g${46*$QX; ziWiVK*S;}Y9%#Ggh1TgzQz<#^cH$SmaLNx%TzWNGo zPz^&$pnvz=)faiC1mLgkc^++g3@d#3jRe2Yhdc@2I^9vYdKRUVHds)-H!;omuz40= z?|HL;tnqm-xW)(BI&Mmt7C_ZLdT5_d)$vXEUj=)^2fYRW_C_2$XoX7QOHqfra&0zf zpd7mN-ArxzxduWkZt2>ufe6uD5vdHDVp;2`JII0@!-5NPYF4IJ9Yc3k1JjG@v!mQO zaQVf2clq5Z%{6ga1zHL&=LjaxPU-sIi~63*ws!l0ydWr8Z=rOr$4L@mq;4=H^=j>_ zwsOG(YSM2Q%ns=2U2@Y+OjnQ>e`p<6Q=?(nW8<&ZW!mJ$%PnzJK8p0d2@%^ks6Vv> z0>V~1M?ey;gwh%8#vVD#uxAZ?a8=&~e?a7Y(o zEt6XMu0SOd|WE%Hwhoyd)`~DLx5?bSlf34x%OOd=++_F`&hlGv3G)@9AHoQx$|%I@(A|q zJJiDfn|b=CW^fE?yBe2FYC!cIY#&!4mXoOW(rDz`TYGzQrgQs%-#{}+4cvIXUt+wx4&3-gNTCIeoFW*fLxPO`fyvcS2C>1f zFdJm>c={)u{C7unWRkpJ^!3Y&h!{id-8_ca`(kW!j)i@Ut2LeFZe!aI4ol+#A)S2B zoKF61zc_@xyvly_iBTARjWQF5vLQB@O7!fd8LJZ``q8-MpW@3bd*doL>H!O|ucdMK zWZ-~{;kCDcK=R9o&Tw5Fc7h{$(G{?YH2_SZdWVNNuVi8%(xP&6S<-c~NaRWto1Y-3 zyG>X|3+QrYA$ksQ`HXLBE3+edssDoOrPuK}_}2()rmpWi_i0Z~k-~Qan`Gdr?4FHa zcr|c%&gn>WTLq*Xs!KI>G5mX(wKS7oxv3IAAIG~|UK*birdEqv`utsd-kkka3FP1>h{V zYTdlsrfH9|0%4lC9AYf14b~%V*s@&pr_VaA-!8Rj90M61~TE77W7_23?6 z0RfZ-JwxwO!4ZzyN-@Be`|9&N0r2GerL3mlw()Uo66VlxX<3(*j*W~kTjnar59frD z*C(X#1q%)?jaBOg;I|tth~NGT_ub7?8EJnA^v76jW1WbUu@t@x%O(%Dr~5$`RW5hC z2hWQ~C$alDt&Ms>xbKbN$E>w=TqkMP$c=|p+=Ok|@pG>t0cqZ(Gw2PBan*$}#(!DT z9Jle^ppcG3{>7oah5g9Di_Mv}_vi+&rZ`r^P{&XJzw-6MM8v}GOdJkH`fir*;vF}R z>PLcM<4sAV3^oygom(7h`;&A&1aU9b`*9&n9X3YC)CS=@Pe;P_R5_v&$nE@Dm4K3n zqq( zbO!!8Db6bGE-PVaz`&a9|285F?@kJ7&+JU4<6V=5F zzX9I89squyqj)s0*)M@~)1aOp6n^u7-v(PB2!5%~_txgq!xR~(PtN0fK?XG9gSUb} z7j@Lq&W6PSb6Jt8-21ueU5*1}4|DyXPN zLM%DEptfk0C>FE*6(j==(?rg?p=9{Xzw~{|+u|U=HBFw2FrNin849=` z%I>EbF>U~GJOFT#TgiaihXU@$H{57j8vxws`^j^@A7%kpfdcNwfLo!|2DQ|X=&H^r z@(^+2&qD+{IQ&(JaLbJC)UhMqG~O$&KBKj=%uKFF4KWy%AM)1%;HB8?-{%bL#KB+u z)b|0Mc->UYU4#Y)3YRw{dI{&<#j2OAJnTN)NgcLQnb^1cq8aIIA1u@<@DPH`!K#b& z(I7oUHW73-4-N+FD+x>?@-Q(`#f#UIi3#=pCo!R$&P`R5`(K`K0eByVhH@~R>cj=0Hk(yN$3pIGV1jpLV(~FQAsfT zXAi45B379%dr2fYA>g@4A&BLD04&Bc>pgH~S`Y%K7Y_pe?SMcTSJ4M*qMq9tWn%k! zh18*OMtG{Ys1(Cj3@$&17rY5d@LZw!wTNE;%oV$N1d%0r-w5+$vPnj>NKLX3#&|GQ ztg;@|7du(hE*DE+Mo;a$Gi3*valn}USjwlAI)t@lI=4QhAYmus*1-x5%bi`f-?s79D>DO|9(zamjW&S>3jRc~a z)gKon@cR&i=)wW!GTJ z0WN4M2G<+DD>X9Eg7y8Xw*8UK`d}@D!7n=^FwrGC07T!n#KO_{wp{r?ZTD@mCNIQ@ zh!QXX-3Jr0hIPZ_nl0vb0IIt3E}VzgEZ?hBO~BiI!~NC#&dxhVd|Fecl^D@CF8M5 zq*1Kfu_znG+tA~n!&b|_a4vCQQ9peqnji$*JB4WRe!O4UA(*B#F&KX7YHK{nJe2fs z#93W?{TA+qakn6JyqItPSl!WeNA?$tB2$#uw*l9fGnzstp$ht<6`XGccRp5*%kOi1 za@KPwz$`G&!;CZ}44c~nZVJ1u0eic}Q$^byk*7MYs;L8c>b8<*ADl~BDN$@Jg=Fz) zb^aUAoc&r^JUlg5>df-zcS+Sl>1CNU6AA(eA!~rPqNGVB4ZW8WX#E;mNaPUL#3Fn- zq#*q@v_McpSH=ZL$@s0-o*=hhs>RrTTRx0|1lb;+7@x}9XT}r>+aIvXKm}Aq3pl^! zpN9BpPrDCt!wUAeIubikvgiX)35w~UByHRH#cPbv3I?_JtqEjzs%(XS0Lapcxd**P zRxm8CWmq98i{IiFVah^@tC=a0Ep->6_@TCYjINjfCy)wc-B9q&3w&k$yvlJVPoU;2 z0?12t!0E9kRipt_-kVnjenW2YI1TRVXV5#ada>3974$yf=ELxy0^ht8gRgR*zzVY& z=p1{)CKT?QsBZ^S)!8wW_sxs7Ni%J)Vu(t-Dg zikv<l+$M!m9yN<>p1oc_kG_dnQfHSpWX=e9D~8|b;iZLw{)huVy2-a&c+2TL z@Nt|V_&&vANR+_cEP6^b4SWvQ#3Qi|s0sMlPa+<-&gb`-lmf8kQN3&0=N&YE5PQ*L z{u{-_?g5=;IB3TFn>f*2-|3HED1S9I(;KOKvsj#7wg1xRu$Eg9w5&|rW?AJ87Bo^! z$=aK;nTa7frMyBd>}pnmqx8N@p--JHbEE}gnGSGDGqNU^9;|k5+*}c5QufpaH*AsK zesA-^5^LgH8=GbE8)}~&awIyg@)^+aQpPqydtF{Hmuq{ZJ-8h)f@5q{R4NL+)}>5m<9Ug(3om@V0#{w@?<>nIjy!Pr5_dW@=I;WQ*GeJz845G^Q9G{EcTP5VnwZ60`1SSTo zH*`1hsnBAl*>I?HXL3^7rVi26_MRfnG+#Td#A89By#f4EEUrscmw?|@agwG{!34TZ z7>;WU_3fgc6zs!0_oj3l+G^+`(RfBTT(mvY?&Q`iFP%`^*3Ef#ve$QA+*lZE@CAG> z!K`AjZ2fa1y<+B3^&lP1o*&47&g+Hq(_esO)FiFDSLRRcJ`N6vboo; zIcu3iYcs%Z^nRkyaX+r2Gx0pFzq#cz?-crbCDo5!Y4GN*v1AoxfIf-&Xs=1)Sr=m$ VGMPlY0<;Y(Ewz2BsXLE){R7a87A61y diff --git a/kat/nodemon.json b/kat/nodemon.json deleted file mode 100644 index 759d521c9d..0000000000 --- a/kat/nodemon.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "watch": ["src"], - "ext": ".ts,.js", - "ignore": [], - "exec": "ts-node ./src/app.ts" -} \ No newline at end of file diff --git a/kat/package.json b/kat/package.json deleted file mode 100644 index ade95df96b..0000000000 --- a/kat/package.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "name": "kaleido-asset-trail", - "version": "1.0.3", - "description": "Kaleido Asset Trail", - "main": "build/index.js", - "scripts": { - "start:dev": "nodemon", - "build": "rimraf ./build && tsc", - "start": "npm run build && node build/app.js", - "test_wc": "env DATA_DIRECTORY=$PWD/test-resources/sandbox/ethereum mocha --bail --timeout 25000 \"src/test/ethereum-suite.ts\" && env DATA_DIRECTORY=$PWD/test-resources/sandbox/corda mocha --bail --timeout 25000 \"src/test/corda-suite.ts\"", - "test": "nyc npm run test_wc" - }, - "keywords": [], - "author": "", - "license": "Apache-2.0", - "dependencies": { - "ajv": "^6.12.5", - "axios": "^0.21.1", - "body-parser": "^1.19.0", - "bs58": "^4.0.1", - "busboy": "^0.3.1", - "chokidar": "^3.4.3", - "express": "^4.17.1", - "form-data": "^3.0.0", - "ldapjs": "^2.2.3", - "mock-require": "^3.0.3", - "mongodb": "^3.6.3", - "nanoid": "^3.1.21", - "nedb": "git+https://github.com:hyperledger/nedb.git", - "nedb-promises": "^4.1.0", - "proxyquire": "^2.1.3", - "socket.io": "^2.3.0", - "socket.io-client": "^2.3.1", - "uuid": "^8.3.1", - "ws": "^7.4.5" - }, - "devDependencies": { - "@types/axios": "^0.14.0", - "@types/bs58": "^4.0.1", - "@types/busboy": "^0.2.3", - "@types/express": "^4.17.8", - "@types/ldapjs": "^1.0.9", - "@types/mocha": "^8.0.3", - "@types/mock-require": "^2.0.0", - "@types/mongodb": "^3.6.3", - "@types/node": "^14.11.5", - "@types/proxyquire": "^1.3.28", - "@types/rimraf": "^3.0.0", - "@types/sinon": "^9.0.10", - "@types/socket.io": "^2.1.11", - "@types/socket.io-client": "^1.4.34", - "@types/supertest": "^2.0.10", - "@types/uuid": "^8.3.0", - "@types/ws": "^7.2.7", - "mocha": "^8.4.0", - "nock": "^13.0.4", - "nodemon": "^2.0.4", - "nyc": "^15.1.0", - "rimraf": "^3.0.2", - "sinon": "^10.0.0", - "supertest": "^6.0.0", - "ts-node": "^9.0.0", - "ts-sinon": "^2.0.1", - "typescript": "^4.2.4" - }, - "nyc": { - "extension": [ - ".ts", - ".tsx" - ], - "exclude": [ - "coverage", - "test", - "dist", - "**/*.d.ts", - "src/test" - ], - "reporter": [ - "html", - "text-summary" - ], - "all": true, - "check-coverage": true, - "statements": 64, - "branches": 42, - "functions": 64, - "lines": 66 - }, - "mocha": { - "require": [ - "ts-node/register", - "source-map-support/register" - ] - } -} diff --git a/kat/src/app.ts b/kat/src/app.ts deleted file mode 100644 index 8cd1aa8e2c..0000000000 --- a/kat/src/app.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { start } from './index'; -import * as utils from './lib/utils'; - -const log = utils.getLogger('app.ts'); - -export const promise = start().catch(err => { - log.error(`Failed to start asset trail. ${err}`); -}); \ No newline at end of file diff --git a/kat/src/clients/api-gateway.ts b/kat/src/clients/api-gateway.ts deleted file mode 100644 index cb705d4e40..0000000000 --- a/kat/src/clients/api-gateway.ts +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { config } from '../lib/config'; -import { IAPIGatewayAsyncResponse, IAPIGatewaySyncResponse } from '../lib/interfaces'; -import * as ethereumGateway from './gateway-providers/ethereum'; -import * as cordaGateway from './gateway-providers/corda'; - -// Member APIs - -export const upsertMember = async (address: string, name: string, app2appDestination: string, - docExchangeDestination: string, sync: boolean): Promise => { - return ethereumGateway.upsertMember(address, name, app2appDestination, docExchangeDestination, sync); -}; - - -// Asset definition APIs - -export const createAssetDefinition = async (author: string, assetDefinitionHash: string, sync: boolean): - Promise => { - return ethereumGateway.createAssetDefinition(author, assetDefinitionHash, sync); -}; - - -// Payment definition APIs - -export const createDescribedPaymentDefinition = async (paymentDefinitionID: string, name: string, author: string, - descriptionSchemaHash: string, sync: boolean): Promise => { - return ethereumGateway.createDescribedPaymentDefinition(paymentDefinitionID, name, author, descriptionSchemaHash, sync); -}; - -export const createPaymentDefinition = async (paymentDefinitionID: string, name: string, author: string, sync: boolean): - Promise => { - return ethereumGateway.createPaymentDefinition(paymentDefinitionID, name, author, sync); -}; - - -// Asset instance APIs - -export const createDescribedAssetInstance = async (assetInstanceID: string, assetDefinitionID: string, author: string, - descriptionHash: string, contentHash: string, participants: string[] | undefined, sync = false): Promise => { - switch (config.protocol) { - case 'corda': - return cordaGateway.createDescribedAssetInstance(assetInstanceID, assetDefinitionID, descriptionHash, contentHash, participants); - case 'ethereum': - return ethereumGateway.createDescribedAssetInstance(assetInstanceID, assetDefinitionID, author, descriptionHash, contentHash, sync); - } -}; - -export const createAssetInstance = async (assetInstanceID: string, assetDefinitionID: string, author: string, - contentHash: string, participants: string[] | undefined, sync = false): Promise => { - switch (config.protocol) { - case 'corda': - return cordaGateway.createAssetInstance(assetInstanceID, assetDefinitionID, contentHash, participants); - case 'ethereum': - return ethereumGateway.createAssetInstance(assetInstanceID, assetDefinitionID, author, contentHash, sync); - } -}; - -export const createAssetInstanceBatch = async (batchHash: string, author: string, participants: string[] | undefined, sync = false): Promise => { - switch (config.protocol) { - case 'corda': - return cordaGateway.createAssetInstanceBatch(batchHash, participants); - case 'ethereum': - return ethereumGateway.createAssetInstanceBatch(batchHash, author, sync); - } -} - -export const setAssetInstanceProperty = async (assetDefinitionID: string, assetInstanceID: string, author: string, key: string, value: string, - participants: string[] | undefined, sync: boolean): Promise => { - switch (config.protocol) { - case 'corda': - return cordaGateway.setAssetInstanceProperty(assetDefinitionID, assetInstanceID, key, value, participants); - case 'ethereum': - return ethereumGateway.setAssetInstanceProperty(assetDefinitionID, assetInstanceID, author, key, value, sync); - } -}; - - -// Payment instance APIs - -export const createDescribedPaymentInstance = async (paymentInstanceID: string, paymentDefinitionID: string, - author: string, member: string, amount: number, descriptionHash: string, participants: string[] | undefined, sync: boolean): - Promise => { - switch (config.protocol) { - case 'corda': - return cordaGateway.createDescribedPaymentInstance(paymentInstanceID, paymentDefinitionID, member, amount, descriptionHash, participants); - case 'ethereum': - return ethereumGateway.createDescribedPaymentInstance(paymentInstanceID, paymentDefinitionID, author, member, amount, descriptionHash, sync); - } -}; - -export const createPaymentInstance = async (paymentInstanceID: string, paymentDefinitionID: string, - author: string, member: string, amount: number, participants: string[] | undefined, sync: boolean): - Promise => { - switch (config.protocol) { - case 'corda': - return cordaGateway.createPaymentInstance(paymentInstanceID, paymentDefinitionID, member, amount, participants); - case 'ethereum': - return ethereumGateway.createPaymentInstance(paymentInstanceID, paymentDefinitionID, author, member, amount, sync); - } -}; diff --git a/kat/src/clients/app2app.ts b/kat/src/clients/app2app.ts deleted file mode 100644 index 0057135dc5..0000000000 --- a/kat/src/clients/app2app.ts +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import io from 'socket.io-client'; -import { config } from '../lib/config'; -import * as utils from '../lib/utils'; -import { AssetTradeMessage, IApp2AppMessage, IApp2AppMessageListener } from '../lib/interfaces'; - -const log = utils.getLogger('clients/app2app.ts'); - -let socket: SocketIOClient.Socket -let listeners: IApp2AppMessageListener[] = []; - -export const init = async () => { - establishSocketIOConnection(); -}; - -function subscribeWithRetry() { - log.trace(`App2App subscription: ${config.app2app.destinations.kat}`) - socket.emit('subscribe', [config.app2app.destinations.kat], (err: any, data: any) => { - if (err) { - log.error(`App2App subscription failure (retrying): ${err}`); - setTimeout(subscribeWithRetry, utils.constants.SUBSCRIBE_RETRY_INTERVAL); - return; - } - log.trace(`App2App subscription succeeded: ${JSON.stringify(data)}`); - }); -} - -const establishSocketIOConnection = () => { - let error = false; - const { APP2APP_BATCH_SIZE, APP2APP_BATCH_TIMEOUT, APP2APP_READ_AHEAD } = utils.constants; - socket = io.connect(`${config.app2app.socketIOEndpoint}?auto_commit=false&read_ahead=${APP2APP_READ_AHEAD}&batch_size=${APP2APP_BATCH_SIZE}&batch_timeout=${APP2APP_BATCH_TIMEOUT}`, { - transportOptions: { - polling: { - extraHeaders: { - Authorization: 'Basic ' + Buffer.from(`${config.appCredentials.user}` + - `:${config.appCredentials.password}`).toString('base64') - } - } - } - }).on('connect', () => { - if (error) { - error = false; - log.info('App2App messaging Socket IO connection restored'); - } - subscribeWithRetry(); - }).on('connect_error', (err: Error) => { - error = true; - log.error(`App2App messaging Socket IO connection error. ${err.toString()}`); - }).on('error', (err: Error) => { - error = true; - log.error(`App2app messaging Socket IO error. ${err.toString()}`); - }).on('exception', (err: Error, extra?: any) => { - // Exceptions are such things as delivery failures. They do not put the connection in error state - log.error(`App2app messaging exception. ${err.toString()}`, extra); - }).on('data', (app2appMessage: IApp2AppMessage) => { - log.trace(`App2App message ${JSON.stringify(app2appMessage)}`); - try { - const content: AssetTradeMessage = JSON.parse(app2appMessage.content); - log.trace(`App2App message type=${content.type}`) - for (const listener of listeners) { - listener(app2appMessage.headers, content); - } - } catch (err) { - log.error(`App2App message error ${err}`); - } finally { - socket.emit('commit'); - } - }) as SocketIOClient.Socket; -}; - -export const addListener = (listener: IApp2AppMessageListener) => { - listeners.push(listener); -}; - -export const removeListener = (listener: IApp2AppMessageListener) => { - listeners = listeners.filter(entry => entry != listener); -}; - -export const dispatchMessage = (to: string, content: any) => { - log.trace(`App2App dispatch type=${content.type}`) - socket.emit('produce', { - headers: { - from: config.app2app.destinations.kat, - to - }, - content: JSON.stringify(content) - }, 'kat', (err: any) => { - if(err) { - log.error(`Failed to dispatch App2App message.`, err); - } - }); -}; - -export const reset = () => { - if (socket) { - log.info('App2App Socket IO connection reset'); - socket.close(); - establishSocketIOConnection(); - } -}; \ No newline at end of file diff --git a/kat/src/clients/database.ts b/kat/src/clients/database.ts deleted file mode 100644 index 939d372731..0000000000 --- a/kat/src/clients/database.ts +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { config } from '../lib/config'; -import { ClientEventType, IClientEventListener, IDatabaseProvider, IDBAssetDefinition, IDBAssetInstance, IDBBatch, IDBBlockchainData, IDBMember, IDBPaymentDefinition, IDBPaymentInstance, IStoredSubscriptions } from '../lib/interfaces'; -import * as utils from '../lib/utils'; -import MongoDBProvider from './db-providers/mongodb'; -import NEDBProvider from './db-providers/nedb'; -const log = utils.getLogger('handlers/asset-trade.ts'); - -let databaseProvider: IDatabaseProvider; - -export const init = async () => { - if (config.mongodb !== undefined) { - databaseProvider = new MongoDBProvider(); - } else { - databaseProvider = new NEDBProvider(); - } - await databaseProvider.init(); -}; - -let listeners: IClientEventListener[] = []; - -// COLLECTION AGNOSTIC QUERIES - -export const createCollection = (collectionName: string, indexes: { fields: string[], unique?: boolean }[]) => { - return databaseProvider.createCollection(collectionName, indexes); -}; - -// MEMBER QUERIES - -export const retrieveMemberByAddress = (address: string): Promise => { - return databaseProvider.findOne('members', { address }); -}; - -export const retrieveMembers = (query: object, skip: number, limit: number): Promise => { - return databaseProvider.find('members', query, { name: 1 }, skip, limit); -}; - -export const upsertMember = async (member: IDBMember) => { - await databaseProvider.updateOne('members', { address: member.address }, { $set: member }, true); - emitEvent('member-registered', member); -}; - -// ASSET DEFINITION QUERIES - -export const retrieveAssetDefinitions = (query: object, skip: number, limit: number): Promise => { - return databaseProvider.find('asset-definitions', query, { name: 1 }, skip, limit) -}; - -export const countAssetDefinitions = (query: object): Promise => { - return databaseProvider.count('asset-definitions', query); -}; - -export const retrieveAssetDefinitionByID = (assetDefinitionID: string): Promise => { - return databaseProvider.findOne('asset-definitions', { assetDefinitionID }); -}; - -export const retrieveAssetDefinitionByName = (name: string): Promise => { - return databaseProvider.findOne('asset-definitions', { name }); -}; - -export const upsertAssetDefinition = async (assetDefinition: IDBAssetDefinition) => { - await databaseProvider.updateOne('asset-definitions', { assetDefinitionID: assetDefinition.assetDefinitionID }, { $set: assetDefinition }, true); - if (assetDefinition.submitted !== undefined) { - emitEvent('asset-definition-submitted', assetDefinition); - } else if (assetDefinition.transactionHash !== undefined) { - emitEvent('asset-definition-created', assetDefinition); - } -}; - -export const markAssetDefinitionAsConflict = async (assetDefinitionID: string, timestamp: number) => { - await databaseProvider.updateOne('asset-definitions', { assetDefinitionID }, { $set: { timestamp, conflict: true } }, false); - emitEvent('asset-definition-name-conflict', { assetDefinitionID }) -}; - -// PAYMENT DEFINITION QUERIES - -export const retrievePaymentDefinitions = (query: object, skip: number, limit: number): Promise => { - return databaseProvider.find('payment-definitions', query, { name: 1 }, skip, limit); -}; - -export const countPaymentDefinitions = (query: object): Promise => { - return databaseProvider.count('payment-definitions', query); -}; - -export const retrievePaymentDefinitionByID = (paymentDefinitionID: string): Promise => { - return databaseProvider.findOne('payment-definitions', { paymentDefinitionID }); -}; - -export const retrievePaymentDefinitionByName = (name: string): Promise => { - return databaseProvider.findOne('payment-definitions', { name }); -}; - -export const upsertPaymentDefinition = async (paymentDefinition: IDBPaymentDefinition) => { - await databaseProvider.updateOne('payment-definitions', { paymentDefinitionID: paymentDefinition.paymentDefinitionID }, { $set: paymentDefinition }, true) - if (paymentDefinition.submitted !== undefined) { - emitEvent('payment-definition-submitted', paymentDefinition); - } else if (paymentDefinition.transactionHash !== undefined) { - emitEvent('payment-definition-created', paymentDefinition); - } -}; - -export const markPaymentDefinitionAsConflict = async (paymentDefinitionID: string, timestamp: number) => { - await databaseProvider.updateOne('payment-definitions', { paymentDefinitionID }, { $set: { conflict: true, timestamp } }, false); - emitEvent('payment-definition-name-conflict', { paymentDefinitionID }) -}; - -// ASSET INSTANCE QUERIES - -export const retrieveAssetInstances = (assetDefinitionID: string, query: object, sort: object, skip: number, limit: number): Promise => { - return databaseProvider.find(`asset-instance-${assetDefinitionID}`, query, sort, skip, limit); -}; - -export const countAssetInstances = (assetDefinitionID: string, query: object): Promise => { - return databaseProvider.count(`asset-instance-${assetDefinitionID}`, query); -}; - -export const retrieveAssetInstanceByID = (assetDefinitionID: string, assetInstanceID: string): Promise => { - return databaseProvider.findOne(`asset-instance-${assetDefinitionID}`, { assetInstanceID }); -}; - -export const retrieveAssetInstanceByDefinitionIDAndContentHash = (assetDefinitionID: string, contentHash: string): Promise => { - return databaseProvider.findOne(`asset-instance-${assetDefinitionID}`, { contentHash }); -}; - -export const upsertAssetInstance = async (assetInstance: IDBAssetInstance) => { - await databaseProvider.updateOne(`asset-instance-${assetInstance.assetDefinitionID}`, { assetInstanceID: assetInstance.assetInstanceID }, { $set: assetInstance }, true); - if (assetInstance.submitted !== undefined) { - emitEvent('asset-instance-submitted', assetInstance); - } else if (assetInstance.transactionHash !== undefined) { - emitEvent('asset-instance-created', assetInstance); - } -}; - -export const setAssetInstanceReceipt = async (assetDefinitionID: string, assetInstanceID: string, receipt: string) => { - await databaseProvider.updateOne(`asset-instance-${assetDefinitionID}`, { assetInstanceID }, { $set: { receipt } }, true); -}; - -export const setAssetInstancePrivateContent = async (assetDefinitionID: string, assetInstanceID: string, content: object | undefined, filename: string | undefined) => { - await databaseProvider.updateOne(`asset-instance-${assetDefinitionID}`, { assetInstanceID }, { $set: { content, filename } }, true); - log.info(`Emitting event for private-asset-instance-content-stored`); - emitEvent('private-asset-instance-content-stored', { assetDefinitionID, assetInstanceID, content, filename }); -}; - -export const markAssetInstanceAsConflict = async (assetDefinitionID: string, assetInstanceID: string, timestamp: number) => { - await databaseProvider.updateOne(`asset-instance-${assetDefinitionID}`, { assetInstanceID }, { $set: { conflict: true, timestamp } }, false); - emitEvent('asset-instance-content-conflict', { assetDefinitionID, assetInstanceID }); -}; - -export const setSubmittedAssetInstanceProperty = async (assetDefinitionID: string, assetInstanceID: string, author: string, key: string, value: string, submitted: number, batchID?: string) => { - await databaseProvider.updateOne(`asset-instance-${assetDefinitionID}`, { assetInstanceID }, - { - $set: { - [`properties.${author}.${key}.value`]: value, - [`properties.${author}.${key}.submitted`]: submitted, - [`properties.${author}.${key}.batchID`]: batchID, - } - }, false); - emitEvent('asset-instance-property-submitted', { assetDefinitionID, assetInstanceID, key, value, submitted, batchID }); -}; - -export const setAssetInstancePropertyReceipt = async (assetDefinitionID: string, assetInstanceID: string, author: string, key: string, receipt: string) => { - await databaseProvider.updateOne(`asset-instance-${assetDefinitionID}`, { assetInstanceID }, - { - $set: { - [`properties.${author}.${key}.receipt`]: receipt - } - }, false); -}; - -export const setConfirmedAssetInstanceProperty = async (assetDefinitionID: string, assetInstanceID: string, author: string, key: string, value: string, timestamp: number, { blockNumber, transactionHash }: IDBBlockchainData) => { - await databaseProvider.updateOne(`asset-instance-${assetDefinitionID}`, { assetInstanceID }, - { - $set: { - [`properties.${author}.${key}.value`]: value, - [`properties.${author}.${key}.history.${timestamp}`]: { value, timestamp, blockNumber, transactionHash } - } - }, false); - emitEvent('asset-instance-property-set', { assetDefinitionID, assetInstanceID, author, key, value, timestamp, blockNumber, transactionHash }); -}; - -// PAYMENT INSTANCE QUERIES - -export const retrievePaymentInstances = (query: object, sort: object, skip: number, limit: number): Promise => { - return databaseProvider.find('payment-instances', query, sort, skip, limit); -}; - -export const countPaymentInstances = (query: object): Promise => { - return databaseProvider.count('payment-instances', query); -}; - -export const retrievePaymentInstanceByID = (paymentInstanceID: string): Promise => { - return databaseProvider.findOne('payment-instances', { paymentInstanceID }); -}; - -export const upsertPaymentInstance = async (paymentInstance: IDBPaymentInstance) => { - await databaseProvider.updateOne('payment-instances', { paymentInstanceID: paymentInstance.paymentInstanceID }, { $set: paymentInstance }, true); - if (paymentInstance.submitted !== undefined) { - emitEvent('payment-instance-submitted', paymentInstance); - } else { - emitEvent('payment-instance-created', paymentInstance); - } -}; - - -// BATCH QUERIES - -export const retrieveBatches = (query: object, skip: number, limit: number, sort: {[f: string]: number} = {}): Promise => { - return databaseProvider.find('batches', query, sort, skip, limit); -}; - -export const retrieveBatchByID = (batchID: string): Promise => { - return databaseProvider.findOne('batches', { batchID }); -}; - -export const retrieveBatchByHash = (batchHash: string): Promise => { - return databaseProvider.findOne('batches', { batchHash }); -}; - -export const upsertBatch = async (batch: IDBBatch) => { - await databaseProvider.updateOne('batches', { batchID: batch.batchID }, { $set: batch }, true); -}; - -// SUBSCRIPTION MANAGEMENT - -export const retrieveSubscriptions = (): Promise => { - return databaseProvider.findOne('state', { key: 'subscriptions' }); -}; - -export const upsertSubscriptions = (subscriptions: IStoredSubscriptions): Promise => { - return databaseProvider.updateOne('state', { key: 'subscriptions' }, { $set: subscriptions }, true); -}; - -// EVENT HANDLING - -export const addListener = (listener: IClientEventListener) => { - listeners.push(listener); -}; - -export const removeListener = (listener: IClientEventListener) => { - listeners = listeners.filter(entry => entry != listener); -}; - -const emitEvent = (eventType: ClientEventType, content: object) => { - for (const listener of listeners) { - listener(eventType, content); - } -}; - -export const shutDown = () => { - databaseProvider.shutDown(); -}; diff --git a/kat/src/clients/db-providers/mongodb.ts b/kat/src/clients/db-providers/mongodb.ts deleted file mode 100644 index 8b06f26fee..0000000000 --- a/kat/src/clients/db-providers/mongodb.ts +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { Db, MongoClient } from 'mongodb'; -import { config } from '../../lib/config'; -import { databaseCollectionName, IDatabaseProvider, indexes } from '../../lib/interfaces'; -import { databaseCollectionIndexes } from '../../lib/utils'; - -let db: Db; -let mongoClient: MongoClient; - -export default class MongoDBProvider implements IDatabaseProvider { - - async init() { - try { - mongoClient = await MongoClient.connect(config.mongodb.connectionUrl, - { useNewUrlParser: true, useUnifiedTopology: true, ignoreUndefined: true }); - db = mongoClient.db(config.mongodb.databaseName); - for (const [collectionName, indexes] of Object.entries(databaseCollectionIndexes)) { - this.createCollection(collectionName, indexes); - } - } catch (err) { - throw new Error(`Failed to connect to Mongodb. ${err}`); - } - } - - async createCollection(collectionName: string, indexes: indexes) { - try { - for (const index of indexes) { - const fields: { [f: string]: number } = {}; - for (const field of index.fields) { - fields[field] = 1; // all ascending currently - } - db.collection(collectionName).createIndex(fields, { unique: !!index.unique }); - } - } catch (err) { - throw new Error(`Failed to create collection. ${err}`); - } - } - - count(collectionName: databaseCollectionName, query: object): Promise { - return db.collection(collectionName).find(query).count(); - } - - find(collectionName: databaseCollectionName, query: object, sort: object, skip: number, limit: number): Promise { - return db.collection(collectionName).find(query, { projection: { _id: 0 } }).sort(sort).skip(skip).limit(limit).toArray(); - } - - findOne(collectionName: databaseCollectionName, query: object): Promise { - return db.collection(collectionName).findOne(query, { projection: { _id: 0 } }); - } - - async updateOne(collectionName: databaseCollectionName, query: object, value: object, upsert: boolean) { - await db.collection(collectionName).updateOne(query, value, { upsert }); - } - - shutDown() { - mongoClient.close(); - } - -} diff --git a/kat/src/clients/db-providers/nedb.ts b/kat/src/clients/db-providers/nedb.ts deleted file mode 100644 index a539e7a089..0000000000 --- a/kat/src/clients/db-providers/nedb.ts +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import Datastore from 'nedb-promises'; -import path from 'path'; -import { databaseCollectionName, IDatabaseProvider, indexes } from '../../lib/interfaces'; -import { constants, databaseCollectionIndexes } from '../../lib/utils'; - -const projection = { _id: 0 }; -let collections: { [name: string]: Datastore } = {}; - -export default class NEDBProvider implements IDatabaseProvider { - - async init() { - try { - for (const [collectionName, indexes] of Object.entries(databaseCollectionIndexes)) { - this.createCollection(collectionName, indexes); - } - } catch (err) { - throw new Error(`Failed to initialize NEDB. ${err}`); - } - } - - async createCollection(collectionName: string, indexes: indexes) { - const collection = Datastore.create({ - filename: path.join(constants.DATA_DIRECTORY, `${collectionName}.json`), - autoload: true - }); - for (const index of indexes) { - // No compound indexes here - for (let fieldName of index.fields) { - collection.ensureIndex({ fieldName, unique: !!index.unique }); - } - } - collections[collectionName] = collection; - } - - count(collectionName: databaseCollectionName, query: object): Promise { - return collections[collectionName].count(query); - } - - find(collectionName: databaseCollectionName, query: object, sort: object, skip: number, limit: number): Promise { - return collections[collectionName].find(query, projection).skip(skip).limit(limit).sort(sort); - } - - findOne(collectionName: databaseCollectionName, query: object): Promise { - return collections[collectionName].findOne(query, projection); - } - - async updateOne(collectionName: databaseCollectionName, query: object, value: object, upsert: boolean) { - await collections[collectionName].update(query, value, { upsert }); - } - - shutDown() { } - -} diff --git a/kat/src/clients/doc-exchange.ts b/kat/src/clients/doc-exchange.ts deleted file mode 100644 index ff9a791019..0000000000 --- a/kat/src/clients/doc-exchange.ts +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { IDocExchangeTransferData, IDocExchangeListener, IDocExchangeDocumentDetails } from '../lib/interfaces'; -import { config } from '../lib/config'; -import { Stream, Readable } from 'stream'; -import io from 'socket.io-client'; -import FormData from 'form-data'; -import axios from 'axios'; -import * as utils from '../lib/utils'; - -const log = utils.getLogger('clients/doc-exchange.ts'); - -let socket: SocketIOClient.Socket -let listeners: IDocExchangeListener[] = []; - -export const init = async () => { - try { - const response = await axios.get(`${config.docExchange.apiEndpoint}/documents`, { - auth: { - username: config.appCredentials.user, - password: config.appCredentials.password - } - }); - if (!Array.isArray(response.data.entries)) { - throw 'Invalid response'; - } else { - establishSocketIOConnection(); - } - } catch (err) { - throw new Error(`Document exchange REST connection failed. ${err}`); - } -}; - -const establishSocketIOConnection = () => { - let error = false; - socket = io.connect(config.docExchange.socketIOEndpoint, { - transportOptions: { - polling: { - extraHeaders: { - Authorization: 'Basic ' + Buffer.from(`${config.appCredentials.user}` + - `:${config.appCredentials.password}`).toString('base64') - } - } - } - }).on('connect', () => { - if (error) { - error = false; - log.info('Document exchange Socket IO connection restored'); - } - }).on('connect_error', (err: Error) => { - error = true; - log.error(`Document exchange Socket IO connection error. ${err.toString()}`); - }).on('error', (err: Error) => { - error = true; - log.error(`Document exchange Socket IO error. ${err.toString()}`); - }).on('document_received', (transferData: IDocExchangeTransferData) => { - log.trace(`Doc exchange transfer event ${JSON.stringify(transferData)}`); - for (const listener of listeners) { - listener(transferData); - } - }) as SocketIOClient.Socket; -}; - -export const addListener = (listener: IDocExchangeListener) => { - listeners.push(listener); -}; - -export const removeListener = (listener: IDocExchangeListener) => { - listeners = listeners.filter(entry => entry != listener); -}; - -export const downloadStream = async (documentPath: string): Promise => { - const response = await axios.get(`${config.docExchange.apiEndpoint}/documents/${documentPath}`, { - responseType: 'arraybuffer', - auth: { - username: config.appCredentials.user, - password: config.appCredentials.password - } - }); - return response.data; -}; - -export const downloadJSON = async (documentPath: string): Promise => { - const response = await axios.get(`${config.docExchange.apiEndpoint}/documents/${documentPath}`, { - responseType: 'json', - auth: { - username: config.appCredentials.user, - password: config.appCredentials.password - } - }); - return response.data; -}; - -export const findDocumentByHash = async (documentHash: string): Promise => { - const result = await axios({ - url: `${config.docExchange.apiEndpoint}/search?query=${documentHash}&by_hash=true`, - auth: { - username: config.appCredentials.user, - password: config.appCredentials.password - } - }); - if (result.data.documents.length > 0) { - return result.data.documents[0].full_path; - } - return null; -} - -export const uploadString = async (value: string, path: string): Promise => { - const readable = new Readable(); - readable.push(value); - readable.push(null); - return uploadStream(readable, path); -}; - -export const uploadStream = async (stream: Stream, path: string): Promise => { - const formData = new FormData(); - formData.append('document', stream); - const result = await axios({ - method: 'put', - url: `${config.docExchange.apiEndpoint}/documents/${path}`, - data: formData, - headers: formData.getHeaders(), - auth: { - username: config.appCredentials.user, - password: config.appCredentials.password - } - }); - return result.data.hash; -}; - -export const transfer = async (from: string, to: string, document: string) => { - await axios({ - method: 'post', - url: `${config.docExchange.apiEndpoint}/transfers`, - auth: { - username: config.appCredentials.user, - password: config.appCredentials.password - }, - data: { from, to, document } - }); -} - -export const getDocumentDetails = async (filePath: string): Promise => { - const result = await axios({ - url: `${config.docExchange.apiEndpoint}/documents/${filePath}?details_only=true`, - auth: { - username: config.appCredentials.user, - password: config.appCredentials.password - } - }); - return result.data; -}; - -export const reset = () => { - if (socket) { - log.info('Document exchange Socket IO connection reset'); - socket.close(); - establishSocketIOConnection(); - } -}; diff --git a/kat/src/clients/event-streams.ts b/kat/src/clients/event-streams.ts deleted file mode 100644 index 6ff008cb1c..0000000000 --- a/kat/src/clients/event-streams.ts +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import WebSocket from 'ws'; -import { config } from '../lib/config'; -import * as utils from '../lib/utils'; -import { IDBBlockchainData, IEventAssetDefinitionCreated, IEventAssetInstanceBatchCreated, IEventAssetInstanceCreated, IEventAssetInstancePropertySet, IEventPaymentDefinitionCreated, IEventPaymentInstanceCreated, IEventStreamMessage, IEventStreamRawMessageCorda } from '../lib/interfaces'; -import * as membersHandler from '../handlers/members'; -import * as assetDefinitionsHandler from '../handlers/asset-definitions'; -import * as paymentDefinitionsHandler from '../handlers/payment-definitions'; -import * as assetInstancesHandler from '../handlers/asset-instances'; -import * as paymentInstanceHandler from '../handlers/payment-instances'; -import { IEventMemberRegistered } from '../lib/interfaces'; - -const log = utils.getLogger('clients/event-streams.ts'); - -let ws: WebSocket; -let heartBeatTimeout: NodeJS.Timeout; -let disconnectionDetected = false; -let disconnectionTimeout: NodeJS.Timeout; - -export const init = () => { - ws = new WebSocket(config.eventStreams.wsEndpoint, { - headers: { - Authorization: 'Basic ' + Buffer.from(`${config.eventStreams.auth?.user ?? config.appCredentials.user}` + - `:${config.eventStreams.auth?.password ?? config.appCredentials.password}`).toString('base64') - - } - }); - addEventHandlers(); -}; - -export const shutDown = () => { - if (disconnectionTimeout) { - clearTimeout(disconnectionTimeout); - } - if (ws) { - clearTimeout(heartBeatTimeout); - ws.close(); - } -}; - -const addEventHandlers = () => { - ws.on('open', () => { - if (disconnectionDetected) { - disconnectionDetected = false; - log.info('Event stream websocket restored'); - } - ws.send(JSON.stringify({ - type: 'listen', - topic: config.eventStreams.topic - })); - heartBeat(); - }).on('close', () => { - disconnectionDetected = true; - log.error(`Event stream websocket disconnected, attempting to reconnect in ${utils.constants.EVENT_STREAM_WEBSOCKET_RECONNECTION_DELAY_SECONDS} second(s)`); - disconnectionTimeout = setTimeout(() => { - init(); - }, utils.constants.EVENT_STREAM_WEBSOCKET_RECONNECTION_DELAY_SECONDS * 1000); - }).on('message', async (message: string) => { - await handleMessage(message); - ws.send(JSON.stringify({ - type: 'ack', - topic: config.eventStreams.topic - })); - }).on('pong', () => { - heartBeat(); - }).on('error', err => { - log.error(`Event stream websocket error. ${err}`); - }); -}; - -const heartBeat = () => { - ws.ping(); - clearTimeout(heartBeatTimeout); - heartBeatTimeout = setTimeout(() => { - log.error('Event stream ping timeout'); - ws.terminate(); - }, utils.constants.EVENT_STREAM_PING_TIMEOUT_SECONDS * 1000); -} - -const processRawMessage = (message: string): Array => { - switch (config.protocol) { - case 'ethereum': - return JSON.parse(message); - case 'corda': - const cordaMessages: Array = JSON.parse(message); - return cordaMessages.map(msg => ( - { - data: { - ...msg.data.data, - timestamp: Date.parse(msg.recordedTime) - }, - transactionHash: msg.stateRef.txhash, - subId: msg.subId, - signature: msg.signature - } - ) - ); - } -} - -const getBlockchainData = (message: IEventStreamMessage): IDBBlockchainData => { - switch (config.protocol) { - case 'ethereum': - return { - blockNumber: Number(message.blockNumber), - transactionHash: message.transactionHash - } - case 'corda': { - return { - transactionHash: message.transactionHash - } - } - } -} - -const eventSignatures = () => { - switch (config.protocol) { - case 'ethereum': return utils.contractEventSignatures - case 'corda': return utils.contractEventSignaturesCorda - } -} - -const handleMessage = async (message: string) => { - const messageArray: Array = processRawMessage(message); - log.info(`Event batch (${messageArray.length})`) - const signatures = eventSignatures(); - for (const message of messageArray) { - log.trace(`Event ${JSON.stringify(message)}`); - log.info(`Event signature: ${message.signature}`); - const blockchainData: IDBBlockchainData = getBlockchainData(message); - try { - switch (message.signature) { - case signatures.MEMBER_REGISTERED: - await membersHandler.handleMemberRegisteredEvent(message.data as IEventMemberRegistered, blockchainData); break; - case signatures.ASSET_DEFINITION_CREATED: - await assetDefinitionsHandler.handleAssetDefinitionCreatedEvent(message.data as IEventAssetDefinitionCreated, blockchainData); break; - case signatures.DESCRIBED_PAYMENT_DEFINITION_CREATED: - case signatures.PAYMENT_DEFINITION_CREATED: - await paymentDefinitionsHandler.handlePaymentDefinitionCreatedEvent(message.data as IEventPaymentDefinitionCreated, blockchainData); break; - case signatures.ASSET_INSTANCE_CREATED: - case signatures.DESCRIBED_ASSET_INSTANCE_CREATED: - await assetInstancesHandler.handleAssetInstanceCreatedEvent(message.data as IEventAssetInstanceCreated, blockchainData); break; - case signatures.ASSET_INSTANCE_BATCH_CREATED: - await assetInstancesHandler.handleAssetInstanceBatchCreatedEvent(message.data as IEventAssetInstanceBatchCreated, blockchainData); break; - case signatures.DESCRIBED_PAYMENT_INSTANCE_CREATED: - case signatures.PAYMENT_INSTANCE_CREATED: - await paymentInstanceHandler.handlePaymentInstanceCreatedEvent(message.data as IEventPaymentInstanceCreated, blockchainData); break; - case signatures.ASSET_PROPERTY_SET: - await assetInstancesHandler.handleSetAssetInstancePropertyEvent(message.data as IEventAssetInstancePropertySet, blockchainData); break; - } - } catch (err) { - log.error(`Failed to handle event: ${message.signature} for message: ${JSON.stringify(message)} with error`, err.stack); - } - } -}; diff --git a/kat/src/clients/gateway-providers/corda.ts b/kat/src/clients/gateway-providers/corda.ts deleted file mode 100644 index 65ac70ae45..0000000000 --- a/kat/src/clients/gateway-providers/corda.ts +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import axios from 'axios'; -import { config } from '../../lib/config'; -import { IAPIGatewayAsyncResponse, IAPIGatewaySyncResponse } from '../../lib/interfaces'; -import { getLogger } from '../../lib/utils'; -const log = getLogger('gateway-providers/corda.ts'); - -// Asset instance APIs - -export const createDescribedAssetInstance = async (assetInstanceID: string, assetDefinitionID: string, - descriptionHash: string, contentHash: string, participants: string[] | undefined): Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createDescribedAssetInstance`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - assetInstanceID: assetInstanceID, - assetDefinitionID: assetDefinitionID, - descriptionHash, - contentHash, - participants - } - }); - return { ...response.data, type: 'sync' }; - } catch (err) { - return handleError(`Failed to create described asset instance ${assetInstanceID}`, err); - } -}; - -export const createAssetInstance = async (assetInstanceID: string, assetDefinitionID: string, - contentHash: string, participants: string[] | undefined): Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createAssetInstance`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - assetInstanceID: assetInstanceID, - assetDefinitionID: assetDefinitionID, - contentHash, - participants - } - }); - return { ...response.data, type: 'sync' }; - } catch (err) { - return handleError(`Failed to create asset instance ${assetInstanceID}`, err); - } -}; - -export const createAssetInstanceBatch = async (batchHash: string, participants: string[] | undefined): Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createAssetInstanceBatch`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - batchHash, - participants - } - }); - return { ...response.data, type: 'sync' }; - } catch (err) { - return handleError(`Failed to create asset instance batch ${batchHash}`, err); - } -}; - -export const setAssetInstanceProperty = async (assetDefinitionID: string, assetInstanceID: string, key: string, value: string, - participants: string[] | undefined | undefined): Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/setAssetInstanceProperty`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - assetDefinitionID: assetDefinitionID, - assetInstanceID: assetInstanceID, - key, - value, - participants - } - }); - return { ...response.data, type: 'sync' }; - } catch (err) { - return handleError(`Failed to set asset instance property ${key} (instance=${assetInstanceID})`, err); - } -}; - -export const createDescribedPaymentInstance = async (paymentInstanceID: string, paymentDefinitionID: string, member: string, amount: number, descriptionHash: string, participants: string[] | undefined): - Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createDescribedPaymentInstance`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - paymentInstanceID: paymentInstanceID, - paymentDefinitionID: paymentDefinitionID, - member, - amount, - descriptionHash, - participants - } - }); - return { ...response.data, type: 'sync' }; - } catch (err) { - return handleError(`Failed to create described asset payment instance ${paymentInstanceID}`, err); - } -}; - -export const createPaymentInstance = async (paymentInstanceID: string, paymentDefinitionID: string, - member: string, amount: number, participants: string[] | undefined): Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createPaymentInstance`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - paymentInstanceID: paymentInstanceID, - paymentDefinitionID: paymentDefinitionID, - member, - amount, - participants - } - }); - return { ...response.data, type: 'sync' }; - } catch (err) { - return handleError(`Failed to create asset payment instance ${paymentInstanceID}`, err); - } -}; - -function handleError(msg: string, err: any): Promise { - const errMsg = err.response?.data?.error ?? err.response.data.message ?? err.toString(); - log.error(`${msg}. ${errMsg}`); - throw new Error(msg); -} \ No newline at end of file diff --git a/kat/src/clients/gateway-providers/ethereum.ts b/kat/src/clients/gateway-providers/ethereum.ts deleted file mode 100644 index 28493d8680..0000000000 --- a/kat/src/clients/gateway-providers/ethereum.ts +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import axios from 'axios'; -import { config } from '../../lib/config'; -import { IAPIGatewayAsyncResponse, IAPIGatewaySyncResponseEthereum } from '../../lib/interfaces'; -import * as utils from '../../lib/utils'; -const log = utils.getLogger('gateway-providers/ethereum.ts'); - -// Member APIs - -export const upsertMember = async (address: string, name: string, app2appDestination: string, - docExchangeDestination: string, sync: boolean): Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/registerMember?kld-from=${address}&kld-sync=${sync}`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - name, - assetTrailInstanceID: config.assetTrailInstanceID, - app2appDestination, - docExchangeDestination - } - }); - return { ...response.data, type: sync ? 'sync' : 'async' }; - } catch (err) { - return handleError(`Failed to register new member ${name}`, err); - } -}; - - -// Asset definition APIs - -export const createAssetDefinition = async (author: string, assetDefinitionHash: string, sync: boolean): - Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createAssetDefinition?kld-from=${author}&kld-sync=${sync}`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - assetDefinitionHash - } - }); - return { ...response.data, type: sync ? 'sync' : 'async' }; - } catch (err) { - return handleError(`Failed to create asset definition ${assetDefinitionHash}`, err); - } -}; - - -// Payment definition APIs - -export const createDescribedPaymentDefinition = async (paymentDefinitionID: string, name: string, author: string, - descriptionSchemaHash: string, sync: boolean): Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createDescribedPaymentDefinition?kld-from=${author}&kld-sync=${sync}`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - paymentDefinitionID: utils.uuidToHex(paymentDefinitionID), - name, - descriptionSchemaHash - } - }); - return { ...response.data, type: sync ? 'sync' : 'async' }; - } catch (err) { - return handleError(`Failed to create described payment definition ${paymentDefinitionID}`, err); - } -}; - -export const createPaymentDefinition = async (paymentDefinitionID: string, name: string, author: string, sync: boolean): - Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createPaymentDefinition?kld-from=${author}&kld-sync=${sync}`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - paymentDefinitionID: utils.uuidToHex(paymentDefinitionID), - name - } - }); - return { ...response.data, type: sync ? 'sync' : 'async' }; - } catch (err) { - return handleError(`Failed to create payment definition ${paymentDefinitionID}`, err); - } -}; - - -// Asset instance APIs - -export const createDescribedAssetInstance = async (assetInstanceID: string, assetDefinitionID: string, author: string, - descriptionHash: string, contentHash: string, sync = false): Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createDescribedAssetInstance?kld-from=${author}&kld-sync=${sync}`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - assetInstanceID: utils.uuidToHex(assetInstanceID), - assetDefinitionID: utils.uuidToHex(assetDefinitionID), - descriptionHash, - contentHash - } - }); - return { ...response.data, type: sync ? 'sync' : 'async' }; - } catch (err) { - return handleError(`Failed to create described asset instance ${assetInstanceID}`, err); - } -}; - -export const createAssetInstance = async (assetInstanceID: string, assetDefinitionID: string, author: string, - contentHash: string, sync = false): Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createAssetInstance?kld-from=${author}&kld-sync=${sync}`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - assetInstanceID: utils.uuidToHex(assetInstanceID), - assetDefinitionID: utils.uuidToHex(assetDefinitionID), - contentHash - } - }); - return { ...response.data, type: sync ? 'sync' : 'async' }; - } catch (err) { - return handleError(`Failed to create asset instance ${assetInstanceID}`, err); - } -}; - -export const createAssetInstanceBatch = async (batchHash: string, author: string, sync = false): Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createAssetInstanceBatch?kld-from=${author}&kld-sync=${sync}`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - batchHash, - } - }); - return { ...response.data, type: sync ? 'sync' : 'async' }; - } catch (err) { - return handleError(`Failed to create asset instance batch ${batchHash}`, err); - } -}; - -export const setAssetInstanceProperty = async (assetDefinitionID: string, assetInstanceID: string, author: string, key: string, value: string, - sync: boolean): Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/setAssetInstanceProperty?kld-from=${author}&kld-sync=${sync}`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - assetDefinitionID: utils.uuidToHex(assetDefinitionID), - assetInstanceID: utils.uuidToHex(assetInstanceID), - key, - value - } - }); - return { ...response.data, type: sync ? 'sync' : 'async' }; - } catch (err) { - return handleError(`Failed to set asset instance property ${key} (instance=${assetInstanceID})`, err); - } -}; - - -// Payment instance APIs - -export const createDescribedPaymentInstance = async (paymentInstanceID: string, paymentDefinitionID: string, - author: string, member: string, amount: number, descriptionHash: string, sync: boolean): - Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createDescribedPaymentInstance?kld-from=${author}&kld-sync=${sync}`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - paymentInstanceID: utils.uuidToHex(paymentInstanceID), - paymentDefinitionID: utils.uuidToHex(paymentDefinitionID), - member, - amount, - descriptionHash - } - }); - return { ...response.data, type: sync ? 'sync' : 'async' }; - } catch (err) { - return handleError(`Failed to create described payment instance ${paymentInstanceID}`, err); - } -}; - -export const createPaymentInstance = async (paymentInstanceID: string, paymentDefinitionID: string, author: string, - member: string, amount: number, sync: boolean): Promise => { - try { - const response = await axios({ - method: 'post', - url: `${config.apiGateway.apiEndpoint}/createPaymentInstance?kld-from=${author}&kld-sync=${sync}`, - auth: { - username: config.apiGateway.auth?.user ?? config.appCredentials.user, - password: config.apiGateway.auth?.password ?? config.appCredentials.password - }, - data: { - paymentInstanceID: utils.uuidToHex(paymentInstanceID), - paymentDefinitionID: utils.uuidToHex(paymentDefinitionID), - member, - amount - } - }); - return { ...response.data, type: sync ? 'sync' : 'async' }; - } catch (err) { - return handleError(`Failed to create payment instance ${paymentInstanceID}`, err); - } -}; - -function handleError(msg: string, err: any): Promise { - const errMsg = err.response?.data?.error ?? err.response.data.message ?? err.toString(); - log.error(`${msg}. ${errMsg}`); - throw new Error(msg); -} \ No newline at end of file diff --git a/kat/src/clients/ipfs.ts b/kat/src/clients/ipfs.ts deleted file mode 100644 index f504db29c0..0000000000 --- a/kat/src/clients/ipfs.ts +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import FormData from 'form-data'; -import { Stream, Readable } from 'stream'; -import { constants } from '../lib/utils'; -import { config } from '../lib/config'; -import * as utils from '../lib/utils'; - -export const init = async () => { - try { - const response = await utils.axiosWithRetry({ - url: `${config.ipfs.apiEndpoint}/api/v0/version`, - method: 'post', - auth: { - username: config.appCredentials.user, - password: config.appCredentials.password - } - }); - if (response.data.Version === undefined) { - throw 'Invalid response'; - } - } catch (err) { - throw new Error(`IPFS Connection failed. ${err}`); - } -}; - -export const downloadJSON = async (hash: string): Promise => { - const response = await utils.axiosWithRetry({ - url: `${config.ipfs.gatewayEndpoint || config.ipfs.apiEndpoint}/ipfs/${hash}`, - method: 'get', - responseType: 'json', - timeout: constants.IPFS_TIMEOUT_MS, - auth: { - username: config.appCredentials.user, - password: config.appCredentials.password - } - }); - return response.data; -}; - -export const uploadString = (value: string): Promise => { - const readable = new Readable(); - readable.push(value); - readable.push(null); - return uploadStream(readable); -}; - -export const uploadStream = async (stream: Stream): Promise => { - const formData = new FormData(); - formData.append('document', stream); - const response = await utils.axiosWithRetry({ - url: `${config.ipfs.apiEndpoint}/api/v0/add`, - method: 'post', - data: formData, - headers: formData.getHeaders(), - auth: { - username: config.appCredentials.user, - password: config.appCredentials.password - } - }); - return response.data.Hash; -}; diff --git a/kat/src/handlers/asset-definitions.ts b/kat/src/handlers/asset-definitions.ts deleted file mode 100644 index c409639ab5..0000000000 --- a/kat/src/handlers/asset-definitions.ts +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import Ajv from 'ajv'; -import * as utils from '../lib/utils'; -import * as ipfs from '../clients/ipfs'; -import * as apiGateway from '../clients/api-gateway'; -import * as database from '../clients/database'; -import RequestError from '../lib/request-handlers'; -import indexSchema from '../schemas/indexes.json' -import assetDefinitionSchema from '../schemas/asset-definition.json' -const log = utils.getLogger('handler/asset-definitions.ts'); - -import { - IDBBlockchainData, - IDBAssetDefinition, - IEventAssetDefinitionCreated, - IAssetDefinitionRequest, - indexes -} from '../lib/interfaces'; -import { config } from '../lib/config'; - -const ajv = new Ajv(); - -export const handleGetAssetDefinitionsRequest = (query: object, skip: number, limit: number) => { - return database.retrieveAssetDefinitions(query, skip, limit); -}; - -export const handleCountAssetDefinitionsRequest = async (query: object) => { - return { count: await database.countAssetDefinitions(query) }; -}; - -export const handleGetAssetDefinitionRequest = async (assetDefinitionID: string) => { - const assetDefinition = await database.retrieveAssetDefinitionByID(assetDefinitionID); - if (assetDefinition === null) { - throw new RequestError('Asset definition not found', 404); - } - return assetDefinition; -}; - -export const handleCreateAssetDefinitionRequest = async (assetDefinitionID: string, name: string, isContentPrivate: boolean, isContentUnique: boolean, - author: string, descriptionSchema: Object | undefined, contentSchema: Object | undefined, indexes: { fields: string[], unique?: boolean }[] | undefined, sync: boolean) => { - if (descriptionSchema !== undefined && !ajv.validateSchema(descriptionSchema)) { - throw new RequestError('Invalid description schema', 400); - } - if (contentSchema !== undefined && !ajv.validateSchema(contentSchema)) { - throw new RequestError('Invalid content schema', 400); - } - if (indexes !== undefined && !ajv.validate(indexSchema, indexes)) { - throw new RequestError('Indexes do not conform to index schema', 400); - } - if (await database.retrieveAssetDefinitionByName(name) !== null) { - throw new RequestError('Asset definition name conflict', 409); - } - const timestamp = utils.getTimestamp(); - const assetDefinition: IAssetDefinitionRequest = { - assetDefinitionID, - name, - isContentPrivate, - isContentUnique, - descriptionSchema, - contentSchema, - indexes - } - - let assetDefinitionHash: string; - let receipt: string | undefined; - - switch (config.protocol) { - case 'ethereum': - assetDefinitionHash = utils.ipfsHashToSha256(await ipfs.uploadString(JSON.stringify(assetDefinition))); - const apiGatewayResponse = await apiGateway.createAssetDefinition(author, assetDefinitionHash, sync); - if (apiGatewayResponse.type === 'async') { - receipt = apiGatewayResponse.id; - } - break; - case 'corda': - assetDefinitionHash = utils.getSha256(JSON.stringify(assetDefinition)); - await createCollection(assetDefinitionID, indexes); - break; - } - await database.upsertAssetDefinition({ - assetDefinitionID, - author, - name, - isContentPrivate, - isContentUnique, - descriptionSchema, - assetDefinitionHash, - contentSchema, - receipt, - indexes, - submitted: timestamp - }); - log.info(`New asset definition ${assetDefinitionID} from API request published to blockchain and added to local database`); - return assetDefinitionID; -}; - -export const handleAssetDefinitionCreatedEvent = async (event: IEventAssetDefinitionCreated, { blockNumber, transactionHash }: IDBBlockchainData) => { - let assetDefinition = await ipfs.downloadJSON(utils.sha256ToIPFSHash(event.assetDefinitionHash)); - if (!ajv.validate(assetDefinitionSchema, assetDefinition)) { - throw new RequestError(`Invalid asset definition content ${JSON.stringify(ajv.errors)}`, 400); - } - const dbAssetDefinitionByID = await database.retrieveAssetDefinitionByID(assetDefinition.assetDefinitionID); - if (dbAssetDefinitionByID !== null) { - if (dbAssetDefinitionByID.transactionHash !== undefined) { - throw new Error(`Asset definition ID conflict ${assetDefinition.assetDefinitionID}`); - } - } else { - const dbAssetDefinitionByName = await database.retrieveAssetDefinitionByName(assetDefinition.name); - if (dbAssetDefinitionByName !== null) { - if (dbAssetDefinitionByName.transactionHash !== undefined) { - throw new Error(`Asset definition name conflict ${dbAssetDefinitionByName.name}`); - } else { - await database.markAssetDefinitionAsConflict(dbAssetDefinitionByName.assetDefinitionID, Number(event.timestamp)); - } - } - } - - await database.upsertAssetDefinition({ - ...assetDefinition, - author: event.author, - assetDefinitionHash: event.assetDefinitionHash, - timestamp: Number(event.timestamp), - blockNumber, - transactionHash - }); - await createCollection(assetDefinition.assetDefinitionID, assetDefinition.indexes); - - log.info(`New asset definition ${assetDefinition.assetDefinitionID} from blockchain event added to local database`); -}; - -const createCollection = async (assetDefinitionID: string, assetDefinitionIndexes: indexes | undefined) => { - const collectionName = `asset-instance-${assetDefinitionID}`; - let indexes: indexes = [{ fields: ['assetInstanceID'], unique: true }, { fields: ['author'], unique: false }]; - if (assetDefinitionIndexes !== undefined) { - indexes = indexes.concat(assetDefinitionIndexes) - } - await database.createCollection(collectionName, indexes); -}; \ No newline at end of file diff --git a/kat/src/handlers/asset-instances-pinning.ts b/kat/src/handlers/asset-instances-pinning.ts deleted file mode 100644 index 873e406acb..0000000000 --- a/kat/src/handlers/asset-instances-pinning.ts +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import * as apiGateway from '../clients/api-gateway'; -import * as ipfs from '../clients/ipfs'; -import { BatchManager } from '../lib/batch-manager'; -import { IAPIGatewayAsyncResponse, IAPIGatewaySyncResponse, IAssetInstance, IAssetInstancePropertySet, IBatchRecord, IDBBatch, IPinnedBatch, BatchRecordType } from '../lib/interfaces'; -import * as utils from '../lib/utils'; - -const log = utils.getLogger('lib/asset-instance-pinning.ts'); - -export class AssetInstancesPinning { - - private batchManager = new BatchManager('asset-instances', this.processBatch.bind(this)); - - public async init() { - await this.batchManager.init(); - } - - public async pin(instance: IAssetInstance): Promise { - const pinnedInstance: IBatchRecord = { recordType: BatchRecordType.assetInstance, ...instance }; - if (instance.isContentPrivate) delete pinnedInstance.content; - const batchID = await this.batchManager.getProcessor(instance.author).add(pinnedInstance); - log.trace(`Pinning initiated for asset ${instance.assetInstanceID}/${instance.assetInstanceID} in batch ${batchID}`); - return batchID; - } - - public async pinProperty(property: IAssetInstancePropertySet): Promise { - const pinnedProperty: IBatchRecord = { recordType: BatchRecordType.assetProperty, ...property }; - const batchID = await this.batchManager.getProcessor(property.author).add(pinnedProperty); - log.trace(`Pinning initiated for property ${property.assetInstanceID}/${property.assetInstanceID}/${property.key} in batch ${batchID}`); - return batchID; - } - - private async processBatch(batch: IDBBatch) { - // Extract the hashable portion, and write it to IPFS, and store the hash - const pinnedBatch: IPinnedBatch = { - type: batch.type, - created: batch.created, - author: batch.author, - completed: batch.completed, - batchID: batch.batchID, - records: batch.records, - }; - batch.batchHash = utils.ipfsHashToSha256(await ipfs.uploadString(JSON.stringify(pinnedBatch)));; - - let apiGatewayResponse: IAPIGatewayAsyncResponse | IAPIGatewaySyncResponse; - apiGatewayResponse = await apiGateway.createAssetInstanceBatch(batch.batchHash, batch.author, batch.participants); - batch.receipt = apiGatewayResponse.type === 'async' ? apiGatewayResponse.id : undefined; - - // The batch processor who called us does the store back to the local MongoDB, as part of completing the batch - } - -} - -/** - * Singleton instance - */ -export const assetInstancesPinning = new AssetInstancesPinning(); diff --git a/kat/src/handlers/asset-instances.ts b/kat/src/handlers/asset-instances.ts deleted file mode 100644 index 5250599793..0000000000 --- a/kat/src/handlers/asset-instances.ts +++ /dev/null @@ -1,542 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import Ajv from 'ajv'; -import { v4 as uuidV4 } from 'uuid'; -import * as apiGateway from '../clients/api-gateway'; -import * as app2app from '../clients/app2app'; -import * as database from '../clients/database'; -import * as docExchange from '../clients/doc-exchange'; -import * as ipfs from '../clients/ipfs'; -import { config } from '../lib/config'; -import { IAPIGatewayAsyncResponse, IAPIGatewaySyncResponse, IAssetInstance, IAssetInstancePropertySet, IAssetTradePrivateAssetInstancePush, IBatchRecord, IDBAssetInstance, IDBBlockchainData, IEventAssetInstanceBatchCreated, IEventAssetInstanceCreated, IEventAssetInstancePropertySet, IPendingAssetInstancePrivateContentDelivery, BatchRecordType } from '../lib/interfaces'; -import RequestError from '../lib/request-handlers'; -import * as utils from '../lib/utils'; -import { assetInstancesPinning } from './asset-instances-pinning'; -import * as assetTrade from './asset-trade'; - - -const log = utils.getLogger('handlers/asset-instances.ts'); - -const ajv = new Ajv(); - -export let pendingAssetInstancePrivateContentDeliveries: { [assetInstanceID: string]: IPendingAssetInstancePrivateContentDelivery } = {}; - -export const handleGetAssetInstancesRequest = (assetDefinitionID: string, query: object, sort: object, skip: number, limit: number) => { - return database.retrieveAssetInstances(assetDefinitionID, query, sort, skip, limit); -}; - -export const handleCountAssetInstancesRequest = async (assetDefinitionID: string, query: object) => { - return { count: await database.countAssetInstances(assetDefinitionID, query) }; -}; - -export const handleGetAssetInstanceRequest = async (assetDefinitionID: string, assetInstanceID: string, content: boolean) => { - const assetInstance = await database.retrieveAssetInstanceByID(assetDefinitionID, assetInstanceID); - if (assetInstance === null) { - throw new RequestError('Asset instance not found', 404); - } - const assetDefinition = await database.retrieveAssetDefinitionByID(assetDefinitionID); - if (assetDefinition === null) { - throw new RequestError('Asset definition not found', 500); - } - if (content) { - if (assetDefinition.contentSchema) { - return assetInstance.content; - } else { - try { - return await docExchange.downloadStream(utils.getUnstructuredFilePathInDocExchange(assetInstance.assetInstanceID)); - } catch (err) { - if (err.response?.status === 404) { - throw new RequestError('Asset instance content not present in off-chain storage', 404); - } else { - throw new RequestError(`Failed to obtain asset content from off-chain storage. ${err}`, 500); - } - } - } - } - return assetInstance; -}; - -export const handleCreateStructuredAssetInstanceRequest = async (author: string, assetDefinitionID: string, description: Object | undefined, content: Object, isContentPrivate: boolean | undefined, participants: string[] | undefined, sync: boolean) => { - let descriptionHash: string | undefined; - let contentHash: string; - const assetDefinition = await database.retrieveAssetDefinitionByID(assetDefinitionID); - if (assetDefinition === null) { - throw new RequestError('Unknown asset definition', 400); - } - if (assetDefinition.conflict === true) { - throw new RequestError('Cannot instantiate assets of conflicted definition', 400); - } - // For ethereum, we need to make assert definition transaction is mined - if (config.protocol === 'ethereum' && assetDefinition.transactionHash === undefined) { - throw new RequestError('Asset definition transaction must be mined', 400); - } - if (!assetDefinition.contentSchema) { - throw new RequestError('Unstructured asset instances must be created using multipart/form-data', 400); - } - if (assetDefinition.descriptionSchema) { - if (!description) { - throw new RequestError('Missing asset description', 400); - } - if (!ajv.validate(assetDefinition.descriptionSchema, description)) { - throw new RequestError('Description does not conform to asset definition schema', 400); - } - descriptionHash = `0x${utils.getSha256(JSON.stringify(description))}`; - } - if (!ajv.validate(assetDefinition.contentSchema, content)) { - throw new RequestError('Content does not conform to asset definition schema', 400); - } - if(isContentPrivate === undefined) { - isContentPrivate = assetDefinition.isContentPrivate; - } - contentHash = `0x${utils.getSha256(JSON.stringify(content))}`; - if (assetDefinition.isContentUnique && (await database.retrieveAssetInstanceByDefinitionIDAndContentHash(assetDefinition.assetDefinitionID, contentHash)) !== null) { - throw new RequestError(`Asset instance content conflict`); - } - if (config.protocol === 'corda') { - // validate participants are registered members - if (participants !== undefined) { - for (const participant of participants) { - if (await database.retrieveMemberByAddress(participant) === null) { - throw new RequestError('One or more participants are not registered', 400); - } - } - } else { - throw new RequestError('Missing asset participants', 400); - } - } - const assetInstanceID = uuidV4(); - const timestamp = utils.getTimestamp(); - const assetInstance: IAssetInstance = { - assetInstanceID, - author, - assetDefinitionID, - descriptionHash, - description, - contentHash, - content, - isContentPrivate - }; - - let dbAssetInstance: IDBAssetInstance = assetInstance; - dbAssetInstance.submitted = timestamp; - if (config.protocol === 'corda') { - dbAssetInstance.participants = participants; - } - // If there are public IPFS shared parts of this instance, we can batch it together with all other - // assets we are publishing for performance. Reducing both the data we write to the blockchain, and - // most importantly the number of IPFS transactions. - // Curently we do batch only for ethereum - if ((assetDefinition.descriptionSchema || !isContentPrivate) && config.protocol === 'ethereum') { - dbAssetInstance.batchID = await assetInstancesPinning.pin(assetInstance); - await database.upsertAssetInstance(dbAssetInstance); - log.info(`Structured asset instance batch ${dbAssetInstance.batchID} saved in local database and pinned to blockchain`); - } else { - await database.upsertAssetInstance(dbAssetInstance); - // One-for-one blockchain transactions to instances - let apiGatewayResponse: IAPIGatewayAsyncResponse | IAPIGatewaySyncResponse; - if (descriptionHash) { - apiGatewayResponse = await apiGateway.createDescribedAssetInstance(assetInstanceID, assetDefinitionID, author, descriptionHash, contentHash, participants, sync); - } else { - apiGatewayResponse = await apiGateway.createAssetInstance(assetInstanceID, assetDefinitionID, author, contentHash, participants, sync); - } - log.info(`Structured asset instance ${assetInstanceID} saved in local database and pinning transaction submitted to the blockchain`); - // dbAssetInstance.receipt = apiGatewayResponse.type === 'async' ? apiGatewayResponse.id : undefined; - if(apiGatewayResponse.type === 'async') { - await database.setAssetInstanceReceipt(assetDefinitionID, assetInstanceID, apiGatewayResponse.id); - log.trace(`Structured asset instance ${assetInstanceID} published in the blockchain (gateway receipt=${apiGatewayResponse.id})`); - } - } - return assetInstanceID; -}; - -export const handleCreateUnstructuredAssetInstanceRequest = async (author: string, assetDefinitionID: string, description: Object | undefined, content: NodeJS.ReadableStream, filename: string, isContentPrivate: boolean | undefined, participants: string[] | undefined, sync: boolean) => { - let descriptionHash: string | undefined; - let contentHash: string; - const assetDefinition = await database.retrieveAssetDefinitionByID(assetDefinitionID); - if (assetDefinition === null) { - throw new RequestError('Unknown asset definition', 400); - } - if (assetDefinition.contentSchema) { - throw new RequestError('Structured asset instances must be created using JSON', 400); - } - if (assetDefinition.descriptionSchema) { - if (!ajv.validate(assetDefinition.descriptionSchema, description)) { - throw new RequestError('Description does not conform to asset definition schema', 400); - } - descriptionHash = utils.ipfsHashToSha256(await ipfs.uploadString(JSON.stringify(description))); - } - if(isContentPrivate === undefined) { - isContentPrivate = assetDefinition.isContentPrivate; - } - const assetInstanceID = uuidV4(); - if (assetDefinition.isContentPrivate) { - contentHash = `0x${await docExchange.uploadStream(content, utils.getUnstructuredFilePathInDocExchange(assetInstanceID))}`; - } else { - contentHash = utils.ipfsHashToSha256(await ipfs.uploadString(JSON.stringify(content))); - } - if (assetDefinition.isContentUnique && (await database.retrieveAssetInstanceByDefinitionIDAndContentHash(assetDefinitionID, contentHash)) !== null) { - throw new RequestError('Asset instance content conflict', 409); - } - if (config.protocol === 'corda') { - // validate participants are registered - if (participants) { - for (const participant of participants) { - if (await database.retrieveMemberByAddress(participant) === null) { - throw new RequestError(`One or more participants are not registered`, 400); - } - } - } else { - throw new RequestError(`Missing asset participants`, 400); - } - } - let apiGatewayResponse: IAPIGatewayAsyncResponse | IAPIGatewaySyncResponse; - const timestamp = utils.getTimestamp(); - await database.upsertAssetInstance({ - assetInstanceID, - author, - assetDefinitionID, - descriptionHash, - description, - contentHash, - filename, - isContentPrivate, - participants, - submitted: timestamp - }); - if (descriptionHash) { - apiGatewayResponse = await apiGateway.createDescribedAssetInstance(assetInstanceID, assetDefinitionID, author, descriptionHash, contentHash, participants, sync); - } else { - apiGatewayResponse = await apiGateway.createAssetInstance(assetInstanceID, assetDefinitionID, author, contentHash, participants, sync); - } - log.info(`Unstructured asset instance ${assetInstanceID} saved in local database and pinning transaction submitted to the blockchain`); - if(apiGatewayResponse.type === 'async') { - await database.setAssetInstanceReceipt(assetDefinitionID, assetInstanceID, apiGatewayResponse.id); - log.trace(`Unstructured asset instance ${assetInstanceID} published in the blockchain (gateway receipt=${apiGatewayResponse.id})`); - } - return assetInstanceID; -} - -export const handleSetAssetInstancePropertyRequest = async (assetDefinitionID: string, assetInstanceID: string, author: string, key: string, value: string, sync: boolean) => { - const assetInstance = await database.retrieveAssetInstanceByID(assetDefinitionID, assetInstanceID); - if (assetInstance === null) { - throw new RequestError('Unknown asset instance', 400); - } - if (assetInstance.transactionHash === undefined) { - throw new RequestError('Asset instance transaction must be mined', 400); - } - if (assetInstance.properties) { - const authorMetadata = assetInstance.properties[author]; - if (authorMetadata) { - const valueData = authorMetadata[key]; - if (valueData?.value === value && valueData.history !== undefined) { - const keys = Object.keys(valueData.history); - const lastConfirmedValue = valueData.history[keys[keys.length - 1]]; - if (lastConfirmedValue.value === value) { - throw new RequestError('Property already set', 409); - } - } - } - } - const submitted = utils.getTimestamp(); - if (config.protocol === 'ethereum') { - const property: IAssetInstancePropertySet = { - assetDefinitionID, - assetInstanceID, - author, - key, - value, - }; - const batchID = await assetInstancesPinning.pinProperty(property); - await database.setSubmittedAssetInstanceProperty(assetDefinitionID, assetInstanceID, author, key, value, submitted, batchID); - log.info(`Asset instance property ${key} (instance=${assetInstanceID}) set via batch`); - } else { - await database.setSubmittedAssetInstanceProperty(assetDefinitionID, assetInstanceID, author, key, value, submitted); - log.info(`Asset instance property ${key} (instance=${assetInstanceID}) set in local database`); - const apiGatewayResponse = await apiGateway.setAssetInstanceProperty(assetDefinitionID, assetInstanceID, author, key, value, assetInstance.participants, sync); - if(apiGatewayResponse.type === 'async') { - await database.setAssetInstancePropertyReceipt(assetDefinitionID, assetInstanceID, author, key, apiGatewayResponse.id); - } - log.info(`Asset instance property ${key} (instance=${assetInstanceID}) pinning transaction submitted to blockchain`); - } - -}; - -export const handleAssetInstanceBatchCreatedEvent = async (event: IEventAssetInstanceBatchCreated, { blockNumber, transactionHash }: IDBBlockchainData) => { - - let batch = await database.retrieveBatchByHash(event.batchHash); - if (!batch) { - batch = await ipfs.downloadJSON(utils.sha256ToIPFSHash(event.batchHash)); - } - if (!batch) { - throw new Error('Unknown batch hash: ' + event.batchHash); - } - - // Process each record within the batch, as if it is an individual event - const records: IBatchRecord[] = batch.records || []; - for (let record of records) { - if (!record.recordType || record.recordType === BatchRecordType.assetInstance) { - const recordEvent: IEventAssetInstanceCreated = { - assetDefinitionID: '', - assetInstanceID: '', - author: record.author, - contentHash: record.contentHash!, - descriptionHash: record.descriptionHash!, - timestamp: event.timestamp, - isContentPrivate: record.isContentPrivate - }; - try { - await handleAssetInstanceCreatedEvent(recordEvent, { blockNumber, transactionHash }, record); - } catch (err) { - // We failed to process this record, but continue to attempt the other records in the batch - log.error(`Record ${record.assetDefinitionID}/${record.assetInstanceID} in batch ${batch.batchID} with hash ${event.batchHash} failed`, err.stack); - } - } else if (record.recordType === BatchRecordType.assetProperty) { - try { - const propertyEvent: IEventAssetInstancePropertySet = { - assetDefinitionID: record.assetDefinitionID, - assetInstanceID: record.assetInstanceID, - author: record.author, - key: record.key, - value: record.value, - timestamp: event.timestamp, - }; - await handleSetAssetInstancePropertyEvent(propertyEvent, { blockNumber, transactionHash }, true); - } catch (err) { - // We failed to process this record, but continue to attempt the other records in the batch - log.error(`Property ${record.assetDefinitionID}/${record.assetInstanceID}/${record.key} in batch ${batch.batchID} with hash ${event.batchHash} failed`, err.stack); - } - } else { - log.error(`Batch record type '${record.recordType}' not known`, record); - } - } - - // Write the batch itself to our local database - await database.upsertBatch({ - ...batch, - timestamp: Number(event.timestamp), - blockNumber, - transactionHash - }); - log.info(`Asset instance batch ${event.batchHash} from blockchain event (blockNumber=${blockNumber} hash=${transactionHash}) saved in local database`); - -} - -export const handleAssetInstanceCreatedEvent = async (event: IEventAssetInstanceCreated, { blockNumber, transactionHash }: IDBBlockchainData, batchInstance?: IBatchRecord) => { - let eventAssetInstanceID: string; - let eventAssetDefinitionID: string; - if (batchInstance === undefined) { - switch (config.protocol) { - case 'corda': - eventAssetInstanceID = event.assetInstanceID; - eventAssetDefinitionID = event.assetDefinitionID; - break; - case 'ethereum': - eventAssetInstanceID = utils.hexToUuid(event.assetInstanceID); - eventAssetDefinitionID = utils.hexToUuid(event.assetDefinitionID); - break; - } - } else { - eventAssetInstanceID = batchInstance.assetInstanceID; - eventAssetDefinitionID = batchInstance.assetDefinitionID; - log.info(`batch instance ${eventAssetDefinitionID}:${eventAssetInstanceID}`); - } - const dbAssetInstance = await database.retrieveAssetInstanceByID(eventAssetDefinitionID, eventAssetInstanceID); - if (dbAssetInstance !== null && dbAssetInstance.transactionHash !== undefined) { - throw new Error(`Duplicate asset instance ID`); - } - const assetDefinition = await database.retrieveAssetDefinitionByID(eventAssetDefinitionID); - if (assetDefinition === null) { - throw new Error('Unkown asset definition'); - } - // For ethereum, we need to make asset definition transaction is mined - if (config.protocol === 'ethereum' && assetDefinition.transactionHash === undefined) { - throw new Error('Asset definition transaction must be mined'); - } - if (assetDefinition.isContentUnique) { - const assetInstanceByContentID = await database.retrieveAssetInstanceByDefinitionIDAndContentHash(eventAssetDefinitionID, event.contentHash); - if (assetInstanceByContentID !== null && eventAssetInstanceID !== assetInstanceByContentID.assetInstanceID) { - if (assetInstanceByContentID.transactionHash !== undefined) { - throw new Error(`Asset instance content conflict ${event.contentHash}`); - } else { - await database.markAssetInstanceAsConflict(eventAssetDefinitionID, assetInstanceByContentID.assetInstanceID, Number(event.timestamp)); - } - } - } - let description: Object | undefined = batchInstance?.description; - if (assetDefinition.descriptionSchema && !description) { - if (event.descriptionHash) { - if (event.descriptionHash === dbAssetInstance?.descriptionHash) { - description = dbAssetInstance.description; - } else { - description = await ipfs.downloadJSON(utils.sha256ToIPFSHash(event.descriptionHash)); - if (!ajv.validate(assetDefinition.descriptionSchema, description)) { - throw new Error('Description does not conform to schema'); - } - } - } else { - throw new Error('Missing asset instance description'); - } - } - let content: Object | undefined = batchInstance?.content; - if (assetDefinition.contentSchema && !content) { - if (event.contentHash === dbAssetInstance?.contentHash) { - content = dbAssetInstance.content; - } else if (!assetDefinition.isContentPrivate) { - content = await ipfs.downloadJSON(utils.sha256ToIPFSHash(event.contentHash)); - if (!ajv.validate(assetDefinition.contentSchema, content)) { - throw new Error('Content does not conform to schema'); - } - } - } - log.trace(`Updating asset instance ${eventAssetInstanceID} with blockchain pinned info blockNumber=${blockNumber} hash=${transactionHash}`); - let assetInstanceDB: IDBAssetInstance = { - assetInstanceID: eventAssetInstanceID, - author: event.author, - assetDefinitionID: assetDefinition.assetDefinitionID, - descriptionHash: event.descriptionHash, - description, - contentHash: event.contentHash, - timestamp: Number(event.timestamp), - content, - blockNumber, - transactionHash, - isContentPrivate: event.isContentPrivate ?? assetDefinition.isContentPrivate - }; - if (config.protocol === 'corda') { - assetInstanceDB.participants = event.participants; - } - await database.upsertAssetInstance(assetInstanceDB); - if (assetInstanceDB.isContentPrivate) { - const privateData = pendingAssetInstancePrivateContentDeliveries[eventAssetInstanceID]; - if (privateData !== undefined) { - const author = await database.retrieveMemberByAddress(event.author); - if (author === null) { - throw new Error('Pending private data author unknown'); - } - if (author.app2appDestination !== privateData.fromDestination) { - throw new Error('Pending private data destination mismatch'); - } - if (privateData.content !== undefined) { - const privateDataHash = `0x${utils.getSha256(JSON.stringify(privateData.content))}`; - if (privateDataHash !== event.contentHash) { - throw new Error('Pending private data content hash mismatch'); - } - } - await database.setAssetInstancePrivateContent(eventAssetDefinitionID, eventAssetInstanceID, privateData.content, privateData.filename); - delete pendingAssetInstancePrivateContentDeliveries[eventAssetInstanceID]; - } - } - log.info(`Asset instance ${eventAssetDefinitionID}/${eventAssetInstanceID} from blockchain event (blockNumber=${blockNumber} hash=${transactionHash}) saved in local database`); -}; - -export const handleSetAssetInstancePropertyEvent = async (event: IEventAssetInstancePropertySet, blockchainData: IDBBlockchainData, isBatch?: boolean) => { - let eventAssetInstanceID: string; - let eventAssetDefinitionID: string; - if (config.protocol === 'corda' || isBatch) { - eventAssetInstanceID = event.assetInstanceID; - eventAssetDefinitionID = event.assetDefinitionID; - } else { - eventAssetInstanceID = utils.hexToUuid(event.assetInstanceID); - eventAssetDefinitionID = utils.hexToUuid(event.assetDefinitionID); - } - const dbAssetInstance = await database.retrieveAssetInstanceByID(eventAssetDefinitionID, eventAssetInstanceID); - if (dbAssetInstance === null) { - throw new Error('Uknown asset instance'); - } - if (dbAssetInstance.transactionHash === undefined) { - throw new Error('Unconfirmed asset instance'); - } - if (!event.key) { - throw new Error('Invalid property key'); - } - await database.setConfirmedAssetInstanceProperty(eventAssetDefinitionID, eventAssetInstanceID, event.author, event.key, event.value, Number(event.timestamp), blockchainData); - log.info(`Asset instance property ${event.key} (instance=${eventAssetDefinitionID}) from blockchain event (blockNumber=${blockchainData.blockNumber} hash=${blockchainData.transactionHash}) saved in local database`); -}; - -export const handleAssetInstanceTradeRequest = async (assetDefinitionID: string, requesterAddress: string, assetInstanceID: string, metadata: object | undefined) => { - const assetInstance = await database.retrieveAssetInstanceByID(assetDefinitionID, assetInstanceID); - if (assetInstance === null) { - throw new RequestError('Uknown asset instance', 404); - } - const author = await database.retrieveMemberByAddress(assetInstance.author); - if (author === null) { - throw new RequestError('Asset author must be registered', 400); - } - if (author.assetTrailInstanceID === config.assetTrailInstanceID) { - throw new RequestError('Asset instance authored', 400); - } - const assetDefinition = await database.retrieveAssetDefinitionByID(assetDefinitionID); - if (assetDefinition === null) { - throw new RequestError('Unknown asset definition', 500); - } - if (assetDefinition.contentSchema !== undefined) { - if (assetInstance.content !== undefined) { - throw new RequestError('Asset content already available', 400); - } - } else { - try { - const documentDetails = await docExchange.getDocumentDetails(utils.getUnstructuredFilePathInDocExchange(assetInstanceID)); - if (documentDetails.hash === assetInstance.contentHash) { - throw new RequestError('Asset content already available', 400); - } - } catch (err) { - if (err.response?.status !== 404) { - throw new RequestError(err, 500); - } - } - } - const requester = await database.retrieveMemberByAddress(requesterAddress); - if (requester === null) { - throw new RequestError('Requester must be registered', 400); - } - await assetTrade.coordinateAssetTrade(assetInstance, assetDefinition, requester.address, metadata, author.app2appDestination); - log.info(`Asset instance trade request from requester ${requesterAddress} (instance=${assetInstanceID}) successfully completed`); -}; - -export const handlePushPrivateAssetInstanceRequest = async (assetDefinitionID: string, assetInstanceID: string, memberAddress: string) => { - const member = await database.retrieveMemberByAddress(memberAddress); - if (member === null) { - throw new RequestError('Unknown member', 400); - } - const assetInstance = await database.retrieveAssetInstanceByID(assetDefinitionID, assetInstanceID); - if (assetInstance === null) { - throw new RequestError('Unknown asset instance', 400); - } - const author = await database.retrieveMemberByAddress(assetInstance.author); - if (author === null) { - throw new RequestError('Unknown asset author', 500); - } - if (author.assetTrailInstanceID !== config.assetTrailInstanceID) { - throw new RequestError('Must be asset instance author', 403); - } - const assetDefinition = await database.retrieveAssetDefinitionByID(assetInstance.assetDefinitionID); - if (assetDefinition === null) { - throw new RequestError('Unknown asset definition', 500); - } - let privateAssetTradePrivateInstancePush: IAssetTradePrivateAssetInstancePush = { - type: 'private-asset-instance-push', - assetInstanceID, - assetDefinitionID - }; - if (assetDefinition.contentSchema !== undefined) { - privateAssetTradePrivateInstancePush.content = assetInstance.content; - } else { - await docExchange.transfer(author.docExchangeDestination, member.docExchangeDestination, - utils.getUnstructuredFilePathInDocExchange(assetInstanceID)); - privateAssetTradePrivateInstancePush.filename = assetInstance.filename; - log.info(`Private asset instance push request for member ${memberAddress} (instance=${assetInstanceID}) successfully completed`); - } - app2app.dispatchMessage(member.app2appDestination, privateAssetTradePrivateInstancePush); -}; diff --git a/kat/src/handlers/asset-trade.ts b/kat/src/handlers/asset-trade.ts deleted file mode 100644 index f8a266899f..0000000000 --- a/kat/src/handlers/asset-trade.ts +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { v4 as uuidV4 } from 'uuid'; -import Ajv from 'ajv'; -import { config } from '../lib/config'; -import { AssetTradeMessage, IApp2AppMessageHeader, IApp2AppMessageListener, IAssetTradePrivateAssetInstanceAuthorizationRequest, IAssetTradePrivateAssetInstancePush, IAssetTradePrivateAssetInstanceRequest, IAssetTradePrivateAssetInstanceResponse, IDBAssetDefinition, IDBAssetInstance, IDBMember, IDocExchangeListener, IDocExchangeTransferData } from "../lib/interfaces"; -import * as utils from '../lib/utils'; -import * as database from '../clients/database'; -import * as app2app from '../clients/app2app'; -import * as docExchange from '../clients/doc-exchange'; -import { pendingAssetInstancePrivateContentDeliveries } from './asset-instances'; -const log = utils.getLogger('handlers/asset-trade.ts'); - -const ajv = new Ajv(); - -export const assetTradeHandler = (headers: IApp2AppMessageHeader, content: AssetTradeMessage) => { - if (content.type === 'private-asset-instance-request') { - processPrivateAssetInstanceRequest(headers, content); - } else if (content.type === 'private-asset-instance-push') { - processPrivateAssetInstancePush(headers, content); - } -}; - -const processPrivateAssetInstanceRequest = async (headers: IApp2AppMessageHeader, request: IAssetTradePrivateAssetInstanceRequest) => { - let tradeResponse: IAssetTradePrivateAssetInstanceResponse = { - type: "private-asset-instance-response", - tradeID: request.tradeID, - assetInstanceID: request.assetInstanceID - }; - const requester = await database.retrieveMemberByAddress(request.requester.address); - try { - if (requester === null) { - throw new Error(`Unknown requester ${request.requester.address}`); - } - if (requester.assetTrailInstanceID !== request.requester.assetTrailInstanceID) { - throw new Error(`Requester asset trail instance mismatch. Expected ${requester.assetTrailInstanceID}, ` + - `actual ${request.requester.assetTrailInstanceID}`); - } - if (requester.app2appDestination !== headers.from) { - throw new Error(`Requester App2App destination mismatch. Expected ${requester.app2appDestination}, ` + - `actual ${headers.from}`); - } - const assetInstance = await database.retrieveAssetInstanceByID(request.assetDefinitionID, request.assetInstanceID); - if (assetInstance === null) { - throw new Error(`Unknown asset instance ${request.assetInstanceID}`); - } - const author = await database.retrieveMemberByAddress(assetInstance.author); - if (author === null) { - throw new Error(`Unknown asset instance author`); - } - if (author.assetTrailInstanceID !== config.assetTrailInstanceID) { - throw new Error(`Asset instance ${assetInstance.assetInstanceID} not authored`); - } - const assetDefinition = await database.retrieveAssetDefinitionByID(assetInstance.assetDefinitionID); - if (assetDefinition === null) { - throw new Error(`Unknown asset definition ${assetInstance.assetDefinitionID}`); - } - if (!assetDefinition.isContentPrivate) { - throw new Error(`Asset instance ${assetInstance.assetInstanceID} not private`); - } - const authorized = await handlePrivateAssetInstanceAuthorization(assetInstance, requester, request.metadata); - if (authorized !== true) { - throw new Error('Access denied'); - } - if (assetDefinition.contentSchema) { - tradeResponse.content = assetInstance.content; - } else { - await docExchange.transfer(config.docExchange.destination, requester.docExchangeDestination, - utils.getUnstructuredFilePathInDocExchange(request.assetInstanceID)); - tradeResponse.filename = assetInstance.filename; - log.info(`Private asset instance trade request (instance=${assetInstance.assetDefinitionID}, requester=${request.requester.address}, tradeId=${request.tradeID}) successfully completed`); - } - } catch (err) { - tradeResponse.rejection = err.message; - } finally { - app2app.dispatchMessage(headers.from, tradeResponse); - } -}; - -const handlePrivateAssetInstanceAuthorization = (assetInstance: IDBAssetInstance, requester: IDBMember, metadata: object | undefined): Promise => { - return new Promise((resolve, reject) => { - const authorizationID = uuidV4(); - const authorizationRequest: IAssetTradePrivateAssetInstanceAuthorizationRequest = { - type: 'private-asset-instance-authorization-request', - authorizationID, - assetInstance, - requester, - metadata - }; - const timeout = setTimeout(() => { - app2app.removeListener(app2appListener); - reject(new Error('Asset instance authorization response timed out')); - }, utils.constants.TRADE_AUTHORIZATION_TIMEOUT_SECONDS * 1000); - const app2appListener: IApp2AppMessageListener = (headers: IApp2AppMessageHeader, content: AssetTradeMessage) => { - if (headers.from === config.app2app.destinations.client && content.type === 'private-asset-instance-authorization-response' && - content.authorizationID === authorizationID) { - clearTimeout(timeout); - app2app.removeListener(app2appListener); - resolve(content.authorized); - } - }; - app2app.addListener(app2appListener); - app2app.dispatchMessage(config.app2app.destinations.client, authorizationRequest); - }); -}; - -export const coordinateAssetTrade = async (assetInstance: IDBAssetInstance, assetDefinition: IDBAssetDefinition, - requesterAddress: string, metadata: object | undefined, authorDestination: string) => { - const tradeID = uuidV4(); - const tradeRequest: IAssetTradePrivateAssetInstanceRequest = { - type: 'private-asset-instance-request', - tradeID, - assetInstanceID: assetInstance.assetInstanceID, - assetDefinitionID: assetInstance.assetDefinitionID, - requester: { - assetTrailInstanceID: config.assetTrailInstanceID, - address: requesterAddress - }, - metadata - }; - const docExchangePromise = assetDefinition.contentSchema === undefined ? getDocumentExchangePromise(assetInstance.assetInstanceID) : Promise.resolve(); - const app2appPromise: Promise = new Promise((resolve, reject) => { - const timeout = setTimeout(() => { - app2app.removeListener(app2appListener); - reject(new Error('Asset instance author response timed out')); - }, utils.constants.ASSET_INSTANCE_TRADE_TIMEOUT_SECONDS * 1000); - const app2appListener: IApp2AppMessageListener = (_headers: IApp2AppMessageHeader, content: AssetTradeMessage) => { - if (content.type === 'private-asset-instance-response' && content.tradeID === tradeID) { - clearTimeout(timeout); - app2app.removeListener(app2appListener); - if (content.rejection) { - reject(new Error(`Asset instance request rejected. ${content.rejection}`)); - } else { - const contentHash = `0x${utils.getSha256(JSON.stringify(content.content))}`; - if (contentHash !== assetInstance.contentHash) { - reject(new Error('Asset instance content hash mismatch')); - } else if (assetDefinition.contentSchema && !ajv.validate(assetDefinition.contentSchema, content.content)) { - reject(new Error('Asset instance content does not conform to schema')); - } else { - database.setAssetInstancePrivateContent(assetInstance.assetDefinitionID, content.assetInstanceID, content.content, content.filename); - resolve(); - } - } - } - }; - app2app.addListener(app2appListener); - app2app.dispatchMessage(authorDestination, tradeRequest); - }); - await Promise.all([app2appPromise, docExchangePromise]); -}; - -const getDocumentExchangePromise = (assetInstanceID: string): Promise => { - return new Promise((resolve, reject) => { - const timeout = setTimeout(() => { - docExchange.removeListener(docExchangeListener); - reject(new Error('Off-chain asset transfer timeout')); - }, utils.constants.DOCUMENT_EXCHANGE_TRANSFER_TIMEOUT_SECONDS * 1000); - const docExchangeListener: IDocExchangeListener = (event: IDocExchangeTransferData) => { - if (event.document === utils.getUnstructuredFilePathInDocExchange(assetInstanceID)) { - clearTimeout(timeout); - docExchange.removeListener(docExchangeListener); - resolve(); - } - }; - docExchange.addListener(docExchangeListener); - }); -}; - -const processPrivateAssetInstancePush = async (headers: IApp2AppMessageHeader, push: IAssetTradePrivateAssetInstancePush) => { - log.trace(`Handling private asset instance push event (instance=${push.assetInstanceID}, filename=${push.filename})`); - const assetInstance = await database.retrieveAssetInstanceByID(push.assetDefinitionID, push.assetInstanceID); - if (assetInstance !== null) { - log.trace(`Found existing asset instance, ${JSON.stringify(assetInstance, null, 2)}`); - const author = await database.retrieveMemberByAddress(assetInstance.author); - if (author === null) { - throw new Error(`Unknown author for asset ${assetInstance.assetInstanceID}`); - } - if (author.app2appDestination !== headers.from) { - throw new Error(`Asset instance author destination mismatch ${author.app2appDestination} - ${headers.from}`); - } - if (push.content) { - const contentHash = `0x${utils.getSha256(JSON.stringify(push.content))}`; - if (assetInstance.contentHash !== contentHash) { - throw new Error('Private asset content hash mismatch'); - } - } - await database.setAssetInstancePrivateContent(push.assetDefinitionID, push.assetInstanceID, push.content, push.filename); - log.info(`Private asset instance from push event (instance=${push.assetInstanceID}, filename=${push.filename}) saved in local database`); - } else { - log.info(`Private asset instance ${push.assetDefinitionID}/${push.assetInstanceID} from push event not found in local database, adding to pending instances`); - pendingAssetInstancePrivateContentDeliveries[push.assetInstanceID] = { ...push, fromDestination: headers.from }; - } -} diff --git a/kat/src/handlers/batches.ts b/kat/src/handlers/batches.ts deleted file mode 100644 index 74170c5e8e..0000000000 --- a/kat/src/handlers/batches.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import * as database from '../clients/database'; -import RequestError from '../lib/request-handlers'; - -export const handleGetBatchRequest = async (batchID: string) => { - const batch = await database.retrieveBatchByID(batchID); - if (batch === null) { - throw new RequestError('Asset instance not found', 404); - } - return batch; -}; diff --git a/kat/src/handlers/client-events.ts b/kat/src/handlers/client-events.ts deleted file mode 100644 index 409db2f647..0000000000 --- a/kat/src/handlers/client-events.ts +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { ClientEventType } from "../lib/interfaces"; -import { config } from '../lib/config'; -import { settings } from '../lib/settings'; -import * as utils from '../lib/utils'; -import * as app2app from '../clients/app2app'; - -const log = utils.getLogger('handlers/client-events.ts'); - -export const clientEventHandler = (eventType: ClientEventType, content: object) => { - if (settings.clientEvents.includes(eventType)) { - log.info(`Dispatched client event ${eventType}`); - app2app.dispatchMessage(config.app2app.destinations.client, { type: eventType, content }); - } -}; diff --git a/kat/src/handlers/members.ts b/kat/src/handlers/members.ts deleted file mode 100644 index 901b6a0dad..0000000000 --- a/kat/src/handlers/members.ts +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import * as database from '../clients/database'; -import * as apiGateway from '../clients/api-gateway'; -import * as utils from '../lib/utils'; -import { IDBBlockchainData, IDBMember, IEventMemberRegistered } from '../lib/interfaces'; -import RequestError from '../lib/request-handlers'; -import { config } from '../lib/config'; - -export const handleGetMembersRequest = (query: object, skip: number, limit: number) => { - return database.retrieveMembers(query, skip, limit); -}; - -export const handleGetMemberRequest = async (address: string) => { - const member = await database.retrieveMemberByAddress(address); - if (member === null) { - throw new RequestError('Member not found', 404); - } - return member; -}; - -export const handleUpsertMemberRequest = async (address: string, name: string, assetTrailInstanceID: string, app2appDestination: string, docExchangeDestination: string, sync: boolean) => { - const timestamp = utils.getTimestamp(); - let memberDB: IDBMember = { - address, - name, - assetTrailInstanceID, - app2appDestination, - docExchangeDestination, - submitted: timestamp - }; - if(config.protocol === 'ethereum') { - const apiGatewayResponse = await apiGateway.upsertMember(address, name, app2appDestination, docExchangeDestination, sync); - if(apiGatewayResponse.type === 'async') { - memberDB.receipt = apiGatewayResponse.id - } - } - await database.upsertMember(memberDB); -}; - -export const handleMemberRegisteredEvent = async ({ member, name, assetTrailInstanceID, app2appDestination, docExchangeDestination, timestamp }: - IEventMemberRegistered, { blockNumber, transactionHash}: IDBBlockchainData) => { - await database.upsertMember({ - address: member, - name, - app2appDestination, - docExchangeDestination, - assetTrailInstanceID, - timestamp: Number(timestamp), - blockNumber, - transactionHash - }); -}; diff --git a/kat/src/handlers/payment-definitions.ts b/kat/src/handlers/payment-definitions.ts deleted file mode 100644 index e1f085f5d2..0000000000 --- a/kat/src/handlers/payment-definitions.ts +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { v4 as uuidV4 } from 'uuid'; -import Ajv from 'ajv'; -import * as utils from '../lib/utils'; -import * as ipfs from '../clients/ipfs'; -import * as apiGateway from '../clients/api-gateway'; -import * as database from '../clients/database'; -import RequestError from '../lib/request-handlers'; -import { IAPIGatewayAsyncResponse, IAPIGatewaySyncResponse, IDBBlockchainData, IEventPaymentDefinitionCreated } from '../lib/interfaces'; - -const ajv = new Ajv(); - -export const handleGetPaymentDefinitionsRequest = (query: object, skip: number, limit: number) => { - return database.retrievePaymentDefinitions(query, skip, limit); -}; - -export const handleCountPaymentDefinitionsRequest = async (query: object) => { - return { count: await database.countPaymentDefinitions(query) }; -}; - -export const handleGetPaymentDefinitionRequest = async (paymentDefinitionID: string) => { - const paymentDefinition = await database.retrievePaymentDefinitionByID(paymentDefinitionID); - if (paymentDefinition === null) { - throw new RequestError('Payment definition not found', 404); - } - return paymentDefinition; -}; - -export const handleCreatePaymentDefinitionRequest = async (name: string, author: string, descriptionSchema: Object | undefined, sync: boolean) => { - if (descriptionSchema !== undefined && !ajv.validateSchema(descriptionSchema)) { - throw new RequestError('Invalid description schema', 400); - } - if (await database.retrievePaymentDefinitionByName(name) !== null) { - throw new RequestError('Payment definition name conflict', 409); - } - let descriptionSchemaHash: string | undefined; - let apiGatewayResponse: IAPIGatewayAsyncResponse | IAPIGatewaySyncResponse; - const timestamp = utils.getTimestamp(); - - const paymentDefinitionID = uuidV4(); - if (descriptionSchema) { - descriptionSchemaHash = utils.ipfsHashToSha256(await ipfs.uploadString(JSON.stringify(descriptionSchema))); - apiGatewayResponse = await apiGateway.createDescribedPaymentDefinition(paymentDefinitionID, name, author, descriptionSchemaHash, sync); - } else { - apiGatewayResponse = await apiGateway.createPaymentDefinition(paymentDefinitionID, name, author, sync); - } - const receipt = apiGatewayResponse.type === 'async' ? apiGatewayResponse.id : undefined; - await database.upsertPaymentDefinition({ - paymentDefinitionID, - name, - author, - descriptionSchemaHash, - descriptionSchema, - submitted: timestamp, - receipt - }); - return paymentDefinitionID; -}; - -export const handlePaymentDefinitionCreatedEvent = async (event: IEventPaymentDefinitionCreated, { blockNumber, transactionHash }: IDBBlockchainData) => { - const paymentDefinitionID = utils.hexToUuid(event.paymentDefinitionID); - const dbPaymentDefinitionByID = await database.retrievePaymentDefinitionByID(paymentDefinitionID); - if (dbPaymentDefinitionByID !== null) { - if (dbPaymentDefinitionByID.transactionHash !== undefined) { - throw new Error(`Payment definition ID conflict ${paymentDefinitionID}`); - } - } else { - const dbpaymentDefinitionByName = await database.retrievePaymentDefinitionByName(event.name); - if (dbpaymentDefinitionByName !== null) { - if (dbpaymentDefinitionByName.transactionHash !== undefined) { - throw new Error(`Payment definition name conflict ${event.name}`); - } else { - await database.markPaymentDefinitionAsConflict(dbpaymentDefinitionByName.paymentDefinitionID, Number(event.timestamp)); - } - } - } - let descriptionSchema; - if (event.descriptionSchemaHash) { - if (event.descriptionSchemaHash === dbPaymentDefinitionByID?.descriptionSchemaHash) { - descriptionSchema = dbPaymentDefinitionByID?.descriptionSchema - } else { - descriptionSchema = await ipfs.downloadJSON(utils.sha256ToIPFSHash(event.descriptionSchemaHash)); - } - } - database.upsertPaymentDefinition({ - paymentDefinitionID, - author: event.author, - name: event.name, - descriptionSchemaHash: event.descriptionSchemaHash, - descriptionSchema, - timestamp: Number(event.timestamp), - blockNumber, - transactionHash - }); -}; diff --git a/kat/src/handlers/payment-instances.ts b/kat/src/handlers/payment-instances.ts deleted file mode 100644 index e058e71607..0000000000 --- a/kat/src/handlers/payment-instances.ts +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import Ajv from 'ajv'; -import { v4 as uuidV4 } from 'uuid'; -import * as database from '../clients/database'; -import * as ipfs from '../clients/ipfs'; -import * as utils from '../lib/utils'; -import * as apiGateway from '../clients/api-gateway'; -import RequestError from '../lib/request-handlers'; -import { IAPIGatewayAsyncResponse, IAPIGatewaySyncResponse, IDBBlockchainData, IDBPaymentInstance, IEventPaymentInstanceCreated } from '../lib/interfaces'; -import { config } from '../lib/config'; - -const ajv = new Ajv(); - -export const handleGetPaymentInstancesRequest = (query: object, sort: object, skip: number, limit: number) => { - return database.retrievePaymentInstances(query, sort, skip, limit); -}; - -export const handleCountPaymentInstancesRequest = async (query: object) => { - return { count: await database.countPaymentInstances(query) }; -}; - -export const handleGetPaymentInstanceRequest = async (paymentInstanceID: string) => { - const assetInstance = await database.retrievePaymentInstanceByID(paymentInstanceID); - if (assetInstance === null) { - throw new RequestError('Payment instance not found', 404); - } - return assetInstance; -}; - -export const handleCreatePaymentInstanceRequest = async (author: string, paymentDefinitionID: string, - member: string, description: object | undefined, amount: number, participants: string[] | undefined, sync: boolean) => { - const paymentDefinition = await database.retrievePaymentDefinitionByID(paymentDefinitionID); - if (paymentDefinition === null) { - throw new RequestError('Unknown payment definition', 400); - } - if (paymentDefinition.transactionHash === undefined) { - throw new RequestError('Payment definition transaction must be mined', 400); - } - if(config.protocol === 'ethereum' && participants !== undefined) { - throw new RequestError('Participants not supported in Ethereum', 400); - } - if(config.protocol === 'corda') { - // validate participants are registered members - if(participants !== undefined) { - for(const participant of participants) { - if (await database.retrieveMemberByAddress(participant) === null) { - throw new RequestError('One or more participants are not registered', 400); - } - } - } else { - throw new RequestError('Missing payment participants', 400); - } - } - let descriptionHash: string | undefined; - if (paymentDefinition.descriptionSchema) { - if (!description) { - throw new RequestError('Missing payment description', 400); - } - if (!ajv.validate(paymentDefinition.descriptionSchema, description)) { - throw new RequestError('Description does not conform to payment definition schema', 400); - } - descriptionHash = utils.ipfsHashToSha256(await ipfs.uploadString(JSON.stringify(description))); - } - const paymentInstanceID = uuidV4(); - const timestamp = utils.getTimestamp(); - let apiGatewayResponse: IAPIGatewayAsyncResponse | IAPIGatewaySyncResponse; - if (descriptionHash) { - apiGatewayResponse = await apiGateway.createDescribedPaymentInstance(paymentInstanceID, - paymentDefinitionID, author, member, amount, descriptionHash, participants,sync); - } else { - apiGatewayResponse = await apiGateway.createPaymentInstance(paymentInstanceID, - paymentDefinitionID, author, member, amount, participants, sync); - } - const receipt = apiGatewayResponse.type === 'async' ? apiGatewayResponse.id : undefined; - await database.upsertPaymentInstance({ - paymentInstanceID, - author, - paymentDefinitionID: paymentDefinition.paymentDefinitionID, - descriptionHash, - description, - member, - participants, - amount, - receipt, - submitted: timestamp - }); - return paymentInstanceID; -}; - -export const handlePaymentInstanceCreatedEvent = async (event: IEventPaymentInstanceCreated, { blockNumber, transactionHash }: IDBBlockchainData) => { - let eventPaymentInstanceID: string; - let eventPaymentDefinitionID: string; - switch(config.protocol) { - case 'corda': - eventPaymentDefinitionID = event.paymentDefinitionID; - eventPaymentInstanceID = event.paymentInstanceID; - break; - case 'ethereum': - eventPaymentDefinitionID = utils.hexToUuid(event.paymentDefinitionID) - eventPaymentInstanceID = utils.hexToUuid(event.paymentInstanceID); - break; - } - const dbPaymentInstance = await database.retrievePaymentInstanceByID(eventPaymentInstanceID); - if (dbPaymentInstance !== null && dbPaymentInstance.transactionHash !== undefined) { - throw new Error(`Duplicate payment instance ID`); - } - const paymentDefinition = await database.retrievePaymentDefinitionByID(eventPaymentDefinitionID); - if (paymentDefinition === null) { - throw new Error('Uknown payment definition'); - } - if (config.protocol === 'ethereum' && paymentDefinition.transactionHash === undefined) { - throw new Error('Payment definition transaction must be mined'); - } - let description: Object | undefined = undefined; - if (paymentDefinition.descriptionSchema) { - if (event.descriptionHash) { - if (event.descriptionHash === dbPaymentInstance?.descriptionHash) { - description = dbPaymentInstance.description; - } else { - description = await ipfs.downloadJSON(utils.sha256ToIPFSHash(event.descriptionHash)); - if (!ajv.validate(paymentDefinition.descriptionSchema, description)) { - throw new Error('Description does not conform to schema'); - } - } - } else { - throw new Error('Missing payment instance description'); - } - } - let paymentInstanceDB: IDBPaymentInstance = { - paymentInstanceID: eventPaymentInstanceID, - author: event.author, - paymentDefinitionID: paymentDefinition.paymentDefinitionID, - descriptionHash: event.descriptionHash, - description, - member: event.member, - amount: Number(event.amount), - timestamp: Number(event.timestamp), - blockNumber, - transactionHash - }; - if(config.protocol === 'corda') { - paymentInstanceDB.participants = event.participants; - } - database.upsertPaymentInstance(paymentInstanceDB); -}; diff --git a/kat/src/index.ts b/kat/src/index.ts deleted file mode 100644 index 99a42b00af..0000000000 --- a/kat/src/index.ts +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { config, init as initConfig, shutDown as shutDownConfig } from './lib/config'; -import express from 'express'; -import bodyParser from 'body-parser'; -import membersRouter from './routers/members'; -import assetDefinitionsRouter from './routers/asset-definitions'; -import assetInstancesRouter from './routers/asset-instances'; -import paymentDefinitionsRouter from './routers/payment-definitions'; -import paymentInstancesRouter from './routers/payment-instances'; -import settingsRouter from './routers/settings'; -import batchesRouter from './routers/batches'; -import { errorHandler, requestLogger, responseLogger } from './lib/request-handlers'; -import * as database from './clients/database'; -import * as settings from './lib/settings'; -import * as utils from './lib/utils'; -import * as ipfs from './clients/ipfs'; -import * as app2app from './clients/app2app'; -import * as docExchange from './clients/doc-exchange'; -import * as eventStreams from './clients/event-streams'; -import { ensureEventStreamAndSubscriptions } from './lib/event-stream'; -import { assetTradeHandler } from './handlers/asset-trade'; -import { clientEventHandler } from './handlers/client-events'; -import { assetInstancesPinning } from './handlers/asset-instances-pinning'; - -const log = utils.getLogger('index.ts'); - -export const start = () => { - return initConfig(() => { app2app.reset(); docExchange.reset() }) - .then(() => settings.init()) - .then(() => database.init()) - .then(() => ipfs.init()) - .then(() => app2app.init()) - .then(() => docExchange.init()) - .then(() => ensureEventStreamAndSubscriptions()) - .then(() => assetInstancesPinning.init()) - .then(() => { - eventStreams.init(); - const app = express(); - - app.use(bodyParser.urlencoded({ extended: true })); - app.use(bodyParser.json()); - app.use(requestLogger); - - app.use('/api/v1/members', membersRouter); - app.use('/api/v1/assets/definitions', assetDefinitionsRouter); - app.use('/api/v1/assets', assetInstancesRouter); - app.use('/api/v1/payments/definitions', paymentDefinitionsRouter); - app.use('/api/v1/payments/instances', paymentInstancesRouter); - app.use('/api/v1/settings', settingsRouter); - app.use('/api/v1/batches', batchesRouter); - - app.use(responseLogger); - app.use(errorHandler); - - app2app.addListener(assetTradeHandler); - database.addListener(clientEventHandler); - - const server = app.listen(config.port, () => { - log.info(`Asset trail listening on port ${config.port} - log level "${utils.constants.LOG_LEVEL}"`); - }).on('error', (err) => { - log.error(err); - }); - - const shutDown = () => { - server.close(err => { - if (err) { - log.error(`Error closing server. ${err}`); - } else { - log.info(`Stopped server.`) - } - }); - eventStreams.shutDown(); - database.shutDown(); - shutDownConfig(); - }; - - return { app, shutDown }; - - }); -} diff --git a/kat/src/lib/batch-manager.ts b/kat/src/lib/batch-manager.ts deleted file mode 100644 index 3de8975e5c..0000000000 --- a/kat/src/lib/batch-manager.ts +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import * as database from '../clients/database'; -import { BatchProcessor } from './batch-processor'; -import { IDBBatch } from './interfaces'; -import * as utils from './utils'; - -const log = utils.getLogger('lib/batch-manager.ts'); - -/** - * Lifecycle manager for BatchProcessor instances, within a single type, across multiple authors - */ -export class BatchManager { - - processors: {[author: string]: BatchProcessor} = {}; - - constructor( - private type: string, - private processBatchCallback: (batch: IDBBatch) => Promise, - ) { } - - public async init() { - // Query all incomplete batches for our type, in creation order - const inflightBatches = await database.retrieveBatches({ - type: this.type, - completed: null, - }, 0, 0, { created: 1 }); - const byAuthor: {[author: string]: IDBBatch[]} = {}; - for (const inflight of inflightBatches) { - const forAuthor = byAuthor[inflight.author] = byAuthor[inflight.author] || []; - forAuthor.push(inflight); - } - // Init a set of processors for each distinct authors. - // Note these will be reaped if no work comes in while we're processing the backlog - for (const [author, forAuthor] of Object.entries(byAuthor)) { - await this.getProcessor(author).init(forAuthor); - } - } - - protected processorCompleteCallback(author: string) { - log.trace(`${this.type} batch manager: Reaping processor for ${author}`); - delete this.processors[author]; - } - - public getProcessor(author: string) { - if (!this.processors[author]) { - log.trace(`${this.type} batch manager: Creating processor for ${author}`); - this.processors[author] = new BatchProcessor( - author, - this.type, - this.processBatchCallback, - this.processorCompleteCallback.bind(this), - ); - } - return this.processors[author]; - } - -} \ No newline at end of file diff --git a/kat/src/lib/batch-processor.ts b/kat/src/lib/batch-processor.ts deleted file mode 100644 index 912db91db8..0000000000 --- a/kat/src/lib/batch-processor.ts +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { clearTimeout, setTimeout } from 'timers'; -import { promisify } from 'util'; -import { v4 as uuidV4 } from 'uuid'; -import * as database from '../clients/database'; -import { IBatchRecord, IDBBatch } from './interfaces'; -import * as utils from './utils'; - -const delay = promisify(setTimeout); - -const log = utils.getLogger('lib/batch-processor.ts'); - -export interface IBatchProcessorConfig { - addTimeoutMS: number; - batchTimeoutArrivallMS: number; - batchTimeoutOverallMS: number; - batchMaxRecords: number; - retryInitialDelayMS: number; - retryMaxDelayMS: number; - retryMultiplier: number; -} - -interface BatchAssemblyTask { - timestamp: number; - record: IBatchRecord; - resolve: (batchID: string) => void; - reject: (err: Error) => void; -} - -/** - * A singleton of these should be created for each batch type + author combination. - * - * A persistent batch implementation, which: - * - Is safe for calling concurrently on many async contexts - * - Guarantees to persists batch updates to the database before returning from add - * - Blocks the caller from getting more than one batch ahead - * - Protects against the caller of add (such as a REST API) giving up on a timeout before their record is accepted - * - Recovers in-flight batches on initialization - * - Pipelines the processing of one batch, with the building of the next - * - Retries accepted batches indefinitely - */ -export class BatchProcessor { - - private assemblyList: BatchAssemblyTask[]; - private assembling: boolean; - private assemblyBatch?: IDBBatch; - private dispatchTimeout?: NodeJS.Timeout; - private batchInFlight?: Promise; - public config: IBatchProcessorConfig; - - constructor( - private author: string, - private type: string, - private processBatchCallback: (batch: IDBBatch) => Promise, - private processorCompleteCallback: (author: string, type: string) => void, - config?: Partial, - ) { - this.assemblyList = []; - this.assembling = false; - this.config = { - addTimeoutMS: utils.constants.BATCH_ADD_TIMEOUT_MILLIS, - batchTimeoutArrivallMS: utils.constants.BATCH_TIMEOUT_ARRIVAL_MILLIS, - batchTimeoutOverallMS: utils.constants.BATCH_TIMEOUT_OVERALL_MILLIS, - batchMaxRecords: utils.constants.BATCH_MAX_RECORDS, - retryInitialDelayMS: utils.constants.BATCH_RETRY_INITIAL_DELAY_MILLIS, - retryMaxDelayMS: utils.constants.BATCH_RETRY_MAX_DELAY_MILLIS, - retryMultiplier: utils.constants.BATCH_RETRY_MULTIPLIER, - ...config, - } - } - - public async init(incompleteBatches: IDBBatch[]) { - // Treat the stored batches just as we would do filled batches. - // This logic blocks startup until we queued dispatch of all persisted batches - // (there should be a maximum of two, for the author+type combination) - while (incompleteBatches.length) { - this.assemblyBatch = incompleteBatches.shift(); - await this.dispatchBatch(); - } - } - - /** - * Blocks until the requested record has been assigned to a batch, and its inclusion - * in that batch has been persisted to our local database. - * @param record the record to add to a batch - * @returns {string} the batchID the add was persisted into - */ - public async add(record: IBatchRecord): Promise { - return new Promise((resolve, reject) => { - // Add our record to the assember queue, to resove the parent promise - this.assemblyList.push({ timestamp: Date.now(), record, resolve, reject }); - // Give the assembler a kick, as it might not be already running - this.assembler(); - }); - } - - protected newBatch(): IDBBatch { - const timestamp = Date.now(); - return { - type: this.type, - author: this.author, - batchID: uuidV4(), - created: timestamp, - completed: null, - records: [], - }; - } - - // Safety check to make sure we haven't got work queued into the system - // from a long time ago, that potentially a REST client has forgotten about. - // These are rejected at the point they are detected, before we do any active - // processing on them. - private rejectAnyStale() { - const now = Date.now(); - const newAssemblyList = []; - for (const a of this.assemblyList) { - const inFlightTime = now - a.timestamp; - if (inFlightTime > this.config.addTimeoutMS) { - a.reject(new Error(`Timed out add of record after ${inFlightTime}ms`)) - } else { - newAssemblyList.push(a); - } - } - this.assemblyList = newAssemblyList; - return this.assemblyList; - } - - private async assembler() { - - // Use each add as an opportunity to check for stales - this.rejectAnyStale(); - - // If we've already got an assembler running, nothing more to do - if (this.assembling) return; - - // We are the assembler - stop an duplicate one running (cleared before return) - this.assembling = true; - let chosen: BatchAssemblyTask[] = []; - while (this.rejectAnyStale().length) { - try { - - // Create a new assembly batch if we don't currently have one - if (!this.assemblyBatch) this.assemblyBatch = this.newBatch(); - const batch = this.assemblyBatch; - - // Grab as much capacity as we can out of the assemblyList - let capacity = this.config.batchMaxRecords - batch.records.length; - chosen = this.assemblyList.slice(0, capacity); - this.assemblyList = this.assemblyList.slice(capacity); - - // Add these entries to the in-memory batch object - for (let a of chosen) { - batch.records.push(a.record); - } - - // Persist the batch object to our local database - log.trace(`${this.type}/${this.author}: added ${chosen.length} records to batch ${batch.batchID}`); - await database.upsertBatch(batch); - - // Check if the batch is full - if (batch.records.length >= this.config.batchMaxRecords) { - // Only one batch can be dispatched, so this is a blocking call if we manage - // to run more than one batch ahead of the assembler. - await this.dispatchBatch(); - } else { - // Set/reset the timer to dispatch this batch - const now = Date.now(); - if (this.dispatchTimeout) clearTimeout(this.dispatchTimeout); - this.dispatchTimeout = setTimeout(() => this.dispatchBatch(), - Math.min( - // The next record must arrive within the batchTimeoutArrivallMS - this.config.batchTimeoutArrivallMS, - // The first record in the batch cannot be delayed by more than the batchTimeoutOverallMS - (batch.created + this.config.batchTimeoutOverallMS) - now, - ) - ); - } - - // **** - // Note that this point this.assemblyBatch might be undefined, if we just dispatched it. - // It is also NOT SAFE to do do any async processing here, because the processBatch - // logic relies us to exit if this.assemblyBatch to be undefined when the batch completes. - // So we need to go round to `newBatch` again without any async logic. - // *** - - // We have accepted all the chosen records into a persisted batch, ready for dispatch. - // This unblocks any callers waiting to know what batch they are in. - for (let a of chosen) a.resolve(batch.batchID); - } - catch(err) { - log.error(`${this.type}/${this.author}: Batch assembler failed`, err); - for (let a of chosen) a.reject(err); - } - } - this.assembling = false; - } - - protected async dispatchBatch() { - if (this.batchInFlight) await this.batchInFlight; - if (this.dispatchTimeout) clearTimeout(this.dispatchTimeout); - const batch = this.assemblyBatch; - delete this.assemblyBatch; - delete this.dispatchTimeout; - if (!batch) return; // Covers the posibility of a timer and the assember loop both firing - const batchTime = Date.now() - batch.created; - log.info(`${this.type}/${this.author}: closed batch ${batch.batchID} after ${batchTime}ms with ${batch.records.length} records`); - // Capture the promise for competion of this batch, to block any further dispatchBatch calls - this.batchInFlight = this.processBatch(batch); - } - - protected async processBatch(batch: IDBBatch) { - // We have accepted the batch at this point, and the REST calls to submit it to us have all completed. - // So we cannot fail to process it, and we must retry the processing indefinitely - let attempt = 0; - let complete = false; - while (!complete) { - try { - attempt++; - - // Set the completed time in memory - forms part of uniqueness in the pinning process. - batch.completed = Date.now(); - await this.processBatchCallback(batch); - - // Update the batch as complete - writes the now final completed timestamp, along with any updates made in processBatchCallback - await database.upsertBatch(batch); - - // Ok, we're done here. - complete = true; - } - catch(err) { - let retryDelay = this.config.retryInitialDelayMS; - for (let i = 1; i < attempt; i++) retryDelay *= this.config.retryMultiplier; - retryDelay = Math.min(retryDelay, this.config.retryMaxDelayMS); - log.error(`${this.type}/${this.author}: batch ${batch.batchID} attempt ${attempt} failed (next-retry: ${retryDelay}ms): ${err.stack}`); - await delay(retryDelay); - } - } - - // If there's nothing queued up, we call the completion handler that was passed in, - // to let them unregister this batch processor. - // This is because there are potentially infinite 'author' addresses that could be used, - // so leaving ourselves around indefinitely just because someone submitted on transaction - // would be a memory leak. - if (!this.assemblyBatch) { - this.processorCompleteCallback(this.author, this.type); - } - - } - -} \ No newline at end of file diff --git a/kat/src/lib/config.ts b/kat/src/lib/config.ts deleted file mode 100644 index cce6dafd28..0000000000 --- a/kat/src/lib/config.ts +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { promisify } from 'util'; -import { readFile } from 'fs'; -import Ajv from 'ajv'; -import configSchema from '../schemas/config.json'; -import * as utils from './utils'; -import { IConfig } from './interfaces'; -import path from 'path'; -import chokidar, { FSWatcher } from 'chokidar'; - -const log = utils.getLogger('lib/config.ts'); - -const asyncReadFile = promisify(readFile); -const ajv = new Ajv(); -const validateConfig = ajv.compile(configSchema); -const configFilePath = path.join(utils.constants.DATA_DIRECTORY, utils.constants.CONFIG_FILE_NAME); - -export let config: IConfig; -let fsWatcher: FSWatcher; -let configChangeListener: () => void; - -export const init = async (listener: () => void) => { - await loadConfigFile(); - watchConfigFile(); - configChangeListener = listener; -}; - -const loadConfigFile = async () => { - try { - const data = JSON.parse(await asyncReadFile(configFilePath, 'utf8')); - if(validateConfig(data)) { - config = data; - } else { - throw new Error('Invalid configuration file'); - } - } catch(err) { - throw new Error(`Failed to read configuration file. ${err}`); - } -}; - -const watchConfigFile = () => { - fsWatcher = chokidar.watch(configFilePath, { ignoreInitial: true }).on('change', async () => { - try { - await loadConfigFile(); - log.info('Loaded configuration file changes'); - configChangeListener(); - } catch(err) { - log.error(`Failed to load configuration file. ${err}`); - } - }); -}; - -export const shutDown = () => { - fsWatcher.close(); -}; \ No newline at end of file diff --git a/kat/src/lib/event-stream.ts b/kat/src/lib/event-stream.ts deleted file mode 100644 index 3328de1e05..0000000000 --- a/kat/src/lib/event-stream.ts +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import * as QueryString from 'querystring'; -import { URL } from 'url'; -import axios, { AxiosInstance } from 'axios'; -import { promisify } from 'util'; -import * as timers from 'timers'; -import * as database from '../clients/database'; -const sleep = promisify(timers.setTimeout); - -import * as utils from './utils'; -import { config } from './config' -import { IConfig, IEventStream, IEventStreamSubscription } from './interfaces'; -const logger = utils.getLogger('lib/event-stream.ts'); - -/* istanbul ignore next */ -const requestLogger = (config: any) => { - const qs = config.params ? `?${QueryString.stringify(config.params)}` : ''; - logger.info(`--> ${config.method} ${config.baseURL}${config.url}${qs}`); - logger.debug(config.data); - return config; -}; - -/* istanbul ignore next */ -const responseLogger = (response: any) => { - const { config, status, data } = response; - logger.info(`<-- ${config.method} ${config.url} [${status}]`); - logger.debug(data); - return response; -}; - -/* istanbul ignore next */ -const errorLogger = (err: any) => { - const { config = {}, response = {} } = err; - const { status, data } = response; - logger.info(`<-- ${config.method} ${config.url} [${status || err}]: ${JSON.stringify(data)}`); - throw err; -}; - -const subscriptionsInfoEthereum = [ - ['Asset instance created', 'AssetInstanceCreated'], - ['Asset instance batch created', 'AssetInstanceBatchCreated'], - ['Payment instance created', 'PaymentInstanceCreated'], - ['Payment definition created', 'PaymentDefinitionCreated'], - ['Asset definition created', 'AssetDefinitionCreated'], - ['Asset instance property set', 'AssetInstancePropertySet'], - ['Described payment instance created', 'DescribedPaymentInstanceCreated'], - ['Described asset instance created', 'DescribedAssetInstanceCreated'], - ['Described payment definition created', 'DescribedPaymentDefinitionCreated'], - ['Member registered', 'MemberRegistered'] -]; - -const subscriptionInfoCorda = [ - ['Asset instance created', 'io.kaleido.kat.states.AssetInstanceCreated'], - ['Described asset instance created', 'io.kaleido.kat.states.DescribedAssetInstanceCreated'], - ['Asset instance batch created', 'io.kaleido.kat.states.AssetInstanceBatchCreated'], - ['Asset instance property set', 'io.kaleido.kat.states.AssetInstancePropertySet'] -] - -export const ensureEventStreamAndSubscriptions = async () => { - if(!config.eventStreams.skipSetup) { - const esMgr = new EventStreamManager(config); - await esMgr.ensureEventStreamsWithRetry(); - } -}; - -class EventStreamManager { - private gatewayPath: string; - private api: AxiosInstance; - private streamDetails: any; - private retryCount: number; - private retryDelay: number; - private protocol: string; - - constructor(config: IConfig) { - const apiURL = new URL(config.apiGateway.apiEndpoint); - this.gatewayPath = apiURL.pathname.replace(/^\//, ''); - apiURL.pathname = ''; - const creds = `${config.apiGateway.auth?.user??config.appCredentials.user}:${config.apiGateway.auth?.password??config.appCredentials.password}`; - this.api = axios.create({ - baseURL: apiURL.href, - headers: { - Authorization: `Basic ${Buffer.from(creds).toString('base64')}` - } - }); - this.api.interceptors.request.use(requestLogger); - this.api.interceptors.response.use(responseLogger, errorLogger); - this.retryCount = 20; - this.retryDelay = 5000; - this.protocol = config.protocol; - this.streamDetails = { - name: config.eventStreams.topic, - errorHandling: config.eventStreams.config?.errorHandling??'block', - batchSize: config.eventStreams.config?.batchSize??50, - batchTimeoutMS: config.eventStreams.config?.batchTimeoutMS??500, - type: "websocket", - websocket: { - topic: config.eventStreams.topic - } - } - if(this.protocol === 'ethereum') { - // Due to spell error in ethconnect, we do this for now until ethconnect is updated - this.streamDetails.blockedReryDelaySec = config.eventStreams.config?.blockedRetryDelaySec??30; - } else { - this.streamDetails.blockedRetryDelaySec = config.eventStreams.config?.blockedRetryDelaySec??30; - } - } - - async ensureEventStreamsWithRetry() { - for (let i = 1; i <= this.retryCount; i++) { - try { - if (i > 1) await sleep(this.retryDelay); - const stream: IEventStream = await this.ensureEventStream(); - await this.ensureSubscriptions(stream); - return; - } catch (err) { - logger.error(`Attempt ${i} to initialize event streams failed`, err); - } - } - throw new Error("Failed to initialize event streams after retries"); - } - - async ensureEventStream(): Promise { - const { data: existingStreams } = await this.api.get('eventstreams'); - let stream = existingStreams.find((s: any) => s.name === this.streamDetails.name); - if (stream) { - const { data: patchedStream } = await this.api.patch(`eventstreams/${stream.id}`, this.streamDetails); - return patchedStream; - } - const { data: newStream } = await this.api.post('eventstreams', this.streamDetails); - return newStream; - } - - subscriptionInfo() { - switch(this.protocol) { - case 'ethereum': - return subscriptionsInfoEthereum; - case 'corda': - return subscriptionInfoCorda; - default: - throw new Error("Unsupported protocol."); - } - } - - async createSubscription(eventType: string, streamId: string, description: string): Promise<{id: string, name: string}> { - switch(this.protocol) { - case 'ethereum': - return this.api.post(`${this.gatewayPath}/${eventType}/Subscribe`, { - description, - name: eventType, - stream: streamId, - fromBlock: "0", // Subscribe from the start of the chain - }).then(r => { logger.info(`Created subscription ${eventType}: ${r.data.id}`); return r.data }); - case 'corda': - return this.api.post('subscriptions', { - name: eventType, - stream: streamId, - fromTime: null, // BEGINNING is specified as `null` in Corda event streams - filter: { - stateType: eventType, - stateStatus: "unconsumed", - relevancyStatus: "all" - } - }).then(r => { logger.info(`Created subscription ${eventType}: ${r.data.id}`); return r.data }); - default: - throw new Error("Unsupported protocol."); - } - } - - - - async ensureSubscriptions(stream: IEventStream) { - const dbSubscriptions = (await database.retrieveSubscriptions()) || {}; - const { data: existing } = await this.api.get('subscriptions'); - for (const [description, eventName] of this.subscriptionInfo()) { - const dbEventName = eventName.replace(/\./g, '_'); - let sub = existing.find((s: IEventStreamSubscription) => s.name === eventName && s.stream === stream.id); - let storedSubId = dbSubscriptions[dbEventName]; - if (!sub || sub.id !== storedSubId) { - if (sub) { - logger.info(`Deleting stale subscription that does not match persisted id ${storedSubId}`, sub); - await this.api.delete(`subscriptions/${sub.id}`); - } - const newSub = await this.createSubscription(eventName, stream.id, description); - dbSubscriptions[dbEventName] = newSub.id; - } else { - logger.info(`Subscription ${eventName}: ${sub.id}`); - } - } - await database.upsertSubscriptions(dbSubscriptions); - } - -} diff --git a/kat/src/lib/interfaces.ts b/kat/src/lib/interfaces.ts deleted file mode 100644 index 552074a0d2..0000000000 --- a/kat/src/lib/interfaces.ts +++ /dev/null @@ -1,513 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -// CONFIG INTERFACE - -export interface IConfig { - port: number - assetTrailInstanceID: string - protocol: 'ethereum' | 'corda' - apiGateway: { - apiEndpoint: string - auth?: { - user: string - password: string - } - } - eventStreams: { - wsEndpoint: string - topic: string - auth?: { - user: string - password: string - } - skipSetup?: boolean - config?: { - batchSize: number - batchTimeoutMS: number - blockedRetryDelaySec: number, - errorHandling: 'skip' | 'block' - } - } - ipfs: { - apiEndpoint: string - gatewayEndpoint: string - } - app2app: { - socketIOEndpoint: string - destinations: { - kat: string - client: string - } - } - docExchange: { - apiEndpoint: string - socketIOEndpoint: string - destination: string - } - appCredentials: { - user: string - password: string - } - mongodb: { - connectionUrl: string - databaseName: string - } -} - -// SETTINGS - -export interface ISettings { - clientEvents: string[] -} - -// STORED SUBSCRIPTION CONFIG - -export interface IStoredSubscriptions { - [sub: string]: string; -} - -// API GATEWAY INTERFACES - -export interface IAPIGatewayAsyncResponse { - type: 'async' - id: string - msg: string - sent: boolean -} - -export interface IAPIGatewaySyncResponse { - type: 'sync' - transactionHash: string -} - -export interface IAPIGatewaySyncResponseEthereum extends IAPIGatewaySyncResponse { - protocol: 'ethereum' - blockHash: string - blockNumber: string - cumulativeGasUsed: string - from: string - gasUsed: string - headers: { - id: string - type: 'string', - timeReceived: 'string', - timeElapsed: number - requestOffset: string - } - nonce: string - status: string - to: string - transactionIndex: string -} - -export interface IEventStream { - id: string -} - -export interface IEventStreamSubscription { - name: string - stream: string -} - -// IPFS INTERFACES - -export interface IIPFSAssetDefinition { - assetDefinitionID: string - name: string - isContentPrivate: boolean - isContentUnique: boolean - descriptionSchema?: object - contentSchema?: object - indexes?: indexes -} - -// IPFS INTERFACES - -export interface IIPFSAssetDefinition { - assetDefinitionID: string - name: string - isContentPrivate: boolean - isContentUnique: boolean - descriptionSchema?: object - contentSchema?: object - indexes?: indexes -} - -// REQUEST INTERFACES - -export interface IRequestMultiPartContent { - author?: string - assetDefinitionID?: string - description?: Promise - contentStream: NodeJS.ReadableStream - contentFileName: string - isContentPrivate?: boolean -} - -export interface IAssetDefinitionRequest { - assetDefinitionID: string - name: string - author?: string - isContentPrivate: boolean - isContentUnique: boolean - indexes?: indexes - descriptionSchema?: object - contentSchema?: object -} - -// EVENT STREAM INTERFACES - - -interface IStateRefCorda { - txhash: string, - index: number -} - -interface IStateCorda { - data: object -} - -export interface IEventStreamRawMessageCorda { - data: IStateCorda, - subId: string, - signature: string, - stateRef: IStateRefCorda, - recordedTime: string, - consumedTime: string -} - -export interface IEventStreamMessage { - address?: string - blockNumber?: string - transactionIndex?: string - transactionHash: string - data: object - subId: string - signature: string - logIndex?: string -} - -export interface IEventMemberRegistered { - member: string - name: string - assetTrailInstanceID: string - app2appDestination: string - docExchangeDestination: string - timestamp: number -} - -export interface IEventAssetDefinitionCreated { - author: string - assetDefinitionHash: string - timestamp: string -} - -export interface IEventPaymentDefinitionCreated { - paymentDefinitionID: string - author: string - name: string - descriptionSchemaHash?: string - timestamp: string -} - -export interface IEventAssetInstanceCreated { - assetInstanceID: string - assetDefinitionID: string - author: string - descriptionHash?: string - contentHash: string - timestamp: string - isContentPrivate: boolean - participants?: string[] -} -export interface IEventAssetInstanceBatchCreated { - batchHash: string; - author: string - timestamp: string - participants?: string[] -} - -export interface IEventPaymentInstanceCreated { - paymentInstanceID: string - paymentDefinitionID: string - author: string - member: string - descriptionHash?: string - amount: string - timestamp: string - participants?: string[] -} - -export interface IEventAssetInstancePropertySet extends IAssetInstancePropertySet { - timestamp: string - participants?: string[] -} - -// DATABASE INTERFACES - -//TODO: figure out how to handle variable asset-instance collection names -export type databaseCollectionName = 'members' | 'asset-definitions' | 'payment-definitions' | 'payment-instances' | 'batches' | customCollectionName -export type customCollectionName = string - -export type indexes = {fields: string[], unique?: boolean}[]; - -export interface IDatabaseProvider { - init: () => Promise - createCollection: (collectionName: string, indexes: indexes) => Promise - count: (collectionName: databaseCollectionName, query: object) => Promise - find: (collectionName: databaseCollectionName, query: object, sort: object, skip: number, limit: number) => Promise - findOne: (collectionName: databaseCollectionName, query: object) => Promise - updateOne: (collectionName: databaseCollectionName, query: object, value: object, upsert: boolean) => Promise - shutDown: () => void -} - -export interface IDBBlockchainData { - blockNumber?: number - transactionHash: string - participants?: string[] -} - -export interface IDBBlockchainPinned extends Partial { - submitted?: number - timestamp?: number - receipt?: string -} - -export interface IDBMember extends IDBBlockchainPinned { - _id?: string - address: string - name: string - assetTrailInstanceID: string - app2appDestination: string - docExchangeDestination: string -} - -export interface IDBAssetDefinition extends IIPFSAssetDefinition, IDBBlockchainPinned { - _id?: string - author: string - assetDefinitionHash: string - conflict?: boolean -} - -export interface IDBPaymentDefinition extends IDBBlockchainPinned { - _id?: string - paymentDefinitionID: string - author: string - name: string - descriptionSchema?: object - descriptionSchemaHash?: string - conflict?: boolean -} - -export interface IAssetInstance { - assetInstanceID: string - assetDefinitionID: string - author: string - descriptionHash?: string - description?: object - content?: object - contentHash?: string - isContentPrivate: boolean - conflict?: boolean - filename?: string - properties?: { - [author: string]: { - [key: string]: { - value: string - submitted?: number - receipt?: string - history?: { - [timestamp: string]: { - value: string - timestamp: number - blockNumber: number - transactionHash: string - } - } - } | undefined - } | undefined - } -} - -export interface IDBAssetInstance extends IAssetInstance, IDBBlockchainPinned { - _id?: string - batchID?: string; -} - -export interface IAssetInstancePropertySet { - assetInstanceID: string - assetDefinitionID: string - author: string - key: string - value: string -} - -export interface IDBPaymentInstance extends IDBBlockchainPinned { - _id?: string - paymentInstanceID: string - paymentDefinitionID: string - author: string - member: string - amount: number - descriptionHash?: string - description?: object -} - -export enum BatchRecordType { - assetInstance = 'instance', - assetProperty = 'property', -} - -export interface IBatchRecord { - recordType: BatchRecordType, - [x: string]: any, -} - -export interface IPinnedBatch { - type: string; - author: string; - created: number; - completed: number | null; - batchID: string, - records: IBatchRecord[]; -} - -export interface IDBBatch extends IPinnedBatch, IDBBlockchainPinned { - _id?: string; - batchHash?: string, -} - -// APP2APP INTERFACES - -export interface IApp2AppMessageHeader { - from: string - to: string -} - -export interface IApp2AppMessage { - headers: IApp2AppMessageHeader - content: string -} - -export interface IApp2AppMessageListener { - (header: IApp2AppMessageHeader, content: AssetTradeMessage): void -} - -// DOCUMENT EXCHANGE INTERFACES - -export interface IDocExchangeDocumentDetails { - name: string - is_directory: boolean - size: number - hash: string -} - -export interface IDocExchangeTransferData { - transferId: string - transferHash: string - hash: string - from: string - to: string - senderSignature: string - memberSignature: string - document: string - timestamp: string - status: 'sent' | 'received' | 'failed' -} - -export interface IDocExchangeListener { - (transferData: IDocExchangeTransferData): void -} - -// ASSET TRADE INTERFACES - -export type AssetTradeMessage = - IAssetTradePrivateAssetInstanceRequest - | IAssetTradePrivateAssetInstanceResponse - | IAssetTradePrivateAssetInstancePush - | IAssetTradePrivateAssetInstanceAuthorizationResponse - -export interface IAssetTradePrivateAssetInstanceRequest { - type: 'private-asset-instance-request' - tradeID: string - assetInstanceID: string - assetDefinitionID: string - requester: { - assetTrailInstanceID: string - address: string - } - metadata?: object -} - -export interface IAssetTradePrivateAssetInstanceResponse { - type: 'private-asset-instance-response' - tradeID: string - assetInstanceID: string - rejection?: string - content?: object - filename?: string -} - -export interface IAssetTradePrivateAssetInstancePush { - type: 'private-asset-instance-push' - assetInstanceID: string - assetDefinitionID: string - content?: object - filename?: string -} - -export interface IAssetTradePrivateAssetInstanceAuthorizationRequest { - type: 'private-asset-instance-authorization-request' - authorizationID: string - assetInstance: IDBAssetInstance - requester: IDBMember - metadata?: object -} - -export interface IAssetTradePrivateAssetInstanceAuthorizationResponse { - type: 'private-asset-instance-authorization-response' - authorizationID: string - authorized: boolean -} - -// CLIENT EVENT INTERFACES - -export type ClientEventType = - 'member-registered' - | 'asset-definition-submitted' - | 'asset-definition-created' - | 'asset-definition-name-conflict' - | 'payment-definition-submitted' - | 'payment-definition-created' - | 'payment-definition-name-conflict' - | 'asset-instance-submitted' - | 'asset-instance-created' - | 'asset-instance-content-conflict' - | 'payment-instance-submitted' - | 'payment-instance-created' - | 'private-asset-instance-content-stored' - | 'asset-instance-property-submitted' - | 'asset-instance-property-set' - -export interface IClientEventListener { - (eventType: ClientEventType, content: object): void -} - -export interface IPendingAssetInstancePrivateContentDelivery { - assetInstanceID: string - fromDestination: string - content?: object - filename?: string -} \ No newline at end of file diff --git a/kat/src/lib/logging.ts b/kat/src/lib/logging.ts deleted file mode 100644 index 447ffe6ecf..0000000000 --- a/kat/src/lib/logging.ts +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -"use strict"; - -const LEVEL_NONE = 0; -const LEVEL_ERROR = 1; -const LEVEL_WARN = 2; -const LEVEL_INFO = 3; -const LEVEL_DEBUG = 4; -const LEVEL_TRACE = 5; - -const LEVEL_TAGS = { - [LEVEL_NONE]: 'NONE', - [LEVEL_ERROR]: 'ERROR', - [LEVEL_WARN]: 'WARN ', - [LEVEL_INFO]: 'INFO ', - [LEVEL_DEBUG]: 'DEBUG', - [LEVEL_TRACE]: 'TRACE', -}; - -let logLevel = LEVEL_ERROR; - -export function setLogLevel(level?: string) { - if (!level) level = process.env.LOG_LEVEL || 'info'; - for (let [l,t] of Object.entries(LEVEL_TAGS)) { - if (t.trim().toLowerCase() === level.trim().toLowerCase()) { - logLevel = Number(l); - } - } -} - -export class Logger { - - constructor(private loggerName?: string) {} - - error(...args: any[]) { logLevel >= LEVEL_ERROR && this.log('ERROR', ...args); } - warn(...args: any[]) { logLevel >= LEVEL_WARN && this.log('WARN ', ...args); } - info(...args: any[]) { logLevel >= LEVEL_INFO && this.log('INFO ', ...args); } - debug(...args: any[]) { logLevel >= LEVEL_DEBUG && this.log('DEBUG', ...args); } - trace(...args: any[]) { logLevel >= LEVEL_TRACE && this.log('TRACE', ...args); } - - private log(level: string, ...args: any[]) { - const logArgs = []; - for (const arg of args) { - // Special handling of axios errors to avoid massive dumps in log - if (arg?.isAxiosError) { - let data = arg.response?.data; - data = data?.on ? '[stream]' : JSON.stringify(data); - logArgs.push(`HTTP [${arg.response?.status}] ${arg.message}: ${data}`) - } else { - logArgs.push(arg); - } - } - console.log(`${new Date().toISOString()} [${level}]:`, ...logArgs, this.loggerName); - } - -} - -setLogLevel(); diff --git a/kat/src/lib/request-handlers.ts b/kat/src/lib/request-handlers.ts deleted file mode 100644 index 28924612cd..0000000000 --- a/kat/src/lib/request-handlers.ts +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { NextFunction, Request, Response } from 'express'; -import { nanoid } from 'nanoid'; -import * as utils from './utils'; -const log = utils.getLogger('lib/request-handlers.ts'); - -export default class RequestError extends Error { - - responseCode: number; - - constructor(message: string, responseCode = 500) { - super(message); - this.responseCode = responseCode; - } - -} - -export const errorHandler = (err: Error, req: Request, res: Response, _next: NextFunction) => { - const statusCode = err instanceof RequestError?err.responseCode : 500; - log.error(`!<-- ${req.method} ${req.url} [${statusCode}]`, statusCode === 404 ? undefined : err.stack); - res.status(statusCode).send({ error: err.message }); -}; - -interface ATRequest extends Request { - entryTime: number - requestId: string -} - -export function requestLogger(req: Request, _: Response, next: NextFunction): void { - const r: ATRequest = req as ATRequest; - r.entryTime = Date.now(); - r.requestId = nanoid(10); - log.info(`[${r.requestId}] --> ${req.method} ${req.path}`); - next(); -} - -export function responseLogger(req: Request, res: Response, next: NextFunction): void { - const r: ATRequest = req as ATRequest; - const timing = (Date.now() - r.entryTime).toFixed(1); - log.info( - `[${r.requestId}] <-- ${req.method} ${req.path} [${res.statusCode}] (${timing}ms)` - ); - next(); -} \ No newline at end of file diff --git a/kat/src/lib/settings.ts b/kat/src/lib/settings.ts deleted file mode 100644 index 89408689eb..0000000000 --- a/kat/src/lib/settings.ts +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import Ajv from 'ajv'; -import { promisify } from 'util'; -import { readFile, writeFile } from 'fs'; -import path from 'path'; -import * as utils from './utils'; -import { ISettings } from './interfaces'; -import settingsSchema from '../schemas/settings.json'; -import RequestError from './request-handlers'; - -const log = utils.getLogger('lib/settings.ts'); - -const asyncReadFile = promisify(readFile); -const asyncWriteFile = promisify(writeFile); -const ajv = new Ajv(); -const validateSettings = ajv.compile(settingsSchema); -export let settings: ISettings; - -const settingsFilePath = path.join(utils.constants.DATA_DIRECTORY, utils.constants.SETTINGS_FILE_NAME); - -export const init = async () => { - await readSettingsFile() -}; - -const readSettingsFile = async () => { - try { - const values = JSON.parse(await asyncReadFile(settingsFilePath, 'utf8')); - if(!validateSettings(values)) { - throw new Error('Invalid content'); - } - settings = values; - } catch(err) { - if(err.errno === -2) { - settings = { - clientEvents: [] - }; - } else { - throw new Error(`Failed to read settings file. ${err}`); - } - } -}; - -export const updateSettings = async (key: string, value: any) => { - const updatedSettings = {...settings, [key]: value}; - if (!validateSettings(updatedSettings)) { - throw new RequestError('Invalid Settings', 400); - } - settings = updatedSettings; - await persistSettings(); -}; - -export const setClientEvents = (clientEvents: string[]) => { - settings.clientEvents = clientEvents; - persistSettings(); -}; - -const persistSettings = () => { - try { - asyncWriteFile(settingsFilePath, JSON.stringify(settings)); - } catch(err) { - log.error(`Failed to persist settings. ${err}`); - } -}; \ No newline at end of file diff --git a/kat/src/lib/utils.ts b/kat/src/lib/utils.ts deleted file mode 100644 index 64e833b694..0000000000 --- a/kat/src/lib/utils.ts +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { encode, decode } from 'bs58'; -import crypto from 'crypto'; -import axios, { AxiosRequestConfig } from 'axios'; -import { databaseCollectionName, indexes } from './interfaces'; -import { parseDN } from 'ldapjs'; -import { Logger } from './logging'; - -export const constants = { - DATA_DIRECTORY: process.env.DATA_DIRECTORY || '/data', - LOG_LEVEL: process.env.LOG_LEVEL || 'info', - CONFIG_FILE_NAME: 'config.json', - SETTINGS_FILE_NAME: 'settings.json', - IPFS_TIMEOUT_MS: 15000, - DEFAULT_PAGINATION_LIMIT: 100, - EVENT_STREAM_WEBSOCKET_RECONNECTION_DELAY_SECONDS: 5, - DOC_EXCHANGE_ASSET_FOLDER_NAME: 'assets', - EVENT_STREAM_PING_TIMEOUT_SECONDS: 60, - ASSET_INSTANCE_TRADE_TIMEOUT_SECONDS: 15, - TRADE_AUTHORIZATION_TIMEOUT_SECONDS: 10, - DOCUMENT_EXCHANGE_TRANSFER_TIMEOUT_SECONDS: 15, - SUBSCRIBE_RETRY_INTERVAL: 5 * 1000, - APP2APP_BATCH_SIZE: parseInt(process.env.APP2APP_BATCH_SIZE || "100"), - APP2APP_BATCH_TIMEOUT: parseInt(process.env.APP2APP_BATCH_TIMEOUT || "250"), - APP2APP_READ_AHEAD: parseInt(process.env.APP2APP_READ_AHEAD || "50"), - REST_API_CALL_MAX_ATTEMPTS: parseInt(process.env.REST_API_CALL_MAX_ATTEMPTS || "5"), - REST_API_CALL_RETRY_DELAY_MS: parseInt(process.env.REST_API_CALL_MAX_ATTEMPTS || "500"), - BATCH_ADD_TIMEOUT_MILLIS: parseInt(process.env.BATCH_ADD_TIMEOUT_MILLIS || '30000'), - BATCH_TIMEOUT_OVERALL_MILLIS: parseInt(process.env.BATCH_TIMEOUT_OVERALL_MILLIS || '2500'), - BATCH_TIMEOUT_ARRIVAL_MILLIS: parseInt(process.env.BATCH_TIMEOUT_ARRIVAL_MILLIS || '250'), - BATCH_MAX_RECORDS: parseInt(process.env.BATCH_MAX_RECORDS || '1000'), - BATCH_RETRY_INITIAL_DELAY_MILLIS: parseInt(process.env.BATCH_RETRY_INITIAL_DELAY_MILLIS || '100'), - BATCH_RETRY_MAX_DELAY_MILLIS: parseInt(process.env.BATCH_RETRY_MAX_DELAY_MILLIS || '10000'), - BATCH_RETRY_MULTIPLIER: parseFloat(process.env.BATCH_RETRY_MULTIPLIER || '2.0'), -}; - -const log = new Logger('utis.ts'); - -export const databaseCollectionIndexes: { [name in databaseCollectionName]: indexes } = { - members: [{ fields: ['address'], unique: true }], - 'asset-definitions': [{ fields: ['assetDefinitionID'], unique: true }], - 'payment-definitions': [{ fields: ['paymentDefinitionID'], unique: true }], - 'payment-instances': [{ fields: ['paymentInstanceID'], unique: true }], - 'batches': [ - { fields: ['batchID'], unique: true }, // Primary key - { fields: ['type', 'author', 'completed', 'created'] }, // Search index for startup processing, and other queries - { fields: ['batchHash'] } // To retrieve a batch by its hash, in response to a blockchain event - ], - 'state': [{ fields: ['key'], unique: true }], -}; - -const ETHEREUM_ACCOUNT_REGEXP = /^0x[a-fA-F0-9]{40}$/; - -const isValidX500Name = (name: string) => { - try { - parseDN(name); - } catch (e) { - return false; - } - return true; -}; - -export const isAuthorValid = (author: string, protocol: string) => { - switch (protocol) { - case 'corda': - return isValidX500Name(author); - case 'ethereum': - return ETHEREUM_ACCOUNT_REGEXP.test(author); - } -} - -export const requestKeys = { - ASSET_AUTHOR: 'author', - ASSET_DEFINITION_ID: 'assetDefinitionID', - ASSET_DESCRIPTION: 'description', - ASSET_CONTENT: 'content', - ASSET_IS_CONTENT_PRIVATE: 'isContentPrivate' -}; - -export const contractEventSignaturesCorda = { - ASSET_DEFINITION_CREATED: 'io.kaleido.kat.states.AssetDefinitionCreated', - MEMBER_REGISTERED: 'io.kaleido.kat.states.MemberRegistered', - DESCRIBED_PAYMENT_DEFINITION_CREATED: 'io.kaleido.kat.states.DescribedPaymentDefinitionCreated', - PAYMENT_DEFINITION_CREATED: 'io.kaleido.kat.states.PaymentDefinitionCreated', - DESCRIBED_ASSET_INSTANCE_CREATED: 'io.kaleido.kat.states.DescribedAssetInstanceCreated', - ASSET_INSTANCE_BATCH_CREATED: 'io.kaleido.kat.states.AssetInstanceBatchCreated', - ASSET_INSTANCE_CREATED: 'io.kaleido.kat.states.AssetInstanceCreated', - DESCRIBED_PAYMENT_INSTANCE_CREATED: 'io.kaleido.kat.states.DescribedPaymentInstanceCreated', - PAYMENT_INSTANCE_CREATED: 'io.kaleido.kat.states.PaymentInstanceCreated', - ASSET_PROPERTY_SET: 'io.kaleido.kat.states.AssetInstancePropertySet' -} - -export const contractEventSignatures = { - ASSET_DEFINITION_CREATED: 'AssetDefinitionCreated(bytes32,address,uint256)', - MEMBER_REGISTERED: 'MemberRegistered(address,string,string,string,string,uint256)', - DESCRIBED_PAYMENT_DEFINITION_CREATED: 'DescribedPaymentDefinitionCreated(bytes32,address,string,bytes32,uint256)', - PAYMENT_DEFINITION_CREATED: 'PaymentDefinitionCreated(bytes32,address,string,uint256)', - DESCRIBED_ASSET_INSTANCE_CREATED: 'DescribedAssetInstanceCreated(bytes32,bytes32,address,bytes32,bytes32,uint256)', - ASSET_INSTANCE_BATCH_CREATED: 'AssetInstanceBatchCreated(bytes32,address,uint256)', - ASSET_INSTANCE_CREATED: 'AssetInstanceCreated(bytes32,bytes32,address,bytes32,uint256)', - DESCRIBED_PAYMENT_INSTANCE_CREATED: 'DescribedPaymentInstanceCreated(bytes32,bytes32,address,address,uint256,bytes32,uint256)', - PAYMENT_INSTANCE_CREATED: 'PaymentInstanceCreated(bytes32,bytes32,address,address,uint256,uint256)', - ASSET_PROPERTY_SET: 'AssetInstancePropertySet(bytes32,bytes32,address,string,string,uint256)' -}; - -export const getSha256 = (value: string) => crypto.createHash('sha256').update(value).digest('hex'); - -export const ipfsHashToSha256 = (hash: string) => '0x' + decode(hash).slice(2).toString('hex'); - -export const sha256ToIPFSHash = (short: string) => encode(Buffer.from('1220' + short.slice(2), 'hex')); - -export const getTimestamp = () => { - return Math.round(new Date().getTime() / 1000); -}; - -export const streamToString = (stream: NodeJS.ReadableStream): Promise => { - const chunks: Buffer[] = []; - return new Promise((resolve, reject) => { - stream.on('data', chunk => chunks.push(chunk)); - stream.on('error', reject); - stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8'))); - }) -} - -export const getUnstructuredFilePathInDocExchange = (assetInstanceID: string) => { - return `${constants.DOC_EXCHANGE_ASSET_FOLDER_NAME}/${assetInstanceID}`; -}; - -export const uuidToHex = (uuid: string) => { - return '0x' + Buffer.from(uuid.replace(/-/g, '')).toString('hex'); -}; - -export const hexToUuid = (hex: string) => { - const decodedTransferID = Buffer.from(hex.substr(2), 'hex').toString('utf-8'); - return decodedTransferID.substr(0, 8) + '-' + decodedTransferID.substr(8, 4) + '-' + - decodedTransferID.substr(12, 4) + '-' + decodedTransferID.substr(16, 4) + '-' + - decodedTransferID.substr(20, 12); -}; - -export const axiosWithRetry = async (config: AxiosRequestConfig) => { - let attempts = 0; - let currentError; - while (attempts < constants.REST_API_CALL_MAX_ATTEMPTS) { - try { - return await axios(config); - } catch (err) { - const data = err.response?.data; - log.error(`${config.method} ${config.url} attempt ${attempts} [${err.response?.status}]`, (data && !data.on) ? data : err.stack) - if (err.response?.status === 404) { - throw err; - } else { - currentError = err; - attempts++; - await new Promise(resolve => setTimeout(resolve, constants.REST_API_CALL_RETRY_DELAY_MS)); - } - } - } - throw currentError; -}; - -export function getLogger(label: string) { - return new Logger(label); -} \ No newline at end of file diff --git a/kat/src/routers/asset-definitions.ts b/kat/src/routers/asset-definitions.ts deleted file mode 100644 index 8eb8b27675..0000000000 --- a/kat/src/routers/asset-definitions.ts +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { Router } from 'express'; -import { v4 as uuidV4 } from 'uuid'; -import RequestError from '../lib/request-handlers'; -import * as assetDefinitionsHandler from '../handlers/asset-definitions'; -import { constants } from '../lib/utils'; -import * as utils from '../lib/utils'; -import { config } from '../lib/config'; - -const router = Router(); - -router.get('/', async (req, res, next) => { - try { - const skip = Number(req.query.skip || 0); - const limit = Number(req.query.limit || constants.DEFAULT_PAGINATION_LIMIT); - if (isNaN(skip) || isNaN(limit)) { - throw new RequestError('Invalid skip / limit', 400); - } - res.send(await assetDefinitionsHandler.handleGetAssetDefinitionsRequest({}, skip, limit)); - } catch (err) { - next(err); - } -}); - -router.get('/:assetDefinitionID', async (req, res, next) => { - try { - res.send(await assetDefinitionsHandler.handleGetAssetDefinitionRequest(req.params.assetDefinitionID)); - } catch (err) { - next(err); - } -}); - -router.post('/search', async (req, res, next) => { - try { - const skip = Number(req.body.skip || 0); - const limit = Number(req.body.limit || constants.DEFAULT_PAGINATION_LIMIT); - if (req.body.count !== true && (isNaN(skip) || isNaN(limit))) { - throw new RequestError('Invalid skip / limit', 400); - } - if (!req.body.query) { - throw new RequestError('Missing search query', 400); - } - res.send(req.body.count === true ? - await assetDefinitionsHandler.handleCountAssetDefinitionsRequest(req.body.query) : - await assetDefinitionsHandler.handleGetAssetDefinitionsRequest(req.body.query, skip, limit) - ); - } catch (err) { - next(err); - } -}); - -router.post('/', async (req, res, next) => { - try { - if (!req.body.name || req.body.name === '') { - throw new RequestError('Missing or invalid asset definition name', 400); - } - if (!utils.isAuthorValid(req.body.author, config.protocol)) { - throw new RequestError('Missing or invalid asset definition author', 400); - } - if (typeof req.body.isContentPrivate !== 'boolean') { - throw new RequestError('Missing asset definition content privacy', 400); - } - if (typeof req.body.isContentUnique !== 'boolean') { - throw new RequestError('Missing asset definition content uniqueness', 400); - } - let assetDefinitionID; - switch (config.protocol) { - case 'corda': - if (!req.body.assetDefinitionID) { - throw new RequestError('Missing asset definition id', 400); - } - assetDefinitionID = req.body.assetDefinitionID; - break; - case 'ethereum': - assetDefinitionID = uuidV4(); - break; - } - const sync = req.query.sync === 'true'; - await assetDefinitionsHandler.handleCreateAssetDefinitionRequest(assetDefinitionID, req.body.name, req.body.isContentPrivate, - req.body.isContentUnique, req.body.author, req.body.descriptionSchema, req.body.contentSchema, req.body.indexes, sync); - res.send({ status: sync ? 'success' : 'submitted', assetDefinitionID }); - } catch (err) { - next(err); - } -}); - -export default router; diff --git a/kat/src/routers/asset-instances.ts b/kat/src/routers/asset-instances.ts deleted file mode 100644 index 180c080345..0000000000 --- a/kat/src/routers/asset-instances.ts +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { Router, Request } from 'express'; -import RequestError from '../lib/request-handlers'; -import * as assetInstancesHandler from '../handlers/asset-instances'; -import { constants, requestKeys, streamToString } from '../lib/utils'; -import Busboy from 'busboy'; -import * as utils from '../lib/utils'; -import { IRequestMultiPartContent } from '../lib/interfaces'; -import { config } from '../lib/config'; - -const router = Router(); - -router.get('/:assetDefinitionID', async (req, res, next) => { - try { - const skip = Number(req.query.skip || 0); - const limit = Number(req.query.limit || constants.DEFAULT_PAGINATION_LIMIT); - if (isNaN(skip) || isNaN(limit)) { - throw new RequestError('Invalid skip / limit', 400); - } - res.send(await assetInstancesHandler.handleGetAssetInstancesRequest(req.params.assetDefinitionID, {}, {}, skip, limit)); - } catch (err) { - next(err); - } -}); - -router.get('/:assetDefinitionID/:assetInstanceID', async (req, res, next) => { - try { - const content = req.query.content === 'true'; - res.send(await assetInstancesHandler.handleGetAssetInstanceRequest(req.params.assetDefinitionID, req.params.assetInstanceID, content)); - } catch (err) { - next(err); - } -}); - -router.post('/search/:assetDefinitionID', async (req, res, next) => { - try { - const skip = Number(req.body.skip || 0); - const limit = Number(req.body.limit || constants.DEFAULT_PAGINATION_LIMIT); - if (req.body.count !== true && (isNaN(skip) || isNaN(limit))) { - throw new RequestError('Invalid skip / limit', 400); - } - if (!req.body.query) { - throw new RequestError('Missing search query', 400); - } - res.send(req.body.count === true ? - await assetInstancesHandler.handleCountAssetInstancesRequest(req.params.assetDefinitionID, req.body.query) : - await assetInstancesHandler.handleGetAssetInstancesRequest(req.params.assetDefinitionID, req.body.query, req.body.sort || {}, skip, limit) - ); - } catch (err) { - next(err); - } -}); - -router.post('/:assetDefinitionID', async (req, res, next) => { - try { - let assetInstanceID: string; - const sync = req.query.sync === 'true'; - - if (req.headers["content-type"]?.startsWith('multipart/form-data')) { - let description: Object | undefined; - const formData = await extractDataFromMultipartForm(req); - if (formData.description !== undefined) { - try { - description = JSON.parse(await formData.description); - } catch (err) { - throw new RequestError(`Invalid description. ${err}`, 400); - } - } - if (!formData.author ||!utils.isAuthorValid(formData.author, config.protocol)) { - throw new RequestError('Missing or invalid asset instance author', 400); - } - assetInstanceID = await assetInstancesHandler.handleCreateUnstructuredAssetInstanceRequest(formData.author, req.params.assetDefinitionID, description, formData.contentStream, formData.contentFileName, formData.isContentPrivate, req.body.participants, sync); - } else { - if (!utils.isAuthorValid(req.body.author, config.protocol)) { - throw new RequestError('Missing or invalid asset instance author', 400); - } - if (!(typeof req.body.content === 'object' && req.body.content !== null)) { - throw new RequestError('Missing or invalid asset content', 400); - } - if(req.body.isContentPrivate !== undefined && typeof req.body.isContentPrivate !== 'boolean') { - throw new RequestError('Invalid isContentPrivate', 400); - } - assetInstanceID = await assetInstancesHandler.handleCreateStructuredAssetInstanceRequest(req.body.author, req.params.assetDefinitionID, req.body.description, req.body.content, req.body.isContentPrivate, req.body.participants, sync); - } - res.send({ status: sync ? 'success' : 'submitted', assetInstanceID }); - } catch (err) { - next(err); - } -}); - -router.put('/:assetDefinitionID/:assetInstanceID', async (req, res, next) => { - try { - switch (req.body.action) { - case 'set-property': - if (!req.body.key) { - throw new RequestError('Missing asset property key', 400); - } - if (!req.body.value) { - throw new RequestError('Missing asset property value', 400); - } - if (!utils.isAuthorValid(req.body.author, config.protocol)) { - throw new RequestError('Missing or invalid asset property author', 400); - } - const sync = req.query.sync === 'true'; - await assetInstancesHandler.handleSetAssetInstancePropertyRequest(req.params.assetDefinitionID, req.params.assetInstanceID, req.body.author, req.body.key, req.body.value, sync); - res.send({ status: sync ? 'success' : 'submitted' }); - break; - case 'push': - if (!req.body.memberAddress) { - throw new RequestError('Missing member address', 400); - } - await assetInstancesHandler.handlePushPrivateAssetInstanceRequest(req.params.assetDefinitionID, req.params.assetInstanceID, req.body.memberAddress); - res.send({ status: 'success' }); - break; - default: - throw new RequestError('Missing or invalid action'); - } - } catch (err) { - next(err); - } -}); - -router.patch('/:assetDefinitionID/:assetInstanceID', async (req, res, next) => { - try { - if (!utils.isAuthorValid(req.body.requester, config.protocol)) { - throw new RequestError(`Missing requester`); - } - await assetInstancesHandler.handleAssetInstanceTradeRequest(req.params.assetDefinitionID, req.body.requester, req.params.assetInstanceID, req.body.metadata); - res.send({ status: 'success' }); - } catch (err) { - next(err); - } -}); - -router.post('/:assetDefinitionID/:assetInstanceID/push', async (req, res, next) => { - try { - if (!req.body.memberAddress) { - throw new RequestError('Missing member address', 400); - } - await assetInstancesHandler.handlePushPrivateAssetInstanceRequest(req.params.assetDefinitionID, req.params.assetInstanceID, req.body.memberAddress); - res.send({ status: 'success' }); - } catch (err) { - next(err); - } -}); - -const extractDataFromMultipartForm = (req: Request): Promise => { - return new Promise(async (resolve, reject) => { - let author: string | undefined; - let assetDefinitionID: string | undefined; - let description: Promise | undefined; - let isContentPrivate: boolean | undefined = undefined; - req.pipe(new Busboy({ headers: req.headers }) - .on('field', (fieldname, value) => { - switch (fieldname) { - case requestKeys.ASSET_AUTHOR: author = value; break; - case requestKeys.ASSET_DEFINITION_ID: assetDefinitionID = value; break; - case requestKeys.ASSET_IS_CONTENT_PRIVATE: isContentPrivate = value === 'true'; break; - } - }).on('file', (fieldname, readableStream, fileName) => { - switch (fieldname) { - case requestKeys.ASSET_DESCRIPTION: description = streamToString(readableStream); break; - case requestKeys.ASSET_CONTENT: resolve({ author, assetDefinitionID, description, contentStream: readableStream, contentFileName: fileName, isContentPrivate }); break; - default: readableStream.resume(); - } - })).on('finish', () => { - reject(new RequestError('Missing content', 400)); - }); - }); -}; - -export default router; diff --git a/kat/src/routers/batches.ts b/kat/src/routers/batches.ts deleted file mode 100644 index 290a20ae1a..0000000000 --- a/kat/src/routers/batches.ts +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { Router } from 'express'; -import * as batchHandler from '../handlers/batches'; - -const router = Router(); - -router.get('/:batchID', async (req, res, next) => { - try { - res.send(await batchHandler.handleGetBatchRequest(req.params.batchID)); - } catch (err) { - next(err); - } -}); - -export default router; diff --git a/kat/src/routers/members.ts b/kat/src/routers/members.ts deleted file mode 100644 index c86b6b7c74..0000000000 --- a/kat/src/routers/members.ts +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { Router } from 'express'; -import * as membersHandler from '../handlers/members'; -import { config } from '../lib/config'; -import RequestError from '../lib/request-handlers'; -import { constants } from '../lib/utils'; - -const router = Router(); - -router.get('/', async (req, res, next) => { - try { - const skip = Number(req.query.skip || 0); - const limit = Number(req.query.limit || constants.DEFAULT_PAGINATION_LIMIT); - if (isNaN(skip) || isNaN(limit)) { - throw new RequestError('Invalid skip / limit', 400); - } - res.send(await membersHandler.handleGetMembersRequest({}, skip, limit)); - } catch (err) { - next(err); - } -}); - -router.get('/:memberAddress', async (req, res, next) => { - try { - res.send(await membersHandler.handleGetMemberRequest(req.params.memberAddress)); - } catch (err) { - next(err) - } -}); - -router.put('/', async (req, res, next) => { - try { - if (!req.body.address) { - throw new RequestError('Missing member address', 400); - } - if (!req.body.name) { - throw new RequestError('Missing member name', 400); - } - let assetTrailInstanceID, app2appDestination, docExchangeDestination; - switch (config.protocol) { - case 'corda': - if (!req.body.assetTrailInstanceID) { - throw new RequestError('Missing member assetTrailInstanceID', 400); - } - if (!req.body.app2appDestination) { - throw new RequestError('Missing member app2appDestination', 400); - } - if (!req.body.docExchangeDestination) { - throw new RequestError('Missing member docExchangeDestination', 400); - } - assetTrailInstanceID = req.body.assetTrailInstanceID; - app2appDestination = req.body.app2appDestination; - docExchangeDestination = req.body.docExchangeDestination; - break; - case 'ethereum': - assetTrailInstanceID = config.assetTrailInstanceID; - app2appDestination = config.app2app.destinations.kat; - docExchangeDestination = config.docExchange.destination; - break; - } - const sync = req.query.sync === 'true'; - await membersHandler.handleUpsertMemberRequest(req.body.address, req.body.name, assetTrailInstanceID, app2appDestination, docExchangeDestination, sync); - res.send({ status: sync ? 'success' : 'submitted' }); - } catch (err) { - next(err); - } -}); - -export default router; \ No newline at end of file diff --git a/kat/src/routers/payment-definitions.ts b/kat/src/routers/payment-definitions.ts deleted file mode 100644 index f9576365ad..0000000000 --- a/kat/src/routers/payment-definitions.ts +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { Router } from 'express'; -import RequestError from '../lib/request-handlers'; -import * as paymentDefinitionsHandler from '../handlers/payment-definitions'; -import { constants } from '../lib/utils'; -import * as utils from '../lib/utils'; -import { config } from '../lib/config'; - -const router = Router(); - -router.get('/', async (req, res, next) => { - try { - const skip = Number(req.query.skip || 0); - const limit = Number(req.query.limit || constants.DEFAULT_PAGINATION_LIMIT); - if (isNaN(skip) || isNaN(limit)) { - throw new RequestError('Invalid skip / limit', 400); - } - res.send(await paymentDefinitionsHandler.handleGetPaymentDefinitionsRequest({}, skip, limit)); - } catch (err) { - next(err); - } -}); - -router.get('/:paymentDefinitionID', async (req, res, next) => { - try { - res.send(await paymentDefinitionsHandler.handleGetPaymentDefinitionRequest(req.params.paymentDefinitionID)); - } catch (err) { - next(err); - } -}); - -router.post('/search', async (req, res, next) => { - try { - const skip = Number(req.body.skip || 0); - const limit = Number(req.body.limit || constants.DEFAULT_PAGINATION_LIMIT); - if (req.body.count !== true && (isNaN(skip) || isNaN(limit))) { - throw new RequestError('Invalid skip / limit', 400); - } - if (!req.body.query) { - throw new RequestError('Missing search query', 400); - } - res.send(req.body.count === true ? - await paymentDefinitionsHandler.handleCountPaymentDefinitionsRequest(req.body.query) : - await paymentDefinitionsHandler.handleGetPaymentDefinitionsRequest(req.body.query, skip, limit) - ); - } catch (err) { - next(err); - } -}); - -router.post('/', async (req, res, next) => { - try { - if (!req.body.name || req.body.name === '') { - throw new RequestError('Missing or invalid payment definition name', 400); - } - if (!utils.isAuthorValid(req.body.author, config.protocol)) { - throw new RequestError('Missing or invalid payment definition author', 400); - } - const sync = req.query.sync === 'true'; - const paymentDefinitionID = await paymentDefinitionsHandler.handleCreatePaymentDefinitionRequest(req.body.name, - req.body.author, req.body.descriptionSchema, sync); - res.send({ status: sync? 'success' : 'submitted', paymentDefinitionID }); - } catch (err) { - next(err); - } -}); - -export default router; diff --git a/kat/src/routers/payment-instances.ts b/kat/src/routers/payment-instances.ts deleted file mode 100644 index 032f5045c0..0000000000 --- a/kat/src/routers/payment-instances.ts +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { Router } from 'express'; -import RequestError from '../lib/request-handlers'; -import * as paymentInstancesHandler from '../handlers/payment-instances'; -import { constants } from '../lib/utils'; -import * as utils from '../lib/utils'; -import { config } from '../lib/config'; - -const router = Router(); - -router.get('/', async (req, res, next) => { - try { - const skip = Number(req.query.skip || 0); - const limit = Number(req.query.limit || constants.DEFAULT_PAGINATION_LIMIT); - if (isNaN(skip) || isNaN(limit)) { - throw new RequestError('Invalid skip / limit', 400); - } - res.send(await paymentInstancesHandler.handleGetPaymentInstancesRequest({}, req.body.sort || {}, skip, limit)); - } catch (err) { - next(err); - } -}); - -router.get('/:assetInstanceID', async (req, res, next) => { - try { - res.send(await paymentInstancesHandler.handleGetPaymentInstanceRequest(req.params.assetInstanceID)); - } catch (err) { - next(err); - } -}); - -router.post('/search', async (req, res, next) => { - try { - const skip = Number(req.body.skip || 0); - const limit = Number(req.body.limit || constants.DEFAULT_PAGINATION_LIMIT); - if (req.body.count !== true && (isNaN(skip) || isNaN(limit))) { - throw new RequestError('Invalid skip / limit', 400); - } - if (!req.body.query) { - throw new RequestError('Missing search query', 400); - } - res.send(req.body.count === true ? - await paymentInstancesHandler.handleCountPaymentInstancesRequest(req.body.query) : - await paymentInstancesHandler.handleGetPaymentInstancesRequest(req.body.query, req.body.sort || {}, skip, limit) - ); - } catch (err) { - next(err); - } -}); - -router.post('/', async (req, res, next) => { - try { - if (!req.body.paymentDefinitionID) { - throw new RequestError('Missing payment definition ID', 400); - } - if (!utils.isAuthorValid(req.body.author, config.protocol)) { - throw new RequestError('Missing or invalid payment author', 400); - } - if (!utils.isAuthorValid(req.body.member, config.protocol)) { - throw new RequestError('Missing or invalid payment member', 400); - } - if (req.body.author === req.body.member) { - throw new RequestError('Author and member cannot be the same', 400); - } - if (!(Number.isInteger(req.body.amount) && req.body.amount > 0)) { - throw new RequestError('Missing or invalid payment amount', 400); - } - const sync = req.query.sync === 'true'; - const paymentInstanceID = await paymentInstancesHandler.handleCreatePaymentInstanceRequest(req.body.author, req.body.paymentDefinitionID, req.body.member, req.body.description, req.body.amount, req.body.participants, sync); - res.send({ status: sync? 'success' : 'submitted', paymentInstanceID }); - } catch (err) { - next(err); - } - -}); - -export default router; diff --git a/kat/src/routers/settings.ts b/kat/src/routers/settings.ts deleted file mode 100644 index 58e3b55e1c..0000000000 --- a/kat/src/routers/settings.ts +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { Router } from 'express'; -import * as settings from '../lib/settings'; -import RequestError from '../lib/request-handlers'; - -const router = Router(); - -router.get('/', async (_req, res, next) => { - try { - res.send(settings.settings); - } catch (err) { - next(err); - } -}); - -router.put('/', async (req, res, next) => { - try { - if (req.body.key === undefined || req.body.value === undefined) { - throw new RequestError('Invalid setting key/value', 400); - } - await settings.updateSettings(req.body.key, req.body.value); - res.send({ status: 'success' }); - } catch (err) { - next(err); - } -}); - -export default router; \ No newline at end of file diff --git a/kat/src/schemas/asset-definition.json b/kat/src/schemas/asset-definition.json deleted file mode 100644 index 82392a60c6..0000000000 --- a/kat/src/schemas/asset-definition.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": false, - "required": [ - "assetDefinitionID", - "name", - "isContentPrivate", - "isContentUnique" - ], - "properties": { - "assetDefinitionID": { - "type": "string" - }, - "name": { - "type": "string" - }, - "isContentPrivate": { - "type": "boolean" - }, - "isContentUnique": { - "type": "boolean" - }, - "descriptionSchema": { - "type": "object" - }, - "contentSchema": { - "type": "object" - }, - "indexes": { - "type": "array" - } - } -} \ No newline at end of file diff --git a/kat/src/schemas/config.json b/kat/src/schemas/config.json deleted file mode 100644 index b01fa24fa8..0000000000 --- a/kat/src/schemas/config.json +++ /dev/null @@ -1,199 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": [ - "port", - "assetTrailInstanceID", - "protocol", - "apiGateway", - "eventStreams", - "ipfs", - "app2app", - "docExchange", - "appCredentials" - ], - "properties": { - "port": { - "type": "integer" - }, - "assetTrailInstanceID": { - "type": "string" - }, - "protocol": { - "type": "string", - "enum": ["ethereum", "corda"] - }, - "apiGateway": { - "type": "object", - "required": [ - "apiEndpoint" - ], - "properties": { - "apiEndpoint": { - "type": "string" - }, - "auth": { - "type": "object", - "required": [ - "user", - "password" - ], - "properties": { - "user": { - "type": "string" - }, - "password": { - "type": "string" - } - } - } - } - }, - "eventStreams": { - "type": "object", - "required": [ - "wsEndpoint", - "topic" - ], - "properties": { - "wsEndpoint": { - "type": "string" - }, - "topic": { - "type": "string" - }, - "skipSetup": { - "type": "boolean", - "$comment": "Should only be set to true in development or testing" - }, - "auth": { - "type": "object", - "required": [ - "user", - "password" - ], - "properties": { - "user": { - "type": "string" - }, - "password": { - "type": "string" - } - } - }, - "config": { - "type": "object", - "required": [ - "batchSize", - "batchTimeoutMS", - "errorHandling", - "blockedRetryDelaySec" - ], - "properties": { - "batchSize": { - "type": "number" - }, - "batchTimeoutMS": { - "type": "number" - }, - "blockedRetryDelaySec":{ - "type":"number" - }, - "errorHandling":{ - "type":"string", - "enum": ["block", "skip"] - } - } - } - } - }, - "ipfs": { - "type": "object", - "required": [ - "apiEndpoint" - ], - "properties": { - "apiEndpoint": { - "type": "string" - }, - "gatewayEndpoint": { - "type": "string" - } - } - }, - "app2app": { - "type": "object", - "required": [ - "socketIOEndpoint", - "destinations" - ], - "properties": { - "socketIOEndpoint": { - "type": "string" - }, - "destinations": { - "type": "object", - "required": [ - "kat", - "client" - ], - "properties": { - "kat": { - "type": "string" - }, - "client": { - "type": "string" - } - } - } - } - }, - "docExchange": { - "type": "object", - "required": [ - "apiEndpoint", - "socketIOEndpoint", - "destination" - ], - "properties": { - "apiEndpoint": { - "type": "string" - }, - "socketIOEndpoint": { - "type": "string" - }, - "destination": { - "type": "string" - } - } - }, - "appCredentials": { - "type": "object", - "required": [ - "user", - "password" - ], - "properties": { - "user": { - "type": "string" - }, - "password": { - "type": "string" - } - } - }, - "mongodb": { - "type": "object", - "required": [ - "connectionUrl", - "databaseName" - ], - "connectionUrl": { - "type": "string" - }, - "databaseName": { - "type": "string" - } - } - } -} \ No newline at end of file diff --git a/kat/src/schemas/indexes.json b/kat/src/schemas/indexes.json deleted file mode 100644 index fb790095a1..0000000000 --- a/kat/src/schemas/indexes.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "array", - "items": { "$ref": "#/definitions/index" }, - "definitions": { - "index": { - "type": "object", - "required": [ "fields", "unique" ], - "properties": { - "fields": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Fields specified to be an index" - }, - "unique": { - "type": "boolean", - "description": "Whether the index property allows duplicate values" - } - } - } - } -} \ No newline at end of file diff --git a/kat/src/schemas/settings.json b/kat/src/schemas/settings.json deleted file mode 100644 index bdd54108b5..0000000000 --- a/kat/src/schemas/settings.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": [ - "clientEvents" - ], - "properties": { - "clientEvents": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "member-registered", - "asset-definition-submitted", - "asset-definition-created", - "asset-definition-name-conflict", - "payment-definition-submitted", - "payment-definition-created", - "payment-definition-name-conflict", - "asset-instance-submitted", - "asset-instance-created", - "asset-instance-content-conflict", - "payment-instance-submitted", - "payment-instance-created", - "private-asset-instance-content-stored", - "asset-instance-property-submitted", - "asset-instance-property-set" - ] - } - } - } -} \ No newline at end of file diff --git a/kat/src/test/common.ts b/kat/src/test/common.ts deleted file mode 100644 index 5c8a537861..0000000000 --- a/kat/src/test/common.ts +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { EventEmitter } from 'events'; -import rimraf from 'rimraf'; -import nock from 'nock'; -import mock from 'mock-require'; -import { promises as fs } from 'fs'; -import path from 'path'; -import assert from 'assert'; -import request from 'supertest'; -import * as utils from '../lib/utils'; -import { IEventMemberRegistered } from "../lib/interfaces"; -export let app: Express.Application; -export let mockEventStreamWebSocket: EventEmitter; -export let mockDocExchangeSocketIO = new EventEmitter(); - -let shutDown: () => void; - -class MockWebSocket extends EventEmitter { - - constructor(url: string) { - super(); - assert.strictEqual(url, 'ws://eventstreams.kaleido.io'); - mockEventStreamWebSocket = this; - } - - send(message: string) { - mockEventStreamWebSocket.emit('send', message); - } - - ping() { } - - close() { } - -}; - -export const setUp = async (protocol: string) => { - await new Promise((resolve, reject) => { - rimraf(path.join(__dirname, `../../test-resources/sandbox/${protocol}`), {}, (err) => { - if (err) { - reject() - } else { - resolve(); - } - }); - }); - - const sandboxPath = path.join(__dirname, `../../test-resources/sandbox/${protocol}`); - await fs.mkdir(sandboxPath, { recursive: true }); - await fs.copyFile(path.join(__dirname, '../../test-resources/settings.json'), path.join(sandboxPath, 'settings.json')); - await fs.copyFile(path.join(__dirname, `../../test-resources/config-${protocol}.json`), path.join(sandboxPath, 'config.json')); - - mock('ws', MockWebSocket); - mock('socket.io-client', { - connect: () => { - return mockDocExchangeSocketIO; - } - }); - // IPFS - nock('https://ipfs.kaleido.io') - .post('/api/v0/version') - .reply(200, { Version: 1 }); - - // Doc exchange REST API - nock('https://docexchange.kaleido.io') - .get('/documents') - .reply(200, { entries: [] }); - - nock('https://apigateway.kaleido.io') - .get('/subscriptions') - .reply(200, [{ - name: 'AssetInstanceCreated', - stream: 'es12345' - }]); - - const nockSubscribe = (description: string, name: string) => { - if(protocol === 'ethereum') { - nock('https://apigateway.kaleido.io') - .post(`/${name}/Subscribe`, { - description, - name, - stream: 'es12345', - }) - .reply(200, {}); - } else { - nock('https://apigateway.kaleido.io') - .post(`/subscriptions`, { - name, - stream: 'es12345', - fromTime: null, - filter: { - stateType: name, - stateStatus: "unconsumed", - relevancyStatus: "all" - } - }) - .reply(200, {}); - } - }; - - const nockEventStreamsWithRetry = () => { - // event stream and subscriptions - nock('https://apigateway.kaleido.io') - .get('/eventstreams') - .times(2) - .reply(200, []); - - nock('https://apigateway.kaleido.io') - .post('/eventstreams', { - name: 'dev', - errorHandling: "block", - blockedReryDelaySec: 30, - batchTimeoutMS: 500, - batchSize: 50, - type: "websocket", - websocket: { - topic: 'dev', - } - }) - .reply(500); - - nock('https://apigateway.kaleido.io') - .post('/eventstreams', { - name: 'dev', - errorHandling: "block", - blockedReryDelaySec: 30, - batchTimeoutMS: 500, - batchSize: 50, - type: "websocket", - websocket: { - topic: 'dev', - } - }) - .reply(200, { - id: 'es12345' - }); - } - - const nockEventStreamsWithRetryCorda = () => { - // event stream and subscriptions - nock('https://apigateway.kaleido.io') - .get('/eventstreams') - .times(2) - .reply(200, []); - - nock('https://apigateway.kaleido.io') - .post('/eventstreams', { - name: 'dev', - errorHandling: "block", - blockedRetryDelaySec: 30, - batchTimeoutMS: 500, - batchSize: 50, - type: "websocket", - websocket: { - topic: 'dev', - } - }) - .reply(500); - - nock('https://apigateway.kaleido.io') - .post('/eventstreams', { - name: 'dev', - errorHandling: "block", - blockedRetryDelaySec: 30, - batchTimeoutMS: 500, - batchSize: 50, - type: "websocket", - websocket: { - topic: 'dev', - } - }) - .reply(200, { - id: 'es12345' - }); - } - if(protocol === 'ethereum') { - nockEventStreamsWithRetry(); - nockSubscribe('Asset instance created', 'AssetInstanceCreated'); - nockSubscribe('Asset instance batch created', 'AssetInstanceBatchCreated'); - nockSubscribe('Payment instance created', 'PaymentInstanceCreated'); - nockSubscribe('Payment definition created', 'PaymentDefinitionCreated'); - nockSubscribe('Asset definition created', 'AssetDefinitionCreated'); - nockSubscribe('Asset instance property set', 'AssetInstancePropertySet'); - nockSubscribe('Described payment instance created', 'DescribedPaymentInstanceCreated'); - nockSubscribe('Described asset instance created', 'DescribedAssetInstanceCreated'); - nockSubscribe('Described payment definition created', 'DescribedPaymentDefinitionCreated'); - nockSubscribe('Member registered', 'MemberRegistered'); - } else { - nockEventStreamsWithRetryCorda(); - nockSubscribe('Asset instance created', 'io.kaleido.kat.states.AssetInstanceCreated'); - nockSubscribe('Asset instance batch created', 'io.kaleido.kat.states.AssetInstanceBatchCreated'); - nockSubscribe('Asset instance property set', 'io.kaleido.kat.states.AssetInstancePropertySet'); - nockSubscribe('Described asset instance created', 'io.kaleido.kat.states.DescribedAssetInstanceCreated'); - } - - const { promise } = require('../app'); - ({ app, shutDown } = await promise); - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"listen","topic":"dev"}'); - resolve(); - }) - }); - - mockEventStreamWebSocket.emit('open'); - mockDocExchangeSocketIO.emit('connect'); - - await eventPromise; - - if (protocol === 'corda') { - await setupSampleMembersCorda(); - } else { - await setupSampleMembersEthereum(); - } -} - -const setupSampleMembersCorda = async () => { - console.log('Setting up corda members'); - await request(app) - .put('/api/v1/members') - .send({ - address: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - name: 'Test Member 1', - assetTrailInstanceID: 'service-id_1', - app2appDestination: 'kld://app2app_1', - docExchangeDestination: 'kld://docexchange_1' - }); - - await request(app) - .put('/api/v1/members') - .send({ - address: 'CN=Node of node2 for env1, O=Kaleido, L=Raleigh, C=US', - name: 'Test Member 2', - assetTrailInstanceID: 'service-id_2', - app2appDestination: 'kld://app2app_2', - docExchangeDestination: 'kld://docexchange_2' - }); -}; - -const setupSampleMembersEthereum = async () => { - console.log('Setting up ethereum members'); - nock('https://apigateway.kaleido.io') - .post('/registerMember?kld-from=0x0000000000000000000000000000000000000001&kld-sync=true') - .reply(200); - await request(app) - .put('/api/v1/members') - .send({ - address: '0x0000000000000000000000000000000000000001', - name: 'Test Member 1', - app2appDestination: 'kld://app2app_1', - docExchangeDestination: 'kld://docexchange_1' - }) - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const dataMember1: IEventMemberRegistered = { - member: '0x0000000000000000000000000000000000000001', - name: 'Test Member 1', - assetTrailInstanceID: 'service-instance', - app2appDestination: 'kld://app2app_1', - docExchangeDestination: 'kld://docexchange_1', - timestamp: utils.getTimestamp() - } - const dataMember2: IEventMemberRegistered = - { - member: '0x0000000000000000000000000000000000000002', - name: 'Test Member 2', - assetTrailInstanceID: 'service-instance', - app2appDestination: 'kld://app2app_2', - docExchangeDestination: 'kld://docexchange_2', - timestamp: utils.getTimestamp() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.MEMBER_REGISTERED, - data: dataMember1, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }, { - signature: utils.contractEventSignatures.MEMBER_REGISTERED, - data: dataMember2, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; -}; - -export const closeDown = async () => { - shutDown(); - mock.stop('ws'); - mock.stop('socket.io-client'); - nock.restore(); -}; diff --git a/kat/src/test/corda-suite.ts b/kat/src/test/corda-suite.ts deleted file mode 100644 index a7cf5e1893..0000000000 --- a/kat/src/test/corda-suite.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { closeDown, setUp } from "./common"; -import { cordaTests } from "./corda"; - -describe('corda tests', async () => { - before(async () => { - await setUp('corda'); - }); - cordaTests(); - after(async () => { - await closeDown(); - }); -}); \ No newline at end of file diff --git a/kat/src/test/corda/assets/argument-validation.ts b/kat/src/test/corda/assets/argument-validation.ts deleted file mode 100644 index 8212dc0db7..0000000000 --- a/kat/src/test/corda/assets/argument-validation.ts +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app } from '../../common'; -import request from 'supertest'; -import assert from 'assert'; - -export const testAssetArgumentValidation = () => { -describe('Asset definitions - argument validation', async () => { - - it('Attempting to get an asset definition that does not exist should raise an error', async () => { - const result = await request(app) - .get('/api/v1/assets/definitions/1000000') - .expect(404); - assert.deepStrictEqual(result.body, { error: 'Asset definition not found' }); - }); - - it('Attempting to add an asset definition without a name should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - isContentPrivate: false, - isContentUnique: true - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing or invalid asset definition name' }); - }); - - it('Attempting to add an asset definition without an author should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: 'My asset definition', - isContentPrivate: false, - isContentUnique: true - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing or invalid asset definition author' }); - }); - - it('Attempting to add an asset definition without an valid author name should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: 'My asset definition', - isContentPrivate: false, - isContentUnique: true, - author: "invalid name" - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing or invalid asset definition author' }); - }); - - it('Attempting to add an asset definition without indicating if the content should be private or not should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: 'My asset definition', - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - isContentUnique: true - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing asset definition content privacy' }); - }); - - it('Attempting to add an asset definition without a definition id should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: 'My asset definition', - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - isContentUnique: true, - isContentPrivate: false - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing asset definition id' }); - }); - - it('Attempting to add an asset definition with an invalid index schema should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: 'My asset definition', - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - assetDefinitionID: 'some-uuid', - isContentPrivate: false, - isContentUnique: true, - indexes: {} - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Indexes do not conform to index schema' }); - }); - - it('Attempting to add an asset definition with an invalid description schema should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: 'My asset definition', - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - assetDefinitionID: 'some-uuid', - descriptionSchema: 'INVALID', - isContentPrivate: false, - isContentUnique: true - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Invalid description schema' }); - }); - - it('Attempting to add an asset definition with an invalid content schema should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: 'My asset definition', - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - assetDefinitionID: 'some-uuid', - contentSchema: 'INVALID', - isContentPrivate: false, - isContentUnique: true - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Invalid content schema' }); - }); -}); - -describe('Asset instances - argument validation', async () => { - - it('Attempting to add an asset instance without specifying the author should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx') - .send({ - assetDefinitionID: '', - content: {} - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing or invalid asset instance author' }); - }); - - it('Attempting to add an asset instance without specifying the content should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx') - .send({ - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing or invalid asset content' }); - }); -}); -}; \ No newline at end of file diff --git a/kat/src/test/corda/assets/authored-private-structured.ts b/kat/src/test/corda/assets/authored-private-structured.ts deleted file mode 100644 index 281ec55aa5..0000000000 --- a/kat/src/test/corda/assets/authored-private-structured.ts +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../common'; -import { v4 as uuidV4 } from 'uuid'; -import { testContent } from '../../samples'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IDBAssetDefinition, IDBAssetInstance} from '../../../lib/interfaces'; -import * as utils from '../../../lib/utils'; - -export const testAssetsAuthoredPrivateStructured = () => { - -describe('Assets: authored - structured', async () => { - - let assetDefinitionID = uuidV4(); - const assetDefinitionName = 'authored - private - structured'; - const timestamp = new Date(); - - describe('Create asset definition', () => { - - it('Checks that the asset definition can be added', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetDefinition') - .reply(200); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: 'Qmf71q7zspRmzvH6yVhkrpWCnK54rvxyj6XSTJ5tgBiZfV' }); - - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: assetDefinitionName, - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - assetDefinitionID, - isContentPrivate: true, - isContentUnique: true, - contentSchema: testContent.schema.object - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - private - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US'); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object); - assert.strictEqual(assetDefinition.name, 'authored - private - structured'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - }); - - }); - - describe('Asset instances', async () => { - - let assetInstanceID: string; - - describe('Asset instances - argument validation', async () => { - it('Attempting to add an asset instance without specifying participants should raise an error', async () => { - const result = await request(app) - .post(`/api/v1/assets/${assetDefinitionID}`) - .send({ - content: { - my_content_string: 'test sample content string', - my_content_number: 124, - my_content_boolean: false - }, - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing asset participants' }); - }); - - it('Attempting to add an asset instance without specifying participants should raise an error', async () => { - const result = await request(app) - .post(`/api/v1/assets/${assetDefinitionID}`) - .send({ - content: { - my_content_string: 'test sample content string', - my_content_number: 124, - my_content_boolean: false - }, - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - participants: ['CN=Node of node3 for env1, O=Kaleido, L=Raleigh, C=US'] - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: `One or more participants are not registered` }); - }); - - it('Attempting to set an asset instance property without specifying key should raise an error', async () => { - const result = await request(app) - .put(`/api/v1/assets/some-asset-def-id/some-asset-id`) - .send({ - action: 'set-property', - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: `Missing asset property key` }); - }); - - it('Attempting to set an asset instance property without specifying value should raise an error', async () => { - const result = await request(app) - .put(`/api/v1/assets/some-asset-def-id/some-asset-id`) - .send({ - action: 'set-property', - key: 'key', - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: `Missing asset property value` }); - }); - }); - - it('Checks that an asset instance can be created', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetInstance') - .reply(200); - - const result = await request(app) - .post(`/api/v1/assets/${assetDefinitionID}`) - .send({ - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - content: testContent.sample.object, - participants: ['CN=Node of node2 for env1, O=Kaleido, L=Raleigh, C=US'] - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetInstanceID = result.body.assetInstanceID; - - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.contentHash, testContent.sample.docExchangeSha256); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - assert.strictEqual(typeof assetInstance.submitted, 'number'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - - }); - - it('Checks that the event stream notification for confirming the asset instance creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const assetData: any = { - assetDefinitionID: assetDefinitionID, - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - assetInstanceID: assetInstanceID, - contentHash: testContent.sample.docExchangeSha256, - participants: ['CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', 'CN=Node of node2 for env1, O=Kaleido, L=Raleigh, C=US'] - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignaturesCorda.ASSET_INSTANCE_CREATED, - data: {data: assetData}, - stateRef: { - txhash: "25D867CC5D19AB40AE46E6262F3C274A6B772D68A0AA522F4C5A96196EAF5FCE", - index: 0 - }, - subId: "sb-f5abe54b-53fb-4f63-8236-f3a8a6bc1c60", - recordedTime: timestamp.toISOString(), - consumedTime: null - }])); - await eventPromise; - }); - - it('Checks that the asset instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.contentHash, testContent.sample.docExchangeSha256); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - assert.strictEqual(assetInstance.timestamp, timestamp.getTime()); - assert.strictEqual(typeof assetInstance.submitted, 'number'); - assert.strictEqual(assetInstance.transactionHash, '25D867CC5D19AB40AE46E6262F3C274A6B772D68A0AA522F4C5A96196EAF5FCE'); - assert.deepStrictEqual(assetInstance.participants, ['CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', 'CN=Node of node2 for env1, O=Kaleido, L=Raleigh, C=US']) - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - }); - - it('Checks that the asset instance property can be set', async () => { - nock('https://apigateway.kaleido.io') - .post('/setAssetInstanceProperty') - .reply(200); - - const result = await request(app) - .put(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .send({ - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - action: 'set-property', - key: 'key1', - value: 'value1' - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US'); - assert.strictEqual(assetInstance.properties[assetInstance.author]['key1'].value, 'value1'); - assert.strictEqual(typeof assetInstance.properties[assetInstance.author]['key1'].submitted, 'number'); - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - - }); - - it('Checks that the event stream notification for confirming the asset instance set property is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const assetData: any = { - assetDefinitionID: assetDefinitionID, - author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', - assetInstanceID: assetInstanceID, - key: 'key1', - value: 'value1', - participants: ['CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', 'CN=Node of node2 for env1, O=Kaleido, L=Raleigh, C=US'] - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignaturesCorda.ASSET_PROPERTY_SET, - data: {data: assetData}, - stateRef: { - txhash: "35D867CC5D19AB40AE46E6262F3C274A6B772D68A0AA522F4C5A96196EAF5FCE", - index: 0 - }, - subId: "sb-f5abe54b-53fb-4f63-8236-f3a8a6bc1c60", - recordedTime: timestamp.toISOString(), - consumedTime: null - }])); - await eventPromise; - }); - - it('Checks that the asset instance property set is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.contentHash, testContent.sample.docExchangeSha256); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - assert.strictEqual(assetInstance.timestamp, timestamp.getTime()); - assert.strictEqual(typeof assetInstance.submitted, 'number'); - assert.strictEqual(assetInstance.transactionHash, '25D867CC5D19AB40AE46E6262F3C274A6B772D68A0AA522F4C5A96196EAF5FCE'); - assert.deepStrictEqual(assetInstance.participants, ['CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', 'CN=Node of node2 for env1, O=Kaleido, L=Raleigh, C=US']) - assert.strictEqual(assetInstance.properties[assetInstance.author]['key1'].value, 'value1'); - assert.strictEqual(typeof assetInstance.properties[assetInstance.author]['key1'].submitted, 'number'); - assert.strictEqual(assetInstance.properties[assetInstance.author]['key1'].history[assetInstance.timestamp].transactionHash, '35D867CC5D19AB40AE46E6262F3C274A6B772D68A0AA522F4C5A96196EAF5FCE'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/corda/assets/index.ts b/kat/src/test/corda/assets/index.ts deleted file mode 100644 index 61561f04d7..0000000000 --- a/kat/src/test/corda/assets/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { testAssetArgumentValidation } from "./argument-validation"; -import { testAssetsAuthoredPrivateStructured } from "./authored-private-structured"; - -export const testAssets = async () => { - describe('Asset tests', async () => { - testAssetArgumentValidation(); - testAssetsAuthoredPrivateStructured(); - }); -}; \ No newline at end of file diff --git a/kat/src/test/corda/index.ts b/kat/src/test/corda/index.ts deleted file mode 100644 index f4f4743ab7..0000000000 --- a/kat/src/test/corda/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { testAssets } from './assets'; -import { testMembers } from './members'; - - -export const cordaTests = async () => { - testAssets(); - testMembers(); -}; \ No newline at end of file diff --git a/kat/src/test/corda/members/argument-validation.ts b/kat/src/test/corda/members/argument-validation.ts deleted file mode 100644 index 83f433f928..0000000000 --- a/kat/src/test/corda/members/argument-validation.ts +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app } from '../../common'; -import request from 'supertest'; -import assert from 'assert'; - -export const testMembersArgumentValidation = async () => { - -describe('Members - argument validation', async () => { - - it('Attempting to add a member without an address should raise an error', async () => { - const result = await request(app) - .put('/api/v1/members') - .send({ - name: 'Member A', - app2appDestination: 'kld://app2app', - docExchangeDestination: 'kld://docexchange' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing member address' }); - }); - - it('Attempting to add a member without a name should raise an error', async () => { - const result = await request(app) - .put('/api/v1/members') - .send({ - address: '0x0000000000000000000000000000000000000001', - app2appDestination: 'kld://app2app', - docExchangeDestination: 'kld://docexchange' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing member name' }); - }); - - it('Attempting to add a member without a assetTrailInstanceID should raise an error', async () => { - const result = await request(app) - .put('/api/v1/members') - .send({ - name: 'Member A', - address: '0x0000000000000000000000000000000000000001', - app2appDestination: 'kld://app2app', - docExchangeDestination: 'kld://docexchange' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing member assetTrailInstanceID' }); - }); - - it('Attempting to add a member without a docExchangeDestination should raise an error', async () => { - const result = await request(app) - .put('/api/v1/members') - .send({ - name: 'Member A', - address: '0x0000000000000000000000000000000000000001', - app2appDestination: 'kld://app2app', - assetTrailInstanceID: 'asset-instance-a' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing member docExchangeDestination' }); - }); - - it('Attempting to add a member without a app2appDestination should raise an error', async () => { - const result = await request(app) - .put('/api/v1/members') - .send({ - name: 'Member A', - address: '0x0000000000000000000000000000000000000001', - assetTrailInstanceID: 'asset-instance-a', - docExchangeDestination: 'kld://docexchange' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing member app2appDestination' }); - }); - - it('Attempting to get a member that does not exist should raise an error', async () => { - const result = await request(app) - .get('/api/v1/members/0x0000000000000000000000000000000000000099') - .expect(404); - assert.deepStrictEqual(result.body, { error: 'Member not found' }); - }); - -}); -}; diff --git a/kat/src/test/corda/members/index.ts b/kat/src/test/corda/members/index.ts deleted file mode 100644 index 879158fadc..0000000000 --- a/kat/src/test/corda/members/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { testMembersArgumentValidation } from "./argument-validation"; -import { testMemberRegistration } from "./registration"; - -export const testMembers = async () => { - describe('Member tests', async () => { - testMembersArgumentValidation(); - testMemberRegistration(); - }); -}; \ No newline at end of file diff --git a/kat/src/test/corda/members/registration.ts b/kat/src/test/corda/members/registration.ts deleted file mode 100644 index edba546421..0000000000 --- a/kat/src/test/corda/members/registration.ts +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app } from '../../common'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IDBMember } from '../../../lib/interfaces'; - -export const testMemberRegistration = async () => { - -describe('Members - registration', async () => { - it('Checks that adding a member sends a request to API Gateway and updates the database', async () => { - - nock('https://apigateway.kaleido.io') - .post('/registerMember') - .reply(200); - const addMemberResponse = await request(app) - .put('/api/v1/members') - .send({ - address: 'CN=Node of member1 for env1, O=Kaleido, L=Raleigh, C=US', - name: 'Member 1', - assetTrailInstanceID: 'service-id', - app2appDestination: 'kld://app2app/internal', - docExchangeDestination:'kld://docstore/dest' - }) - .expect(200); - assert.deepStrictEqual(addMemberResponse.body, { status: 'submitted' }); - - const getMemberResponse = await request(app) - .get('/api/v1/members') - .expect(200); - const member = getMemberResponse.body.find((member: IDBMember) => member.address === 'CN=Node of member1 for env1, O=Kaleido, L=Raleigh, C=US'); - assert.strictEqual(member.address, 'CN=Node of member1 for env1, O=Kaleido, L=Raleigh, C=US'); - assert.strictEqual(member.name, 'Member 1'); - assert.strictEqual(member.assetTrailInstanceID, 'service-id'); - assert.strictEqual(member.app2appDestination, 'kld://app2app/internal'); - assert.strictEqual(member.docExchangeDestination, 'kld://docstore/dest'); - assert.strictEqual(typeof member.submitted, 'number'); - - const getMemberByAddressResponse = await request(app) - .get('/api/v1/members/CN=Node of member1 for env1, O=Kaleido, L=Raleigh, C=US') - .expect(200); - assert.deepStrictEqual(member, getMemberByAddressResponse.body); - }); - - it('Get member should return the confirmed member', async () => { - const getMemberResponse = await request(app) - .get('/api/v1/members') - .expect(200); - const member = getMemberResponse.body.find((member: IDBMember) => member.address === 'CN=Node of member1 for env1, O=Kaleido, L=Raleigh, C=US'); - assert.strictEqual(member.address, 'CN=Node of member1 for env1, O=Kaleido, L=Raleigh, C=US'); - assert.strictEqual(member.name, 'Member 1'); - assert.strictEqual(member.assetTrailInstanceID, 'service-id'); - assert.strictEqual(member.app2appDestination, 'kld://app2app/internal'); - assert.strictEqual(member.docExchangeDestination, 'kld://docstore/dest'); - - const getMemberByAddressResponse = await request(app) - .get('/api/v1/members/CN=Node of member1 for env1, O=Kaleido, L=Raleigh, C=US') - .expect(200); - assert.deepStrictEqual(member, getMemberByAddressResponse.body); - }); - -}); -}; diff --git a/kat/src/test/ethereum-suite.ts b/kat/src/test/ethereum-suite.ts deleted file mode 100644 index f735c71f93..0000000000 --- a/kat/src/test/ethereum-suite.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { closeDown, setUp } from "./common"; -import { ethereumTests } from "./ethereum"; -describe('ethereum tests for initial bootstrap', async () => { - before(async () => { - await setUp('ethereum'); - }); - ethereumTests(); - after(async () => { - await closeDown(); - }); -}); diff --git a/kat/src/test/ethereum/assets/argument-validation.ts b/kat/src/test/ethereum/assets/argument-validation.ts deleted file mode 100644 index f3760b4595..0000000000 --- a/kat/src/test/ethereum/assets/argument-validation.ts +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app } from '../../common'; -import request from 'supertest'; -import assert from 'assert'; - -export const testAssetArgumentValidation = () => { -describe('Asset definitions - argument validation', async () => { - it('Attempting to get an asset definition that does not exist should raise an error', async () => { - const result = await request(app) - .get('/api/v1/assets/definitions/1000000') - .expect(404); - assert.deepStrictEqual(result.body, { error: 'Asset definition not found' }); - }); - - it('Attempting to add an asset definition without a name should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - author: '0x0000000000000000000000000000000000000001', - isContentPrivate: false, - isContentUnique: true - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing or invalid asset definition name' }); - }); - - it('Attempting to add an asset definition without an author should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: 'My asset definition', - isContentPrivate: false, - isContentUnique: true - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing or invalid asset definition author' }); - }); - - it('Attempting to add an asset definition with an invalid index schema should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: 'My asset definition', - author: '0x0000000000000000000000000000000000000001', - isContentPrivate: false, - isContentUnique: true, - indexes: {} - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Indexes do not conform to index schema' }); - }); - - it('Attempting to add an asset definition without indicating if the content should be private or not should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: 'My asset definition', - author: '0x0000000000000000000000000000000000000001', - isContentUnique: true - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing asset definition content privacy' }); - }); - - it('Attempting to add an asset definition with an invalid description schema should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: 'My asset definition', - author: '0x0000000000000000000000000000000000000001', - descriptionSchema: 'INVALID', - isContentPrivate: false, - isContentUnique: true - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Invalid description schema' }); - }); - - it('Attempting to add an asset definition with an invalid content schema should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: 'My asset definition', - author: '0x0000000000000000000000000000000000000001', - contentSchema: 'INVALID', - isContentPrivate: false, - isContentUnique: true - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Invalid content schema' }); - }); - -}); - -describe('Asset instances - argument validation', async () => { - - it('Attempting to add an asset instance without specifying the author should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx') - .send({ - assetDefinitionID: '', - content: {} - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing or invalid asset instance author' }); - }); - - it('Attempting to add an asset instance without specifying the content should raise an error', async () => { - const result = await request(app) - .post('/api/v1/assets/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx') - .send({ - author: '0x0000000000000000000000000000000000000001' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing or invalid asset content' }); - }); - -}); -}; diff --git a/kat/src/test/ethereum/assets/authored/private/described-structured.ts b/kat/src/test/ethereum/assets/authored/private/described-structured.ts deleted file mode 100644 index 067470d225..0000000000 --- a/kat/src/test/ethereum/assets/authored/private/described-structured.ts +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import assert from 'assert'; -import { createHash, randomBytes } from 'crypto'; -import nock from 'nock'; -import request from 'supertest'; -import { promisify } from 'util'; -import { IDBAssetDefinition, IDBAssetInstance, IEventAssetDefinitionCreated, IEventAssetInstanceBatchCreated } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; -import { app, mockEventStreamWebSocket } from '../../../../common'; -import { testContent, testDescription, testIndexes } from '../../../../samples'; -const delay = promisify(setTimeout); - -export const testAuthoredPrivateDescribedStructured = () => { -describe('Assets: authored - private - described - structured', async () => { - - let assetDefinitionID: string; - const assetDefinitionName = 'authored - private - described - structured'; - const timestamp = utils.getTimestamp(); - const batchHashSha256 = '0x' + createHash('sha256').update(randomBytes(10)).digest().toString('hex'); - const batchHashIPFSMulti = utils.sha256ToIPFSHash(batchHashSha256); - - let batchMaxRecordsToRestore: number; - beforeEach(() => { - nock.cleanAll(); - // Force batches to close immediately - batchMaxRecordsToRestore = utils.constants.BATCH_MAX_RECORDS; - utils.constants.BATCH_MAX_RECORDS = 1; - }); - - afterEach(() => { - assert.deepStrictEqual(nock.pendingMocks(), []); - utils.constants.BATCH_MAX_RECORDS = batchMaxRecordsToRestore; - }); - - describe('Create asset definition', () => { - - it('Checks that the asset definition can be added', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetDefinition?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: 'QmQX1g8GwrMuACuMfQmKXzeYd7yXMXPpcUaFMqLUzSv1yL' }); - - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: assetDefinitionName, - author: '0x0000000000000000000000000000000000000001', - isContentPrivate: true, - isContentUnique: true, - descriptionSchema: testDescription.schema.object, - contentSchema: testContent.schema.object, - indexes: testIndexes - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetDefinitionID = result.body.assetDefinitionID; - - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - private - described - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.deepStrictEqual(assetDefinition.descriptionSchema, testDescription.schema.object); - assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object); - assert.strictEqual(assetDefinition.name, 'authored - private - described - structured'); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmQX1g8GwrMuACuMfQmKXzeYd7yXMXPpcUaFMqLUzSv1yL') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: assetDefinitionName, - isContentPrivate: true, - isContentUnique: true, - descriptionSchema: testDescription.schema.object, - contentSchema: testContent.schema.object - }); - - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000001', - assetDefinitionHash: '0x205ee35b47f713845ea616c805e346cb90e9de82e56069f0de318c59e57d867b', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - private - described - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.deepStrictEqual(assetDefinition.descriptionSchema, testDescription.schema.object); - assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - assert.strictEqual(assetDefinition.name, 'authored - private - described - structured'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - - describe('Asset instances', async () => { - - let assetInstanceID: string; - - it('Checks that an asset instance can be created, within a batch', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetInstanceBatch?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: batchHashIPFSMulti }) - - const result = await request(app) - .post(`/api/v1/assets/${assetDefinitionID}`) - .send({ - author: '0x0000000000000000000000000000000000000001', - description: testDescription.sample.object, - content: testContent.sample.object - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetInstanceID = result.body.assetInstanceID; - - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.deepStrictEqual(assetInstance.description, testDescription.sample.object); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - assert.strictEqual(typeof assetInstance.submitted, 'number'); - assert.strictEqual(typeof assetInstance.batchID, 'string'); - - // Expect the batch to have been submitted - let getBatchResponse: any; - for (let i = 0; i < 10; i++) { - getBatchResponse = await request(app) - .get(`/api/v1/batches/${assetInstance.batchID}`) - .expect(200); - if (getBatchResponse.body.completed) break; - await delay(1); - } - assert.strictEqual(typeof getBatchResponse.body.completed, 'number'); - assert.strictEqual(typeof getBatchResponse.body.batchHash, 'string'); - assert.strictEqual(getBatchResponse.body.receipt, 'my-receipt-id'); - assert.strictEqual(getBatchResponse.body.batchHash, batchHashSha256); - // As this is a private asset, the content must not have been written to IPFS in the batch - assert.strictEqual(getBatchResponse.body.records[0].content, undefined); - // The full description payload should be in the batch data written to IPFS in the batch - assert.deepStrictEqual(getBatchResponse.body.records[0].description, testDescription.sample.object); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - - }); - - it('Checks that the event stream notification for confirming the asset instance creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetInstanceBatchCreated = { - author: '0x0000000000000000000000000000000000000001', - batchHash: batchHashSha256, - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_INSTANCE_BATCH_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.deepStrictEqual(assetInstance.description, testDescription.sample.object); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - assert.strictEqual(assetInstance.timestamp, timestamp); - assert.strictEqual(typeof assetInstance.submitted, 'number'); - assert.strictEqual(assetInstance.receipt, undefined); // the batch has the receipt - assert.strictEqual(assetInstance.blockNumber, 123); - assert.strictEqual(assetInstance.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - }); - - it('sets a property on an asset, which will be public and batched even though the asset is private', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetInstanceBatch?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: batchHashIPFSMulti }) - - const {body: result} = await request(app) - .put(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .send({ - action: 'set-property', - key: 'key', - value: 'value', - author: '0x0000000000000000000000000000000000000001', - }) - .expect(200); - assert.deepStrictEqual(result.status, 'submitted'); - - const {body: asset} = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - const prop = asset.properties['0x0000000000000000000000000000000000000001']['key']; - assert.strictEqual(prop.value, 'value'); - assert(prop.submitted > 0); - const {batchID} = prop; - - // Expect the batch to have been submitted - let getBatchResponse: any; - for (let i = 0; i < 10; i++) { - getBatchResponse = await request(app) - .get(`/api/v1/batches/${batchID}`) - .expect(200); - if (getBatchResponse.body.completed) break; - await delay(1); - } - - assert.strictEqual(typeof getBatchResponse.body.completed, 'number'); - assert.strictEqual(typeof getBatchResponse.body.batchHash, 'string'); - assert.strictEqual(getBatchResponse.body.receipt, 'my-receipt-id'); - assert.strictEqual(getBatchResponse.body.batchHash, batchHashSha256); - // As properties are always public, the full content will have been written to IPFS in the batch - assert.deepStrictEqual(getBatchResponse.body.records[0].recordType, 'property'); - assert.deepStrictEqual(getBatchResponse.body.records[0].key, 'key'); - assert.deepStrictEqual(getBatchResponse.body.records[0].value, 'value'); - - }); - - }); - -}); - -}; diff --git a/kat/src/test/ethereum/assets/authored/private/described-unstructured.ts b/kat/src/test/ethereum/assets/authored/private/described-unstructured.ts deleted file mode 100644 index 2a07f14a42..0000000000 --- a/kat/src/test/ethereum/assets/authored/private/described-unstructured.ts +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../../../common'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IDBAssetDefinition, IEventAssetDefinitionCreated } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; -import { testDescription } from '../../../../samples'; - -export const testAuthoredPrivateDescribedUnstructured = () => { - -describe('Assets: authored - private - described - unstructured', async () => { - - let assetDefinitionID: string; - const assetDefinitionName = 'authored - private - described - unstructured'; - - describe('Create asset definition', () => { - - const timestamp = utils.getTimestamp(); - - it('Checks that the asset definition can be added', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetDefinition?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: 'QmdkH21EiyQXrgo2sPKtSijtvfYBKqQedBxB7W4RJ4m6jo' }); - - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: assetDefinitionName, - author: '0x0000000000000000000000000000000000000001', - isContentPrivate: true, - isContentUnique: true, - descriptionSchema: testDescription.schema.object - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetDefinitionID = result.body.assetDefinitionID; - - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - private - described - unstructured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.strictEqual(assetDefinition.name, 'authored - private - described - unstructured'); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - }); - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmdkH21EiyQXrgo2sPKtSijtvfYBKqQedBxB7W4RJ4m6jo') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: assetDefinitionName, - isContentPrivate: true, - isContentUnique: true, - descriptionSchema: testDescription.schema.object - }); - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000001', - assetDefinitionHash: '0xe4ecb77d78de507f68f5b410e0972cd5c05959ec1de041bb56bde25277786f96', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - private - described - unstructured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.deepStrictEqual(assetDefinition.descriptionSchema, testDescription.schema.object); - assert.strictEqual(assetDefinition.name, 'authored - private - described - unstructured'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - -}); - -}; diff --git a/kat/src/test/ethereum/assets/authored/private/structured.ts b/kat/src/test/ethereum/assets/authored/private/structured.ts deleted file mode 100644 index e9d7682d71..0000000000 --- a/kat/src/test/ethereum/assets/authored/private/structured.ts +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../../../common'; -import { testContent } from '../../../../samples'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IDBAssetDefinition, IDBAssetInstance, IEventAssetDefinitionCreated, IEventAssetInstanceCreated } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; - -export const testAuthoredPrivateStructured = () => { - -describe('Assets: authored - structured', async () => { - - let assetDefinitionID: string; - const assetDefinitionName = 'authored - private - structured'; - const timestamp = utils.getTimestamp(); - - describe('Create asset definition', () => { - - it('Checks that the asset definition can be added', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetDefinition?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: 'Qmf71q7zspRmzvH6yVhkrpWCnK54rvxyj6XSTJ5tgBiZfV' }); - - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: assetDefinitionName, - author: '0x0000000000000000000000000000000000000001', - isContentPrivate: true, - isContentUnique: true, - contentSchema: testContent.schema.object - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetDefinitionID = result.body.assetDefinitionID; - - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - private - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object); - assert.strictEqual(assetDefinition.name, 'authored - private - structured'); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - }); - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - - nock('https://ipfs.kaleido.io') - .get('/ipfs/Qmf71q7zspRmzvH6yVhkrpWCnK54rvxyj6XSTJ5tgBiZfV') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: assetDefinitionName, - isContentPrivate: true, - isContentUnique: true, - contentSchema: testContent.schema.object - }); - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000001', - assetDefinitionHash: '0xf9186d8e20d9e6786aa5e99e8c83be79ef719ddb1482ddcdf3dccf98bf24cd60', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - private - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object); - assert.strictEqual(assetDefinition.name, 'authored - private - structured'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - - describe('Asset instances', async () => { - - let assetInstanceID: string; - - it('Checks that an asset instance can be created', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetInstance?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - const result = await request(app) - .post(`/api/v1/assets/${assetDefinitionID}`) - .send({ - author: '0x0000000000000000000000000000000000000001', - content: testContent.sample.object - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetInstanceID = result.body.assetInstanceID; - - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.contentHash, testContent.sample.docExchangeSha256); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - // assert.strictEqual(assetInstance.receipt, 'my-receipt-id'); - assert.strictEqual(typeof assetInstance.submitted, 'number'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - - }); - - it('Checks that the event stream notification for confirming the asset instance creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetInstanceCreated = { - assetDefinitionID: utils.uuidToHex(assetDefinitionID), - author: '0x0000000000000000000000000000000000000001', - assetInstanceID: utils.uuidToHex(assetInstanceID), - contentHash: testContent.sample.docExchangeSha256, - timestamp: timestamp.toString(), - isContentPrivate: true - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_INSTANCE_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.contentHash, testContent.sample.docExchangeSha256); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - assert.strictEqual(assetInstance.timestamp, timestamp); - assert.strictEqual(typeof assetInstance.submitted, 'number'); - assert.strictEqual(assetInstance.blockNumber, 123); - assert.strictEqual(assetInstance.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/assets/authored/private/unstructured.ts b/kat/src/test/ethereum/assets/authored/private/unstructured.ts deleted file mode 100644 index d0428fc007..0000000000 --- a/kat/src/test/ethereum/assets/authored/private/unstructured.ts +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../../../common'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IEventAssetDefinitionCreated, IDBAssetDefinition } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; - -export const testAuthoredPrivateUnstructured = () => { - -describe('Assets: authored - private - unstructured', async () => { - - let assetDefinitionID: string; - const assetDefinitionName = 'authored - private - unstructured'; - - describe('Create private asset definition', async () => { - - const timestamp = utils.getTimestamp(); - - it('Checks that the asset definition can be added', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetDefinition?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: 'QmZCxXPtG4t9QR5VWWrGsPzc5S7cY3dHmwGSwkobcdavpb' }); - - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: assetDefinitionName, - author: '0x0000000000000000000000000000000000000001', - isContentPrivate: true, - isContentUnique: true, - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetDefinitionID = result.body.assetDefinitionID; - - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - private - unstructured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.strictEqual(assetDefinition.name, 'authored - private - unstructured'); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - }); - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmZCxXPtG4t9QR5VWWrGsPzc5S7cY3dHmwGSwkobcdavpb') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: assetDefinitionName, - isContentPrivate: true, - isContentUnique: true, - }); - - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000001', - assetDefinitionHash: '0xa1780db691781aa3c276e32b24ca552eb08aef5af4671c65426653fda2996804', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - private - unstructured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.strictEqual(assetDefinition.name, 'authored - private - unstructured'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/assets/authored/public/described-structured.ts b/kat/src/test/ethereum/assets/authored/public/described-structured.ts deleted file mode 100644 index b7f3115fc2..0000000000 --- a/kat/src/test/ethereum/assets/authored/public/described-structured.ts +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import assert from 'assert'; -import { createHash, randomBytes } from 'crypto'; -import nock from 'nock'; -import request from 'supertest'; -import { promisify } from 'util'; -import { IDBAssetDefinition, IDBAssetInstance, IEventAssetDefinitionCreated, IEventAssetInstanceBatchCreated } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; -import { app, mockEventStreamWebSocket } from '../../../../common'; -import { testContent, testDescription } from '../../../../samples'; -const delay = promisify(setTimeout); - -export const testAuthoredPublicDescribedStructured = () => { - -describe('Assets: authored - public - described - structured', async () => { - - let assetDefinitionID: string; - const assetDefinitionName = 'authored - public - described - structured'; - const timestamp = utils.getTimestamp(); - const batchHashSha256 = '0x' + createHash('sha256').update(randomBytes(10)).digest().toString('hex'); - const batchHashIPFSMulti = utils.sha256ToIPFSHash(batchHashSha256); - - let batchMaxRecordsToRestore: number; - beforeEach(() => { - nock.cleanAll(); - // Force batches to close immediately - batchMaxRecordsToRestore = utils.constants.BATCH_MAX_RECORDS; - utils.constants.BATCH_MAX_RECORDS = 1; - }); - - afterEach(() => { - assert.deepStrictEqual(nock.pendingMocks(), []); - utils.constants.BATCH_MAX_RECORDS = batchMaxRecordsToRestore; - }); - - describe('Create asset definition', () => { - - it('Checks that the asset definition can be added', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetDefinition?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: 'QmPsTQxwhQjJsCFh3hBijCC4gGReQpEz5VjcCK7gu6sYXX' }) - - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: assetDefinitionName, - author: '0x0000000000000000000000000000000000000001', - isContentPrivate: false, - isContentUnique: true, - descriptionSchema: testDescription.schema.object, - contentSchema: testContent.schema.object - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetDefinitionID = result.body.assetDefinitionID; - - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - public - described - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, false); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.deepStrictEqual(assetDefinition.descriptionSchema, testDescription.schema.object); - assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object); - assert.strictEqual(assetDefinition.name, 'authored - public - described - structured'); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - }); - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmPsTQxwhQjJsCFh3hBijCC4gGReQpEz5VjcCK7gu6sYXX') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: assetDefinitionName, - isContentPrivate: false, - isContentUnique: true, - descriptionSchema: testDescription.schema.object, - contentSchema: testContent.schema.object - }); - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000001', - assetDefinitionHash: '0x16bfeb8bb4befe63cc90578fe6fa0f4ef56955c462cd57965279effc69df1ea6', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - public - described - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, false); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.deepStrictEqual(assetDefinition.descriptionSchema, testDescription.schema.object); - assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object); - assert.strictEqual(assetDefinition.name, 'authored - public - described - structured'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - - describe('Asset instances', async () => { - - let assetInstanceID: string; - - it('Checks that an asset instance can be created', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetInstanceBatch?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: batchHashIPFSMulti }) - - const result = await request(app) - .post(`/api/v1/assets/${assetDefinitionID}`) - .send({ - author: '0x0000000000000000000000000000000000000001', - description: testDescription.sample.object, - content: testContent.sample.object - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetInstanceID = result.body.assetInstanceID; - - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.descriptionHash, '0x' + utils.getSha256(JSON.stringify(testDescription.sample.object))); - assert.deepStrictEqual(assetInstance.description, testDescription.sample.object); - assert.strictEqual(assetInstance.contentHash,'0x' + utils.getSha256(JSON.stringify(testContent.sample.object))); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - assert.strictEqual(assetInstance.receipt, undefined); // As this has been batched - assert.strictEqual(typeof assetInstance.submitted, 'number'); - assert.strictEqual(typeof assetInstance.batchID, 'string'); - - // Expect the batch to have been submitted - let getBatchResponse: any; - for (let i = 0; i < 10; i++) { - getBatchResponse = await request(app) - .get(`/api/v1/batches/${assetInstance.batchID}`) - .expect(200); - if (getBatchResponse.body.completed) break; - await delay(1); - } - assert.strictEqual(typeof getBatchResponse.body.completed, 'number'); - assert.strictEqual(typeof getBatchResponse.body.batchHash, 'string'); - assert.strictEqual(getBatchResponse.body.receipt, 'my-receipt-id'); - assert.strictEqual(getBatchResponse.body.batchHash, batchHashSha256); - // As this is a public asset, the full content will have been written to IPFS in the batch - assert.deepStrictEqual(getBatchResponse.body.records[0].content, testContent.sample.object); - // The full description payload should be in the batch data written to IPFS in the batch - assert.deepStrictEqual(getBatchResponse.body.records[0].description, testDescription.sample.object); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - - }); - - it('Checks that the event stream notification for confirming the asset instance creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetInstanceBatchCreated = { - author: '0x0000000000000000000000000000000000000001', - batchHash: batchHashSha256, - timestamp: timestamp.toString() - }; - - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_INSTANCE_BATCH_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.descriptionHash, '0x' + utils.getSha256(JSON.stringify(testDescription.sample.object))); - assert.deepStrictEqual(assetInstance.description, testDescription.sample.object); - assert.strictEqual(assetInstance.contentHash, '0x' + utils.getSha256(JSON.stringify(testContent.sample.object))); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - assert.strictEqual(assetInstance.receipt, undefined); // the batch has the receipt - assert.strictEqual(typeof assetInstance.timestamp, 'number'); - assert.strictEqual(assetInstance.timestamp, timestamp); - assert.strictEqual(assetInstance.blockNumber, 123); - assert.strictEqual(assetInstance.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/assets/authored/public/described-unstructured.ts b/kat/src/test/ethereum/assets/authored/public/described-unstructured.ts deleted file mode 100644 index 80914c56cf..0000000000 --- a/kat/src/test/ethereum/assets/authored/public/described-unstructured.ts +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../../../common'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IDBAssetDefinition, IEventAssetDefinitionCreated } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; -import { testDescription } from '../../../../samples'; - -export const testAuthoredPublicDescribedUnstructured = () => { - -describe('Asset definitions: authored - public - described - unstructured', async () => { - - let assetDefinitionID: string; - const assetDefinitionName = 'authored - public - described - unstructured'; - - describe('Create asset definition', () => { - - const timestamp = utils.getTimestamp(); - - it('Checks that the asset definition can be added', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetDefinition?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: 'QmedsLGSbtuo3GsNjh2F4u2nDpNyjVSTkYGet9KtG1WCY5' }); - - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: assetDefinitionName, - author: '0x0000000000000000000000000000000000000001', - isContentPrivate: false, - isContentUnique: true, - descriptionSchema: testDescription.schema.object - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetDefinitionID = result.body.assetDefinitionID; - - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - public - described - unstructured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, false); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.deepStrictEqual(assetDefinition.descriptionSchema, testDescription.schema.object); - assert.strictEqual(assetDefinition.name, 'authored - public - described - unstructured'); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - }); - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmedsLGSbtuo3GsNjh2F4u2nDpNyjVSTkYGet9KtG1WCY5') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: assetDefinitionName, - isContentPrivate: false, - isContentUnique: true, - descriptionSchema: testDescription.schema.object - }); - - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000001', - assetDefinitionHash: '0xf22423517fb1783b6b1e913f3915fa3215396000412d3420204b1394ab31e03e', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - public - described - unstructured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, false); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.deepStrictEqual(assetDefinition.descriptionSchema, testDescription.schema.object); - assert.strictEqual(assetDefinition.name, 'authored - public - described - unstructured'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/assets/authored/public/structured.ts b/kat/src/test/ethereum/assets/authored/public/structured.ts deleted file mode 100644 index 5f0005a44b..0000000000 --- a/kat/src/test/ethereum/assets/authored/public/structured.ts +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import assert from 'assert'; -import { createHash, randomBytes } from 'crypto'; -import nock from 'nock'; -import request from 'supertest'; -import { promisify } from 'util'; -import { IDBAssetDefinition, IDBAssetInstance, IEventAssetDefinitionCreated, IEventAssetInstanceBatchCreated } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; -import { app, mockEventStreamWebSocket } from '../../../../common'; -import { testContent } from '../../../../samples'; -const delay = promisify(setTimeout); - -export const testAuthoredPublicStructured = () => { - -describe('Assets: authored - public - structured', async () => { - - let assetDefinitionID: string; - const assetDefinitionName = 'authored - public - structured'; - const timestamp = utils.getTimestamp(); - const batchHashSha256 = '0x' + createHash('sha256').update(randomBytes(10)).digest().toString('hex'); - const batchHashIPFSMulti = utils.sha256ToIPFSHash(batchHashSha256); - - let batchMaxRecordsToRestore: number; - beforeEach(() => { - nock.cleanAll(); - // Force batches to close immediately - batchMaxRecordsToRestore = utils.constants.BATCH_MAX_RECORDS; - utils.constants.BATCH_MAX_RECORDS = 1; - }); - - afterEach(() => { - assert.deepStrictEqual(nock.pendingMocks(), []); - utils.constants.BATCH_MAX_RECORDS = batchMaxRecordsToRestore; - }); - - describe('Create asset definition', () => { - - it('Checks that the asset definition can be added', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetDefinition?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: 'QmV85fRf9jng5zhcSC4Zef2dy8ypouazgckRz4GhA5cUgw' }); - - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: assetDefinitionName, - author: '0x0000000000000000000000000000000000000001', - isContentPrivate: false, - isContentUnique: true, - contentSchema: testContent.schema.object - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetDefinitionID = result.body.assetDefinitionID; - - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - public - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, false); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object); - assert.strictEqual(assetDefinition.name, 'authored - public - structured'); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - }); - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmV85fRf9jng5zhcSC4Zef2dy8ypouazgckRz4GhA5cUgw') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: assetDefinitionName, - isContentPrivate: false, - isContentUnique: true, - contentSchema: testContent.schema.object - }); - - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000001', - assetDefinitionHash: '0x64c97929fb90da1b94d560a29d8522c77b6c662588abb6ad23f1a0377250a2b0', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - public - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, false); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object); - assert.strictEqual(assetDefinition.name, 'authored - public - structured'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - - - describe('Asset instances', async () => { - - let assetInstanceID: string; - - it('Checks that an asset instance can be created', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetInstanceBatch?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: batchHashIPFSMulti }) - - const result = await request(app) - .post(`/api/v1/assets/${assetDefinitionID}`) - .send({ - assetDefinitionID, - author: '0x0000000000000000000000000000000000000001', - content: testContent.sample.object - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetInstanceID = result.body.assetInstanceID; - - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.contentHash,'0x' + utils.getSha256(JSON.stringify(testContent.sample.object))); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - assert.strictEqual(assetInstance.receipt, undefined); // As this has been batched - assert.strictEqual(typeof assetInstance.submitted, 'number'); - assert.strictEqual(typeof assetInstance.batchID, 'string'); - - // Expect the batch to have been submitted - let getBatchResponse: any; - for (let i = 0; i < 10; i++) { - getBatchResponse = await request(app) - .get(`/api/v1/batches/${assetInstance.batchID}`) - .expect(200); - if (getBatchResponse.body.completed) break; - await delay(1); - } - assert.strictEqual(typeof getBatchResponse.body.completed, 'number'); - assert.strictEqual(typeof getBatchResponse.body.batchHash, 'string'); - assert.strictEqual(getBatchResponse.body.receipt, 'my-receipt-id'); - assert.strictEqual(getBatchResponse.body.batchHash, batchHashSha256); - // As this is a public asset, the full content will have been written to IPFS in the batch - assert.deepStrictEqual(getBatchResponse.body.records[0].content, testContent.sample.object); - // There is no description, as this is not a described asset type - assert.deepStrictEqual(getBatchResponse.body.records[0].description, undefined); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - - }); - - it('Checks that the event stream notification for confirming the asset instance creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetInstanceBatchCreated = { - author: '0x0000000000000000000000000000000000000001', - batchHash: batchHashSha256, - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_INSTANCE_BATCH_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.contentHash, '0x' + utils.getSha256(JSON.stringify(testContent.sample.object))); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - assert.strictEqual(assetInstance.receipt, undefined); // the batch has the receipt - assert.strictEqual(assetInstance.timestamp, timestamp); - assert.strictEqual(typeof assetInstance.submitted, 'number'); - assert.strictEqual(assetInstance.blockNumber, 123); - assert.strictEqual(assetInstance.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - }); - - }); - -}); - -}; diff --git a/kat/src/test/ethereum/assets/authored/public/unstructured.ts b/kat/src/test/ethereum/assets/authored/public/unstructured.ts deleted file mode 100644 index b9b3c9be41..0000000000 --- a/kat/src/test/ethereum/assets/authored/public/unstructured.ts +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../../../common'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IEventAssetDefinitionCreated, IDBAssetDefinition } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; - -export const testAuthoredPublicUnstructured = () => { - -describe('Assets: authored - unstructured', async () => { - - let assetDefinitionID: string; - const assetDefinitionName = 'authored - public - unstructured'; - - describe('Create asset definition', async () => { - - const timestamp = utils.getTimestamp(); - - it('Checks that the asset definition can be added', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createAssetDefinition?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: 'QmW9kyL5Dd1NxZGGMPYHYydjNp7bwchjMReMsYsrZyZMNr' }); - - const result = await request(app) - .post('/api/v1/assets/definitions') - .send({ - name: assetDefinitionName, - author: '0x0000000000000000000000000000000000000001', - isContentPrivate: false, - isContentUnique: true, - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - assetDefinitionID = result.body.assetDefinitionID; - - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - public - unstructured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, false); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.strictEqual(assetDefinition.name, 'authored - public - unstructured'); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - }); - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmW9kyL5Dd1NxZGGMPYHYydjNp7bwchjMReMsYsrZyZMNr') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: assetDefinitionName, - isContentPrivate: false, - isContentUnique: true - }); - - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000001', - assetDefinitionHash: '0x741330003d1780fb3aec3c569011c4c7d133a99b95a276f45c73b1a30395ea83', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - public - unstructured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(assetDefinition.isContentPrivate, false); - assert.strictEqual(assetDefinition.isContentUnique, true); - assert.strictEqual(assetDefinition.name, 'authored - public - unstructured'); - assert.strictEqual(typeof assetDefinition.submitted, 'number'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - -}); -}; \ No newline at end of file diff --git a/kat/src/test/ethereum/assets/index.ts b/kat/src/test/ethereum/assets/index.ts deleted file mode 100644 index 0eb9af1e68..0000000000 --- a/kat/src/test/ethereum/assets/index.ts +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { testAssetArgumentValidation } from "./argument-validation"; -import { testAuthoredPrivateDescribedStructured } from "./authored/private/described-structured"; -import { testAuthoredPrivateDescribedUnstructured } from "./authored/private/described-unstructured"; -import { testAuthoredPrivateStructured } from "./authored/private/structured"; -import { testAuthoredPrivateUnstructured } from "./authored/private/unstructured"; -import { testAuthoredPublicDescribedStructured } from "./authored/public/described-structured"; -import { testAuthoredPublicDescribedUnstructured } from "./authored/public/described-unstructured"; -import { testAuthoredPublicStructured } from "./authored/public/structured"; -import { testAuthoredPublicUnstructured } from "./authored/public/unstructured"; -import { testUnauthoredPrivateDescribedStructured } from "./unauthored/private/described-structured"; -import { testUnauthoredPrivateDescribedUnstructured } from "./unauthored/private/described-unstructured"; -import { testUnauthoredPrivateStructured } from "./unauthored/private/structured"; -import { testUnauthoredPrivateUnstructured } from "./unauthored/private/unstructured"; -import { testUnauthoredPublicDescribedStructured } from "./unauthored/public/described-structured"; -import { testUnauthoredPublicDescribedUnstructured } from "./unauthored/public/described-unstructured"; -import { testUnauthoredPublicStructured } from "./unauthored/public/structured"; -import { testUnauthoredPublicUnstructured } from "./unauthored/public/unstructured"; - -export const testAssets = async () => { - describe('Asset tests', async () => { - testAssetArgumentValidation(); - testAuthoredPrivateDescribedStructured(); - testAuthoredPrivateDescribedUnstructured(); - testAuthoredPrivateStructured(); - testAuthoredPrivateUnstructured(); - testAuthoredPublicDescribedStructured(); - testAuthoredPublicDescribedUnstructured(); - testAuthoredPublicStructured(); - testAuthoredPublicUnstructured(); - testUnauthoredPrivateDescribedStructured(); - testUnauthoredPrivateDescribedUnstructured(); - testUnauthoredPrivateStructured(); - testUnauthoredPrivateUnstructured(); - testUnauthoredPublicDescribedStructured(); - testUnauthoredPublicDescribedUnstructured(); - testUnauthoredPublicStructured(); - testUnauthoredPublicUnstructured(); - }); -}; \ No newline at end of file diff --git a/kat/src/test/ethereum/assets/unauthored/private/described-structured.ts b/kat/src/test/ethereum/assets/unauthored/private/described-structured.ts deleted file mode 100644 index ec64e305a5..0000000000 --- a/kat/src/test/ethereum/assets/unauthored/private/described-structured.ts +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import assert from 'assert'; -import { createHash, randomBytes } from 'crypto'; -import nock from 'nock'; -import request from 'supertest'; -import { v4 as uuidV4 } from 'uuid'; -import { IDBAssetDefinition, IDBAssetInstance, IDBBatch, IEventAssetDefinitionCreated, IEventAssetInstanceBatchCreated, BatchRecordType } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; -import { app, mockEventStreamWebSocket } from '../../../../common'; -import { testContent, testDescription } from '../../../../samples'; - -export const testUnauthoredPrivateDescribedStructured = () => { - -describe('Assets: unauthored - private - described - structured', async () => { - - const assetDefinitionID = '9ac02d4e-e0a3-4e9e-9d97-be0a41595425'; - const timestamp = utils.getTimestamp(); - - let batchMaxRecordsToRestore: number; - beforeEach(() => { - nock.cleanAll(); - // Force batches to close immediately - batchMaxRecordsToRestore = utils.constants.BATCH_MAX_RECORDS; - utils.constants.BATCH_MAX_RECORDS = 1; - }); - - afterEach(() => { - assert.deepStrictEqual(nock.pendingMocks(), []); - utils.constants.BATCH_MAX_RECORDS = batchMaxRecordsToRestore; - }); - - describe('Asset definition', async () => { - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmbGq3hw6r5C3yUkGvqJHq7c67pyMHXxQJ6XBHUh9kf5Ex') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: 'unauthored - private - described - structured', - isContentPrivate: true, - isContentUnique: true, - descriptionSchema: testDescription.schema.object, - contentSchema: testContent.schema.object - }); - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000002', - assetDefinitionHash: '0xc02d4bc2c162538e1ca45d20c472b608520d99d6d3988383251d626b8a3411d9', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'unauthored - private - described - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000002'); - assert.deepStrictEqual(assetDefinition.descriptionSchema, testDescription.schema.object); - assert.deepStrictEqual(assetDefinition.contentSchema,testContent.schema.object); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.name, 'unauthored - private - described - structured'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.submitted, undefined); - assert.strictEqual(assetDefinition.receipt, undefined); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - - describe('Asset instances', async () => { - - const assetInstanceID = 'e07f4682-71d1-4a76-8084-8adbc97ef99c'; - const batchHashSha256 = '0x' + createHash('sha256').update(randomBytes(10)).digest().toString('hex'); - const batchHashIPFSMulti = utils.sha256ToIPFSHash(batchHashSha256); - - it('Checks that the event stream notification for confirming the asset instance creation is handled', async () => { - - const testBatch: IDBBatch = { - author: '0x0000000000000000000000000000000000000002', - batchID: uuidV4(), - completed: Date.now() - 100, - created: Date.now() - 200, - type: 'asset-instances', - records: [{ - recordType: BatchRecordType.assetInstance, - assetDefinitionID, - assetInstanceID, - author: '0x0000000000000000000000000000000000000002', - description: testDescription.sample.object, - descriptionHash: '0x' + utils.getSha256(JSON.stringify(testDescription.sample.object)), - contentHash: '0x' + utils.getSha256(JSON.stringify(testContent.sample.object)), - isContentPrivate: true - }], - }; - - nock('https://ipfs.kaleido.io') - .get(`/ipfs/${batchHashIPFSMulti}`) - .reply(200, testBatch) - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetInstanceBatchCreated = { - batchHash: batchHashSha256, - author: '0x0000000000000000000000000000000000000002', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_INSTANCE_BATCH_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.descriptionHash, '0x' + utils.getSha256(JSON.stringify(testDescription.sample.object))); - assert.deepStrictEqual(assetInstance.description, testDescription.sample.object); - assert.strictEqual(assetInstance.contentHash, '0x' + utils.getSha256(JSON.stringify(testContent.sample.object))); - assert.deepStrictEqual(assetInstance.content, undefined); - assert.strictEqual(assetInstance.submitted, undefined); - assert.strictEqual(assetInstance.receipt, undefined); - assert.strictEqual(assetInstance.timestamp, timestamp); - assert.strictEqual(assetInstance.blockNumber, 123); - assert.strictEqual(assetInstance.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/assets/unauthored/private/described-unstructured.ts b/kat/src/test/ethereum/assets/unauthored/private/described-unstructured.ts deleted file mode 100644 index 09b3af1c64..0000000000 --- a/kat/src/test/ethereum/assets/unauthored/private/described-unstructured.ts +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../../../common'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IEventAssetDefinitionCreated, IDBAssetDefinition } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; -import { testDescription } from '../../../../samples'; - -export const testUnauthoredPrivateDescribedUnstructured = () => { - -describe('Assets: unauthored - private - described - unstructured', async () => { - - const assetDefinitionID = '0989dfe5-4b4c-43e0-91fc-3fea194a7c56'; - - describe('Asset definition', async () => { - - const timestamp = utils.getTimestamp(); - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmbUq3WLWyrXcEtBH8LTpiq3Usg5mkWb4kAGPigg4a7YKU') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: 'unauthored - private - described - unstructured', - isContentPrivate: true, - isContentUnique: true, - descriptionSchema: testDescription.schema.object, - }); - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000002', - assetDefinitionHash: '0xc34043022814b07d606980cbd6d605952943faddadac9f32419ee33c2bdf0eab', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'unauthored - private - described - unstructured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000002'); - assert.deepStrictEqual(assetDefinition.descriptionSchema, testDescription.schema.object); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.name, 'unauthored - private - described - unstructured'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.submitted, undefined); - assert.strictEqual(assetDefinition.receipt, undefined); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/assets/unauthored/private/structured.ts b/kat/src/test/ethereum/assets/unauthored/private/structured.ts deleted file mode 100644 index 3d9e2d845b..0000000000 --- a/kat/src/test/ethereum/assets/unauthored/private/structured.ts +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../../../common'; -import { testContent } from '../../../../samples'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IEventAssetDefinitionCreated, IDBAssetDefinition, IEventAssetInstanceCreated, IDBAssetInstance } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; - -export const testUnauthoredPrivateStructured = () => { - -describe('Assets: unauthored - private - structured', async () => { - - const assetDefinitionID = '02d7cbbf-aa9e-4724-a645-86edf4572ff3'; - const timestamp = utils.getTimestamp(); - - describe('Asset definition', async () => { - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmUsjZyav8UhEvK41EGCgntbfGJT3fQx5KRzFw8uCFhqTe') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: 'unauthored - private - structured', - isContentPrivate: true, - isContentUnique: true, - contentSchema: testContent.schema.object, - }); - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000002', - assetDefinitionHash: '0x611c9f2515ec393c0fd9cacaf51caff2a4462b6d0571b2b5600dc7ea961b8c49', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'unauthored - private - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000002'); - assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.name, 'unauthored - private - structured'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.submitted, undefined); - assert.strictEqual(assetDefinition.receipt, undefined); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - - describe('Asset instances', async () => { - - const assetInstanceID = '9d53cce2-0879-4aaa-9b82-cb30eb6331be'; - - it('Checks that the event stream notification for confirming the asset instance creation is handled', async () => { - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetInstanceCreated = { - assetDefinitionID: utils.uuidToHex(assetDefinitionID), - author: '0x0000000000000000000000000000000000000002', - assetInstanceID: utils.uuidToHex(assetInstanceID), - contentHash: testContent.sample.docExchangeSha256, - timestamp: timestamp.toString(), - isContentPrivate: true - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.DESCRIBED_ASSET_INSTANCE_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.contentHash, testContent.sample.docExchangeSha256); - assert.deepStrictEqual(assetInstance.content, undefined); - assert.strictEqual(assetInstance.receipt, undefined); - assert.strictEqual(assetInstance.submitted, undefined); - assert.strictEqual(assetInstance.timestamp, timestamp); - assert.strictEqual(assetInstance.blockNumber, 123); - assert.strictEqual(assetInstance.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/assets/unauthored/private/unstructured.ts b/kat/src/test/ethereum/assets/unauthored/private/unstructured.ts deleted file mode 100644 index f1d7bd72d7..0000000000 --- a/kat/src/test/ethereum/assets/unauthored/private/unstructured.ts +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../../../common'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IEventAssetDefinitionCreated, IDBAssetDefinition } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; - -export const testUnauthoredPrivateUnstructured = () => { - -describe('Asset definitions: unauthored - unstructured', async () => { - - const assetDefinitionID = '2a624ed6-7d71-4b44-94a8-faea64537036'; - - describe('Asset definition', async () => { - - const timestamp = utils.getTimestamp(); - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmVB7euGyrkSZPTaoBEZB4rou3A7Za48GNKidL1hSK2bsA') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: 'unauthored - private - unstructured', - isContentPrivate: true, - isContentUnique: true - }); - - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000002', - assetDefinitionHash: '0x65907788050862e3317097ac1b1b7dc6cd9c7b35ea11dcccbcef727aae01450d', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'unauthored - private - unstructured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(assetDefinition.isContentPrivate, true); - assert.strictEqual(assetDefinition.name, 'unauthored - private - unstructured'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.submitted, undefined); - assert.strictEqual(assetDefinition.receipt, undefined); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - -}); - -}; diff --git a/kat/src/test/ethereum/assets/unauthored/public/described-structured.ts b/kat/src/test/ethereum/assets/unauthored/public/described-structured.ts deleted file mode 100644 index c197b676fd..0000000000 --- a/kat/src/test/ethereum/assets/unauthored/public/described-structured.ts +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../../../common'; -import { testDescription, testContent } from '../../../../samples'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IEventAssetDefinitionCreated, IDBAssetDefinition, IEventAssetInstanceCreated, IDBAssetInstance } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; - -export const testUnauthoredPublicDescribedStructured = () => { - -describe('Assets: unauthored - public - described - structured', async () => { - - const assetDefinitionID = 'cb289f68-5eaf-46d2-9be1-3dcfdde76885'; - const timestamp = utils.getTimestamp(); - - describe('Asset definition', async () => { - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - nock('https://ipfs.kaleido.io') - .get('/ipfs/Qma49mzceUqCmZrBsFAzC26XnwT1gVzhTBkby2JZsYiaUF') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: 'unauthored - public - described - structured', - isContentPrivate: false, - isContentUnique: true, - descriptionSchema: testDescription.schema.object, - contentSchema: testContent.schema.object - }); - - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000002', - assetDefinitionHash: '0xae123c4d3b9e77716be55ea8ad616b74ac67c455951698f4e40f22e1ed7981e8', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'unauthored - public - described - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(assetDefinition.isContentPrivate, false); - assert.deepStrictEqual(assetDefinition.descriptionSchema, testDescription.schema.object); - assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object); - assert.strictEqual(assetDefinition.name, 'unauthored - public - described - structured'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.submitted, undefined); - assert.strictEqual(assetDefinition.receipt, undefined); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - - describe('Asset instances', async () => { - - const assetInstanceID = '9e8acd3b-4067-443f-ad6e-739976bc63ee'; - - it('Checks that the event stream notification for confirming the asset instance creation is handled', async () => { - - nock('https://ipfs.kaleido.io') - .get(`/ipfs/${testDescription.sample.ipfsMultiHash}`) - .reply(200, testDescription.sample.object) - .get(`/ipfs/${testContent.sample.ipfsMultiHash}`) - .reply(200, testContent.sample.object) - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetInstanceCreated = { - assetDefinitionID: utils.uuidToHex(assetDefinitionID), - author: '0x0000000000000000000000000000000000000002', - assetInstanceID: utils.uuidToHex(assetInstanceID), - descriptionHash: testDescription.sample.ipfsSha256, - contentHash: testContent.sample.ipfsSha256, - timestamp: timestamp.toString(), - isContentPrivate: false - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.DESCRIBED_ASSET_INSTANCE_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.descriptionHash, testDescription.sample.ipfsSha256); - assert.deepStrictEqual(assetInstance.description, testDescription.sample.object); - assert.strictEqual(assetInstance.contentHash, testContent.sample.ipfsSha256); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - assert.strictEqual(assetInstance.submitted, undefined); - assert.strictEqual(assetInstance.receipt, undefined); - assert.strictEqual(assetInstance.timestamp, timestamp); - assert.strictEqual(assetInstance.blockNumber, 123); - assert.strictEqual(assetInstance.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/assets/unauthored/public/described-unstructured.ts b/kat/src/test/ethereum/assets/unauthored/public/described-unstructured.ts deleted file mode 100644 index 974aacd255..0000000000 --- a/kat/src/test/ethereum/assets/unauthored/public/described-unstructured.ts +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../../../common'; -import { testDescription } from '../../../../samples'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IEventAssetDefinitionCreated, IDBAssetDefinition } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; - -export const testUnauthoredPublicDescribedUnstructured = () => { - describe('Assets: unauthored - public - described - unstructured', async () => { - - const assetDefinitionID = 'f832ea06-71e4-43e3-b0fb-61cb8f9a9631'; - - describe('Asset definition', async () => { - - const timestamp = utils.getTimestamp(); - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmXNQHuaQ9odf4dw7CrvZuQXQ8iyizwaWHV4pUZorQKFrS') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: 'unauthored - public - described - unstructured', - isContentPrivate: false, - isContentUnique: true, - descriptionSchema: testDescription.schema.object - }); - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000002', - assetDefinitionHash: '0x862c0ad6e169fc23a45c7c9d4b09ba9ce22344a5b4242843a3549c4ea0d8668b', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'unauthored - public - described - unstructured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(assetDefinition.isContentPrivate, false); - assert.deepStrictEqual(assetDefinition.descriptionSchema, testDescription.schema.object); - assert.strictEqual(assetDefinition.name, 'unauthored - public - described - unstructured'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.submitted, undefined); - assert.strictEqual(assetDefinition.receipt, undefined); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/assets/unauthored/public/structured.ts b/kat/src/test/ethereum/assets/unauthored/public/structured.ts deleted file mode 100644 index 6ece10b508..0000000000 --- a/kat/src/test/ethereum/assets/unauthored/public/structured.ts +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../../../common'; -import { testContent } from '../../../../samples'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IEventAssetDefinitionCreated, IDBAssetDefinition, IEventAssetInstanceCreated, IDBAssetInstance } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; - -export const testUnauthoredPublicStructured = () => { - -describe('Assets: unauthored - public - structured', async () => { - - const assetDefinitionID = 'f5847e19-8632-44fb-a742-17b7a1fd8bc5'; - const timestamp = utils.getTimestamp(); - - describe('Asset definition', async () => { - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - - nock('https://ipfs.kaleido.io') - .get('/ipfs/QmdptNuREBKs2ruCrfb7EwUJcEXj5oEpmQ5C4MSKht6SmY') - .reply(200,{ - assetDefinitionID: assetDefinitionID, - name: 'unauthored - public - structured', - isContentPrivate: false, - isContentUnique: true, - contentSchema: testContent.schema.object - }); - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000002', - assetDefinitionHash: '0xe61b05a5914b8b0361d2ae2fa91ac0b76de09a517ef411df049b4af3844b4593', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'unauthored - public - structured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(assetDefinition.isContentPrivate, false); - assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object); - assert.strictEqual(assetDefinition.name, 'unauthored - public - structured'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.submitted, undefined); - assert.strictEqual(assetDefinition.receipt, undefined); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - - describe('Asset instances', async () => { - - const assetInstanceID = '28bc0765-0261-415d-95cf-ea285c91a09c'; - - it('Checks that the event stream notification for confirming the asset instance creation is handled', async () => { - - nock('https://ipfs.kaleido.io') - .get(`/ipfs/${testContent.sample.ipfsMultiHash}`) - .reply(200, testContent.sample.object) - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventAssetInstanceCreated = { - assetDefinitionID: utils.uuidToHex(assetDefinitionID), - author: '0x0000000000000000000000000000000000000002', - assetInstanceID: utils.uuidToHex(assetInstanceID), - contentHash: testContent.sample.ipfsSha256, - timestamp: timestamp.toString(), - isContentPrivate: false - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.DESCRIBED_ASSET_INSTANCE_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}`) - .expect(200); - const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID); - assert.strictEqual(assetInstance.author, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetInstance.contentHash, testContent.sample.ipfsSha256); - assert.deepStrictEqual(assetInstance.content, testContent.sample.object); - assert.strictEqual(assetInstance.submitted, undefined); - assert.strictEqual(assetInstance.receipt, undefined); - assert.strictEqual(assetInstance.timestamp, timestamp); - assert.strictEqual(assetInstance.blockNumber, 123); - assert.strictEqual(assetInstance.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`) - .expect(200); - assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/assets/unauthored/public/unstructured.ts b/kat/src/test/ethereum/assets/unauthored/public/unstructured.ts deleted file mode 100644 index 23d43ca6c1..0000000000 --- a/kat/src/test/ethereum/assets/unauthored/public/unstructured.ts +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../../../common'; -import request from 'supertest'; -import assert from 'assert'; -import nock from 'nock' -import { IEventAssetDefinitionCreated, IDBAssetDefinition } from '../../../../../lib/interfaces'; -import * as utils from '../../../../../lib/utils'; - -export const testUnauthoredPublicUnstructured = () => { - -describe('Assets: unauthored - public - unstructured', async () => { - - const assetDefinitionID = 'c4ecf059-67be-4e61-900f-352876604a7f'; - - describe('Asset definition', async () => { - - const timestamp = utils.getTimestamp(); - - it('Checks that the event stream notification for confirming the asset definition creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - - nock('https://ipfs.kaleido.io') - .get('/ipfs/Qmc6W97aTfV8QuBMkYYygRBakJZ93ZjadtGPNi3KbYALTh') - .reply(200, { - assetDefinitionID: assetDefinitionID, - name: 'unauthored - public - unstructured', - isContentPrivate: false, - isContentUnique: true - }); - - const data: IEventAssetDefinitionCreated = { - author: '0x0000000000000000000000000000000000000002', - assetDefinitionHash: '0xcc63cbfd00dc7c62c1265a42074afb19531e67b10f85b7f5170b836655a10fd0', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.ASSET_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the asset definition is confirmed', async () => { - const getAssetDefinitionsResponse = await request(app) - .get('/api/v1/assets/definitions') - .expect(200); - const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'unauthored - public - unstructured'); - assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID); - assert.strictEqual(assetDefinition.author, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(assetDefinition.isContentPrivate, false); - assert.strictEqual(assetDefinition.name, 'unauthored - public - unstructured'); - assert.strictEqual(assetDefinition.timestamp, timestamp); - assert.strictEqual(assetDefinition.submitted, undefined); - assert.strictEqual(assetDefinition.receipt, undefined); - assert.strictEqual(assetDefinition.blockNumber, 123); - assert.strictEqual(assetDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetDefinitionResponse = await request(app) - .get(`/api/v1/assets/definitions/${assetDefinitionID}`) - .expect(200); - assert.deepStrictEqual(assetDefinition, getAssetDefinitionResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/clients/app2app-test.ts b/kat/src/test/ethereum/clients/app2app-test.ts deleted file mode 100644 index c41548fc4b..0000000000 --- a/kat/src/test/ethereum/clients/app2app-test.ts +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import * as sinon from "sinon"; -import io from 'socket.io-client'; -import { StubbedInstance, stubInterface } from "ts-sinon"; -import * as app2app from '../../../clients/app2app'; - -export const testApp2App = async () => { - -describe('App2App', () => { - - let mocksSocketIo: StubbedInstance; - let callbacks: {[f: string]: Function}; - - before(() => { - callbacks = {}; - mocksSocketIo = stubInterface(); - mocksSocketIo.on.callsFake((event, fn) => { - callbacks[event] = fn; - return mocksSocketIo; - }); - sinon.stub(io, 'connect').returns(mocksSocketIo); - }); - - after(() => { - (io.connect as sinon.SinonStub).restore(); - }) - - beforeEach(() => { - callbacks = {}; - app2app.reset(); - }); - - describe('establishSocketIOConnection', () => { - - it('subscribes after connect', async () => { - sinon.assert.notCalled(mocksSocketIo.emit); - callbacks['connect'](); - sinon.assert.calledWith(mocksSocketIo.emit, 'subscribe'); - }); - - it('logs connect_error', async () => { - callbacks['connect_error'](new Error('pop')); - }); - - it('logs error', async () => { - callbacks['error'](new Error('pop')); - }); - - it('logs exception', async () => { - callbacks['exception'](new Error('pop'), {batch: 'test'}); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/clients/index.ts b/kat/src/test/ethereum/clients/index.ts deleted file mode 100644 index c350268845..0000000000 --- a/kat/src/test/ethereum/clients/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { testApp2App } from "./app2app-test"; - -export const testClients = async () => { - describe('Client tests', async () => { - testApp2App(); - }); -}; \ No newline at end of file diff --git a/kat/src/test/ethereum/index.ts b/kat/src/test/ethereum/index.ts deleted file mode 100644 index dc4fd2262d..0000000000 --- a/kat/src/test/ethereum/index.ts +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { testLibraryFunctions } from './lib'; -import { testMembers } from './members'; -import { testPayments } from './payments'; -import { testAssets } from './assets'; -import { testClients } from './clients'; -export const ethereumTests = async () => { -// test Assets -testAssets(); - -testLibraryFunctions(); - -testMembers(); - -testPayments(); - -testClients(); - -}; diff --git a/kat/src/test/ethereum/lib/batch-manager-test.ts b/kat/src/test/ethereum/lib/batch-manager-test.ts deleted file mode 100644 index a6f76d4658..0000000000 --- a/kat/src/test/ethereum/lib/batch-manager-test.ts +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import assert from 'assert'; -import sinon, { SinonStub } from 'sinon'; -import * as database from '../../../clients/database'; -import { BatchManager } from '../../../lib/batch-manager'; -import { BatchProcessor } from '../../../lib/batch-processor'; - -export const testBatchManager = async () => { - -describe('BatchManager', () => { - - let batchRetriever: SinonStub; - let processorInit: SinonStub; - - beforeEach(() => { - batchRetriever = sinon.stub(database, 'retrieveBatches'); - processorInit = sinon.stub(BatchProcessor.prototype, 'init'); - }); - - afterEach(() => { - batchRetriever.restore(); - processorInit.restore(); - }) - - it('inits all the right processors', async () => { - - batchRetriever.resolves([ - { - type: 't1', - author: 'author1', - batchID: 'author1-batch1', - }, - { - type: 't1', - author: 'author2', - batchID: 'author2-batch1', - }, - { - type: 't1', - author: 'author3', - batchID: 'author3-batch1', - }, - { - type: 't1', - author: 'author2', - batchID: 'author2-batch2', - }, - { - type: 't1', - author: 'author1', - batchID: 'author1-batch2', - }, - ]); - - const bm = new BatchManager('t1', sinon.stub()); - await bm.init(); - - sinon.assert.calledWith(processorInit, [ - { - type: 't1', - author: 'author1', - batchID: 'author1-batch1', - }, - { - type: 't1', - author: 'author1', - batchID: 'author1-batch2', - } - ]); - - sinon.assert.calledWith(processorInit, [ - { - type: 't1', - author: 'author2', - batchID: 'author2-batch1', - }, - { - type: 't1', - author: 'author2', - batchID: 'author2-batch2', - } - ]); - - sinon.assert.calledWith(processorInit, [ - { - type: 't1', - author: 'author3', - batchID: 'author3-batch1', - } - ]); - }); - - it('caches batch processors', async () => { - - class TestBatchManagerWrapper extends BatchManager { - public processorCompleteCallback(author: string) { - return super.processorCompleteCallback(author); - } - } - - const bm = new TestBatchManagerWrapper('t1', sinon.stub()); - const bp1 = bm.getProcessor('author1'); - - // Check it caches - assert(bp1 === bm.getProcessor('author1')); - - // Check it doesn't clear the wrong entry - bm.processorCompleteCallback('author2'); - assert(bp1 === bm.getProcessor('author1')); - - // Check it clears the right entry - bm.processorCompleteCallback('author1'); - assert(bp1 !== bm.getProcessor('author1')); - - }) - -}); -}; diff --git a/kat/src/test/ethereum/lib/batch-processor-test.ts b/kat/src/test/ethereum/lib/batch-processor-test.ts deleted file mode 100644 index 24358d0191..0000000000 --- a/kat/src/test/ethereum/lib/batch-processor-test.ts +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import assert from 'assert'; -import sinon, { SinonStub } from 'sinon'; -import { promisify } from 'util'; -import * as database from '../../../clients/database'; -import { BatchProcessor } from '../../../lib/batch-processor'; -import { IDBBatch, BatchRecordType } from '../../../lib/interfaces'; - -const delay = promisify(setTimeout); - -export const testBatchProcessor = async () => { - -describe('BatchProcessor', () => { - - beforeEach(() => { - sinon.stub(database, 'retrieveBatches'); - sinon.stub(database, 'upsertBatch'); - }); - - afterEach(() => { - (database.retrieveBatches as SinonStub).restore(); - (database.upsertBatch as SinonStub).restore(); - }) - - it('fills a batch full in parallel and dispatches it, then cleans up', async () => { - - const processBatchCallback = sinon.stub(); - const processorCompleteCallback = sinon.stub(); - const p = new BatchProcessor( - 'author1', - 'type1', - processBatchCallback, - processorCompleteCallback, - ); - - const scheduleRandomDelayedAdd = async (i: number) => { - // Introduce some randomness, but with very short delays to keep the test fast - await delay(Math.ceil(Math.random() * 5)); - // Half and half records vs. properties - if (i % 2 === 0) { - await p.add({ - recordType: BatchRecordType.assetInstance, - id: `test_${i}`, - }); - } else { - await p.add({ - recordType: BatchRecordType.assetProperty, - key: `test_${i}`, - value: `value_${i}`, - }); - } - } - - const promises: Promise[] = []; - for (let i = 0; i < p.config.batchMaxRecords; i++) { - promises.push(scheduleRandomDelayedAdd(i)); - } - await Promise.all(promises); - - assert.strictEqual(processBatchCallback.callCount, 1); - assert.strictEqual(processorCompleteCallback.callCount, 1); - const batch: IDBBatch = processBatchCallback.getCall(0).args[0]; - for (let i = 0; i < p.config.batchMaxRecords; i++) { - // Half and half records vs. properties - if (i % 2 === 0) { - assert(batch.records.find(r => r.id === `test_${i}`)); - } else { - assert(batch.records.find(r => r.key === `test_${i}`)); - assert(batch.records.find(r => r.value === `value_${i}`)); - } - } - - }); - - it('takes a batch array on input simulating recovery, and dispatches immediately', async () => { - - const processBatchCallback = sinon.stub(); - const processorCompleteCallback = sinon.stub(); - const p = new BatchProcessor( - 'author1', - 'type1', - processBatchCallback, - processorCompleteCallback, - ); - - let batch: IDBBatch = { - author: 'author1', - type: 'type1', - batchID: 'batch1', - completed: null, - created: Date.now(), - records: [], - }; - for (let i = 0; i < p.config.batchMaxRecords-1; i++) { - assert(batch.records.push({id: `test_${i}`, recordType: BatchRecordType.assetInstance })); - } - await p.init([batch]); - - assert.strictEqual(processBatchCallback.callCount, 1); - assert.strictEqual(processorCompleteCallback.callCount, 1); - batch = processBatchCallback.getCall(0).args[0]; - for (let i = 0; i < p.config.batchMaxRecords-1; i++) { - assert(batch.records.find(r => r.id === `test_${i}`)); - } - - }); - - it('times out a batch with arrival, then cleans up once it dispatches', async () => { - - const processBatchCallback = sinon.stub(); - const processorCompleteCallback = sinon.stub(); - const p = new BatchProcessor( - 'author1', - 'type1', - processBatchCallback, - processorCompleteCallback, - { - batchTimeoutArrivallMS: 10, - } - ); - - const scheduleRandomDelayedAdd = async (i: number) => { - // Introduce some randomness, but with very short delays to keep the test fast - await delay(Math.ceil(Math.random() * 5)); - await p.add({ - recordType: BatchRecordType.assetInstance, - id: `test_${i}`, - }); - } - - const before = Date.now(); - const promises: Promise[] = []; - for (let i = 0; i < (p.config.batchMaxRecords - 1); i++) { - promises.push(scheduleRandomDelayedAdd(i)); - } - await Promise.all(promises); - - // Should not be set yet - wait for timeout - assert.strictEqual(processBatchCallback.callCount, 0); - assert.strictEqual(processorCompleteCallback.callCount, 0); - - for (let i = 0; i < 100; i++) { - if (processBatchCallback.callCount === 0) await delay(1); - } - const after = Date.now(); - - assert(after - before >= 10 /* we must have waited this long */) - assert.strictEqual(processBatchCallback.callCount, 1); - assert.strictEqual(processorCompleteCallback.callCount, 1); - - const batch: IDBBatch = processBatchCallback.getCall(0).args[0]; - for (let i = 0; i < (p.config.batchMaxRecords - 1); i++) { - assert(batch.records.find(r => r.id === `test_${i}`)); - } - - }); - - it('times out a batch with an overall timeout, then continues to add to the next batch', async () => { - - let totalReceived = 0; - let batchCount = 0; - const processorCompleteCallback = sinon.stub(); - const p = new BatchProcessor( - 'author1', - 'type1', - async b => {totalReceived += b.records.length; batchCount++}, - processorCompleteCallback, - { - batchTimeoutArrivallMS: 10, - batchTimeoutOverallMS: 20, - } - ); - - for (let i = 0; i < 50; i++) { - await delay(1); - await p.add({ - recordType: BatchRecordType.assetInstance, - id: `test_${i}`, - }); - } - - while (totalReceived < 50) await delay(5); - - assert(batchCount > 1); - assert(processorCompleteCallback.callCount >= 1); - - }); - - it('fills a batch with a slow persistence to the DB', async () => { - - const processBatchCallback = sinon.stub(); - const processorCompleteCallback = sinon.stub(); - const p = new BatchProcessor( - 'author1', - 'type1', - processBatchCallback, - processorCompleteCallback, - { - batchMaxRecords: 10, - } - ); - - // Make the persistence slow - const dbUpdateStub = (database.upsertBatch as SinonStub); - dbUpdateStub.callsFake(() => delay(10)) - - // Make the adding fast - const addImmediate = async (i: number) => { - await p.add({ - recordType: BatchRecordType.assetInstance, - id: `test_${i}`, - }); - } - const promises: Promise[] = []; - for (let i = 0; i < p.config.batchMaxRecords; i++) { - promises.push(addImmediate(i)); - } - await Promise.all(promises); - - for (let i = 0; i < 100; i++) { - if (processorCompleteCallback.callCount === 0) await delay(1); - } - - // We should have exactly three calls - // - once for the first as the batch started - // - once with everything else in the batch - // - once when we completed the batch - assert.strictEqual(dbUpdateStub.callCount, 3); - - assert.strictEqual(processBatchCallback.callCount, 1); - assert.strictEqual(processorCompleteCallback.callCount, 1); - const batch: IDBBatch = processBatchCallback.getCall(0).args[0]; - for (let i = 0; i < p.config.batchMaxRecords; i++) { - assert(batch.records.find(r => r.id === `test_${i}`)); - } - - }); - - it('handles a failure to persist the batch to the DB', async () => { - - const processBatchCallback = sinon.stub(); - const processorCompleteCallback = sinon.stub(); - const p = new BatchProcessor( - 'author1', - 'type1', - processBatchCallback, - processorCompleteCallback, - ); - - // Make the persistence fail - (database.upsertBatch as SinonStub).rejects(new Error('pop')); - - let failed; - try { - await p.add({ - recordType: BatchRecordType.assetInstance, - id: `test` - }); - } - catch(err) { - failed = true; - assert.strictEqual(err.message, 'pop'); - } - assert(failed); - - }); - - it('times out a requests that are queued too long, when there is a batch in flight, and a batch queued', async () => { - - const processBatchCallback = sinon.stub().callsFake(() => delay(10)); - const processorCompleteCallback = sinon.stub(); - const p = new BatchProcessor( - 'author1', - 'type1', - processBatchCallback, - processorCompleteCallback, - { - batchMaxRecords: 1, // to trigger a batch immeidately - addTimeoutMS: 5, - } - ); - - await p.add({ id: `test-batch1-dispatched`, recordType: BatchRecordType.assetInstance }); - - // Make the persistence fail - (database.upsertBatch as SinonStub).onSecondCall().callsFake(() => delay(10)); - - let failed; - try { - await Promise.all([ - p.add({ id: `test-batch2-blocked`, recordType: BatchRecordType.assetInstance }), - p.add({ id: `test-batch3-timeout`, recordType: BatchRecordType.assetInstance }), - ]); - } - catch(err) { - failed = true; - assert(err.message.includes('Timed out add of record after')); - } - assert(failed); - - // Clear everything out - for (let i = 0; i < 100; i++) { - if (processorCompleteCallback.callCount === 0) await delay(1); - } - // Confirm two batches went through - assert.strictEqual(processBatchCallback.callCount, 2); - - }); - - describe('with test wrapper', () => { - - class TestBatchProcessorWrapper extends BatchProcessor { - public dispatchBatch() { - return super.dispatchBatch(); - } - public processBatch(batch: IDBBatch) { - return super.processBatch(batch); - } - public newBatch(): IDBBatch { - return super.newBatch(); - } - } - - it('protects dispatchBatch against duplicate calls', async () => { - const p = new TestBatchProcessorWrapper( - 'author1', - 'type1', - sinon.stub(), - sinon.stub(), - ); - // p.assemblyBatch is not set, so this is a no-op and can be called many times - await p.dispatchBatch(); - await p.dispatchBatch(); - }); - - it('retries in processBatch, with backoff', async () => { - const p = new TestBatchProcessorWrapper( - 'author1', - 'type1', - sinon.stub() - .onFirstCall().rejects(new Error('try me again')) - .onSecondCall().rejects(new Error('and one more time with feeling')), - sinon.stub(), - { - retryInitialDelayMS: 1, - } - ); - // p.assemblyBatch is not set, so this is a no-op and can be called many times - await p.processBatch(p.newBatch()); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/lib/config.ts b/kat/src/test/ethereum/lib/config.ts deleted file mode 100644 index 77232aa2c3..0000000000 --- a/kat/src/test/ethereum/lib/config.ts +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import * as utils from '../../../lib/utils'; -import nock from 'nock'; -import sinon from 'sinon'; -import assert from 'assert'; - -export const testUtils = async () => { - -describe('Utils', () => { - - before(() => { - sinon.replace(utils, 'constants', { ...utils.constants, REST_API_CALL_MAX_ATTEMPTS: 3, REST_API_CALL_RETRY_DELAY_MS: 0 }); - }); - - describe('Axios with retry', () => { - - it('First attempt successful', async () => { - nock('https://kaleido.io') - .get('/test') - .reply(200, { data: 'test' }); - const result = await utils.axiosWithRetry({ - url: 'https://kaleido.io/test' - }); - assert.deepStrictEqual(result.data, { data: 'test' }); - }); - - it('1 failed attempt', async () => { - nock('https://kaleido.io') - .get('/test') - .reply(500) - .get('/test') - .reply(200, { data: 'test' }); - - const result = await utils.axiosWithRetry({ - url: 'https://kaleido.io/test' - }); - assert.deepStrictEqual(result.data, { data: 'test' }); - }); - - it('2 failed attempts', async () => { - nock('https://kaleido.io') - .get('/test') - .reply(500) - .get('/test') - .reply(500) - .get('/test') - .reply(200, { data: 'test' }); - const result = await utils.axiosWithRetry({ - url: 'https://kaleido.io/test' - }); - assert.deepStrictEqual(result.data, { data: 'test' }); - }); - - it('3 failed attempts', async () => { - nock('https://kaleido.io') - .get('/test') - .reply(500) - .get('/test') - .reply(500) - .get('/test') - .reply(500) - try { - await utils.axiosWithRetry({ - url: 'https://kaleido.io/test' - }); - } catch (err) { - assert.strictEqual(err.response.status, 500); - } - }); - - it('Not found should return immediately', async () => { - nock('https://kaleido.io') - .get('/test') - .reply(404); - try { - await utils.axiosWithRetry({ - url: 'https://kaleido.io/test' - }); - } catch (err) { - assert.deepStrictEqual(err.response.status, 404); - } - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/lib/index.ts b/kat/src/test/ethereum/lib/index.ts deleted file mode 100644 index 53a1dc9982..0000000000 --- a/kat/src/test/ethereum/lib/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { testBatchManager } from "./batch-manager-test"; -import { testBatchProcessor } from "./batch-processor-test"; -import { testUtils } from "./config"; -import { testSettings } from "./settings"; -import { testLogging } from "./logging"; - -export const testLibraryFunctions = () => { - describe('Lib tests', async () => { - testBatchManager(); - testBatchProcessor(); - testUtils(); - testSettings(); - testLogging(); - }); -}; \ No newline at end of file diff --git a/kat/src/test/ethereum/lib/logging.ts b/kat/src/test/ethereum/lib/logging.ts deleted file mode 100644 index 9b19bff433..0000000000 --- a/kat/src/test/ethereum/lib/logging.ts +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { Logger, setLogLevel } from '../../../lib/logging'; - -export const testLogging = async () => { - - describe('Logging', () => { - - it('logs all the levels', () => { - - setLogLevel('trace') - - const logger = new Logger('unit test'); - logger.error('this is an error message'); - logger.warn('this is an warning message'); - logger.warn('this is an info message'); - logger.debug('this is a debug message'); - logger.trace('this is a trace message'); - - // Log empty - logger.info(); - - // Log a dodgy axios message exercising paths - logger.info({ - isAxiosError: true, - }) - - // Log an axios error that looks like a stream - logger.info({ - isAxiosError: true, - response: { - data: { - on: () => null, - }, - }, - }) - - }); - - }); -}; diff --git a/kat/src/test/ethereum/lib/settings.ts b/kat/src/test/ethereum/lib/settings.ts deleted file mode 100644 index 2cedc64ca1..0000000000 --- a/kat/src/test/ethereum/lib/settings.ts +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app } from '../../common'; -import assert from 'assert'; -import request from 'supertest'; -import { ISettings } from '../../../lib/interfaces'; - -export const testSettings = async () => { - -describe('Settings', () => { - it('Checks that settings can be retrieved', async () => { - const getSettingsResponse = await request(app) - .get('/api/v1/settings') - .expect(200); - const settings: ISettings = getSettingsResponse.body; - assert.deepStrictEqual(settings.clientEvents, [ 'asset-instance-submitted' ]); - }); - - it('Checks that settings can be updated', async () => { - const result = await request(app) - .put('/api/v1/settings') - .send({ - key: 'clientEvents', - value: ['asset-instance-property-set'] - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'success'); - - const getSettingsResponse = await request(app) - .get('/api/v1/settings') - .expect(200); - const settings: ISettings = getSettingsResponse.body; - assert.deepStrictEqual(settings.clientEvents, [ 'asset-instance-property-set' ]); - }); - - it('Fails when attempting to add an invalid setting', async () => { - const result = await request(app) - .put('/api/v1/settings') - .send({ - key: 'clientEvents', - value: ['invalid'] - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Invalid Settings' }); - }); -}); -}; diff --git a/kat/src/test/ethereum/members/argument-validation.ts b/kat/src/test/ethereum/members/argument-validation.ts deleted file mode 100644 index bfcb83de80..0000000000 --- a/kat/src/test/ethereum/members/argument-validation.ts +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app } from '../../common'; -import request from 'supertest'; -import assert from 'assert'; - -export const testMembersArgumentValidation = async () => { - -describe('Members - argument validation', async () => { - - it('Attempting to add a member without an address should raise an error', async () => { - const result = await request(app) - .put('/api/v1/members') - .send({ - name: 'Member A', - app2appDestination: 'kld://app2app', - docExchangeDestination: 'kld://docexchange' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing member address' }); - }); - - it('Attempting to add a member without a name should raise an error', async () => { - const result = await request(app) - .put('/api/v1/members') - .send({ - address: '0x0000000000000000000000000000000000000001', - app2appDestination: 'kld://app2app', - docExchangeDestination: 'kld://docexchange' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing member name' }); - }); - - it('Attempting to get a member that does not exist should raise an error', async () => { - const result = await request(app) - .get('/api/v1/members/0x0000000000000000000000000000000000000099') - .expect(404); - assert.deepStrictEqual(result.body, { error: 'Member not found' }); - }); - -}); -}; diff --git a/kat/src/test/ethereum/members/index.ts b/kat/src/test/ethereum/members/index.ts deleted file mode 100644 index 95f9145715..0000000000 --- a/kat/src/test/ethereum/members/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { testMembersArgumentValidation } from "./argument-validation"; -import { testMemberRegistration } from "./registration"; - -export const testMembers = async () => { - describe('Member tests', async () => { - testMemberRegistration(); - testMembersArgumentValidation(); - }); -}; \ No newline at end of file diff --git a/kat/src/test/ethereum/members/registration.ts b/kat/src/test/ethereum/members/registration.ts deleted file mode 100644 index 3a161ec358..0000000000 --- a/kat/src/test/ethereum/members/registration.ts +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../common'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IEventMemberRegistered, IDBMember } from '../../../lib/interfaces'; -import * as utils from '../../../lib/utils'; - -export const testMemberRegistration = async () => { - -describe('Members - registration', async () => { - - const timestampCreation = utils.getTimestamp(); - const timestampUpdate = utils.getTimestamp(); - - it('Checks that adding a member sends a request to API Gateway and updates the database', async () => { - - nock('https://apigateway.kaleido.io') - .post('/registerMember?kld-from=0x0000000000000000000000000000000000000011&kld-sync=false') - .reply(200); - const addMemberResponse = await request(app) - .put('/api/v1/members') - .send({ - address: '0x0000000000000000000000000000000000000011', - name: 'Member 1' - }) - .expect(200); - assert.deepStrictEqual(addMemberResponse.body, { status: 'submitted' }); - - const getMemberResponse = await request(app) - .get('/api/v1/members') - .expect(200); - const member = getMemberResponse.body.find((member: IDBMember) => member.address === '0x0000000000000000000000000000000000000011'); - assert.strictEqual(member.address, '0x0000000000000000000000000000000000000011'); - assert.strictEqual(member.name, 'Member 1'); - assert.strictEqual(member.assetTrailInstanceID, 'service-id'); - assert.strictEqual(member.app2appDestination, 'kld://app2app/internal'); - assert.strictEqual(member.docExchangeDestination, 'kld://docstore/dest'); - assert.strictEqual(typeof member.submitted, 'number'); - - const getMemberByAddressResponse = await request(app) - .get('/api/v1/members/0x0000000000000000000000000000000000000011') - .expect(200); - assert.deepStrictEqual(member, getMemberByAddressResponse.body); - }); - - it('Checks that event stream notification for confirming member registrations is handled', async () => { - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - - const data: IEventMemberRegistered = { - member: '0x0000000000000000000000000000000000000011', - name: 'Member 1', - assetTrailInstanceID: 'service-id', - app2appDestination: 'kld://app2app/internal', - docExchangeDestination: 'kld://docstore/dest', - timestamp: timestampCreation - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.MEMBER_REGISTERED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Get member should return the confirmed member', async () => { - const getMemberResponse = await request(app) - .get('/api/v1/members') - .expect(200); - const member = getMemberResponse.body.find((member: IDBMember) => member.address === '0x0000000000000000000000000000000000000011'); - assert.strictEqual(member.address, '0x0000000000000000000000000000000000000011'); - assert.strictEqual(member.name, 'Member 1'); - assert.strictEqual(member.assetTrailInstanceID, 'service-id'); - assert.strictEqual(member.app2appDestination, 'kld://app2app/internal'); - assert.strictEqual(member.docExchangeDestination, 'kld://docstore/dest'); - assert.strictEqual(member.blockNumber, 123); - assert.strictEqual(member.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - assert.strictEqual(member.timestamp, timestampCreation); - - const getMemberByAddressResponse = await request(app) - .get('/api/v1/members/0x0000000000000000000000000000000000000011') - .expect(200); - assert.deepStrictEqual(member, getMemberByAddressResponse.body); - }); - - it('Checks that updating a member sends a request to API Gateway and updates the database', async () => { - nock('https://apigateway.kaleido.io') - .post('/registerMember?kld-from=0x0000000000000000000000000000000000000011&kld-sync=false') - .reply(200); - const addMemberResponse = await request(app) - .put('/api/v1/members') - .send({ - address: '0x0000000000000000000000000000000000000011', - name: 'Member 2' - }) - .expect(200); - assert.deepStrictEqual(addMemberResponse.body, { status: 'submitted' }); - - const getMemberResponse = await request(app) - .get('/api/v1/members') - .expect(200); - const member = getMemberResponse.body.find((member: IDBMember) => member.address === '0x0000000000000000000000000000000000000011'); - assert.strictEqual(member.address, '0x0000000000000000000000000000000000000011'); - assert.strictEqual(member.name, 'Member 2'); - assert.strictEqual(member.assetTrailInstanceID, 'service-id'); - assert.strictEqual(member.app2appDestination, 'kld://app2app/internal'); - assert.strictEqual(member.docExchangeDestination, 'kld://docstore/dest'); - assert.strictEqual(member.blockNumber, 123); - assert.strictEqual(member.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - assert.strictEqual(typeof member.timestamp, 'number'); - - const getMemberByAddressResponse = await request(app) - .get('/api/v1/members/0x0000000000000000000000000000000000000011') - .expect(200); - assert.deepStrictEqual(member, getMemberByAddressResponse.body); - }); - - it('Checks that event stream notification for confirming member registrations are handled', async () => { - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - - const data: IEventMemberRegistered = { - member: '0x0000000000000000000000000000000000000011', - name: 'Member 2', - assetTrailInstanceID: 'service-id', - app2appDestination: 'kld://app2app/internal', - docExchangeDestination: 'kld://docstore/dest', - timestamp: timestampUpdate - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.MEMBER_REGISTERED, - data, - blockNumber: '456', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000001' - }])); - await eventPromise; - }); - - it('Get member should return the confirmed member', async () => { - const getMemberResponse = await request(app) - .get('/api/v1/members') - .expect(200); - const member = getMemberResponse.body.find((member: IDBMember) => member.address === '0x0000000000000000000000000000000000000011'); - assert.strictEqual(member.address, '0x0000000000000000000000000000000000000011'); - assert.strictEqual(member.name, 'Member 2'); - assert.strictEqual(member.assetTrailInstanceID, 'service-id'); - assert.strictEqual(member.app2appDestination, 'kld://app2app/internal'); - assert.strictEqual(member.docExchangeDestination, 'kld://docstore/dest'); - assert.strictEqual(member.blockNumber, 456); - assert.strictEqual(member.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000001'); - assert.strictEqual(member.timestamp, timestampUpdate); - - const getMemberByAddressResponse = await request(app) - .get('/api/v1/members/0x0000000000000000000000000000000000000011') - .expect(200); - assert.deepStrictEqual(member, getMemberByAddressResponse.body); - }); - -}); -}; diff --git a/kat/src/test/ethereum/payments/argument-validation.ts b/kat/src/test/ethereum/payments/argument-validation.ts deleted file mode 100644 index f9136389ce..0000000000 --- a/kat/src/test/ethereum/payments/argument-validation.ts +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app } from '../../common'; -import request from 'supertest'; -import assert from 'assert'; - -export const testPaymentArgumentValidation = async () => { - -describe('Payment definitions - argument validation', async () => { - - it('Attempting to get a payment definition that does not exist should raise an error', async () => { - const result = await request(app) - .get('/api/v1/payments/definitions/missing') - .expect(404); - assert.deepStrictEqual(result.body, { error: 'Payment definition not found' }); - }); - - it('Attempting to add a payment definition without a name should raise an error', async () => { - const result = await request(app) - .post('/api/v1/payments/definitions') - .send({ - author: '0x0000000000000000000000000000000000000001' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing or invalid payment definition name' }); - }); - - it('Attempting to add a payment definition without an author should raise an error', async () => { - const result = await request(app) - .post('/api/v1/payments/definitions') - .send({ - name: 'My payment definition' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Missing or invalid payment definition author' }); - }); - - it('Attempting to add a payment definition with an invalid description schema should raise an error', async () => { - const result = await request(app) - .post('/api/v1/payments/definitions') - .send({ - name: 'My payment definition', - author: '0x0000000000000000000000000000000000000001', - descriptionSchema: 'INVALID' - }) - .expect(400); - assert.deepStrictEqual(result.body, { error: 'Invalid description schema' }); - }); - -}); -}; diff --git a/kat/src/test/ethereum/payments/authored-described.ts b/kat/src/test/ethereum/payments/authored-described.ts deleted file mode 100644 index 05470afb53..0000000000 --- a/kat/src/test/ethereum/payments/authored-described.ts +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../common'; -import { testDescription } from '../../samples'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IDBPaymentDefinition, IDBPaymentInstance, IEventPaymentDefinitionCreated, IEventPaymentInstanceCreated } from '../../../lib/interfaces'; -import * as utils from '../../../lib/utils'; - -export const testAuthoredDescribed = async () => { - -describe('Payment definitions: authored - described', async () => { - - let paymentDefinitionID: string; - const timestamp = utils.getTimestamp(); - - describe('Create described payment definition', () => { - - it('Checks that the payment definition can be added', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createDescribedPaymentDefinition?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: testDescription.schema.ipfsMultiHash }); - - const result = await request(app) - .post('/api/v1/payments/definitions') - .send({ - name: 'authored - described', - author: '0x0000000000000000000000000000000000000001', - descriptionSchema: testDescription.schema.object - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - paymentDefinitionID = result.body.paymentDefinitionID; - - const getPaymentDefinitionsResponse = await request(app) - .get('/api/v1/payments/definitions') - .expect(200); - const paymentDefinition = getPaymentDefinitionsResponse.body.find((paymentDefinition: IDBPaymentDefinition) => paymentDefinition.name === 'authored - described'); - assert.strictEqual(paymentDefinition.paymentDefinitionID, paymentDefinitionID); - assert.strictEqual(paymentDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.deepStrictEqual(paymentDefinition.descriptionSchema, testDescription.schema.object); - assert.strictEqual(paymentDefinition.name, 'authored - described'); - assert.strictEqual(paymentDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(typeof paymentDefinition.submitted, 'number'); - - const getPaymentDefinitionResponse = await request(app) - .get(`/api/v1/payments/definitions/${paymentDefinitionID}`) - .expect(200); - assert.deepStrictEqual(paymentDefinition, getPaymentDefinitionResponse.body); - }); - - it('Checks that the event stream notification for confirming the payment definition creation is handled', async () => { - nock('https://ipfs.kaleido.io') - .get(`/ipfs/${testDescription.schema.ipfsMultiHash}`) - .reply(200, testDescription.schema.object); - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventPaymentDefinitionCreated = { - paymentDefinitionID: utils.uuidToHex(paymentDefinitionID), - author: '0x0000000000000000000000000000000000000001', - name: 'authored - described', - descriptionSchemaHash: testDescription.schema.ipfsSha256, - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.DESCRIBED_PAYMENT_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the payment definition is confirmed', async () => { - const getPaymentDefinitionsResponse = await request(app) - .get('/api/v1/payments/definitions') - .expect(200); - const paymentDefinition = getPaymentDefinitionsResponse.body.find((paymentDefinition: IDBPaymentDefinition) => paymentDefinition.name === 'authored - described'); - assert.strictEqual(paymentDefinition.paymentDefinitionID, paymentDefinitionID); - assert.strictEqual(paymentDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.deepStrictEqual(paymentDefinition.descriptionSchema, testDescription.schema.object); - assert.strictEqual(paymentDefinition.name, 'authored - described'); - assert.strictEqual(paymentDefinition.timestamp, timestamp); - assert.strictEqual(paymentDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(typeof paymentDefinition.submitted, 'number'); - assert.strictEqual(paymentDefinition.blockNumber, 123); - assert.strictEqual(paymentDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getPaymentDefinitionResponse = await request(app) - .get(`/api/v1/payments/definitions/${paymentDefinitionID}`) - .expect(200); - assert.deepStrictEqual(paymentDefinition, getPaymentDefinitionResponse.body); - }); - - }); - - describe('Payment instances', async () => { - - let paymentInstanceID: string; - - it('Checks that a payment instance can be created', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createDescribedPaymentInstance?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - nock('https://ipfs.kaleido.io') - .post('/api/v0/add') - .reply(200, { Hash: testDescription.sample.ipfsMultiHash }) - - const result = await request(app) - .post('/api/v1/payments/instances') - .send({ - paymentDefinitionID, - author: '0x0000000000000000000000000000000000000001', - description: testDescription.sample.object, - member: '0x0000000000000000000000000000000000000002', - amount: 10 - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - paymentInstanceID = result.body.paymentInstanceID; - - const getPaymentInstancesResponse = await request(app) - .get('/api/v1/payments/instances') - .expect(200); - const paymentInstance = getPaymentInstancesResponse.body.find((paymentInstance: IDBPaymentInstance) => paymentInstance.paymentInstanceID === paymentInstanceID); - assert.strictEqual(paymentInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(paymentInstance.paymentDefinitionID, paymentDefinitionID); - assert.strictEqual(paymentInstance.descriptionHash, testDescription.sample.ipfsSha256); - assert.deepStrictEqual(paymentInstance.description, testDescription.sample.object); - assert.strictEqual(paymentInstance.member, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(paymentInstance.amount, 10); - assert.strictEqual(paymentInstance.receipt, 'my-receipt-id'); - assert.strictEqual(typeof paymentInstance.submitted, 'number'); - - const getPaymentInstanceResponse = await request(app) - .get(`/api/v1/payments/instances/${paymentInstanceID}`) - .expect(200); - assert.deepStrictEqual(paymentInstance, getPaymentInstanceResponse.body); - - }); - - it('Checks that the event stream notification for confirming the payment instance creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventPaymentInstanceCreated = { - paymentDefinitionID: utils.uuidToHex(paymentDefinitionID), - author: '0x0000000000000000000000000000000000000001', - paymentInstanceID: utils.uuidToHex(paymentInstanceID), - descriptionHash: testDescription.sample.ipfsSha256, - amount: '10', - member: '0x0000000000000000000000000000000000000002', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.DESCRIBED_PAYMENT_INSTANCE_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the payment instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get('/api/v1/payments/instances') - .expect(200); - const paymentInstance = getAssetInstancesResponse.body.find((paymentInstance: IDBPaymentInstance) => paymentInstance.paymentInstanceID === paymentInstanceID); - assert.strictEqual(paymentInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(paymentInstance.member, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(paymentInstance.paymentDefinitionID, paymentDefinitionID); - assert.strictEqual(paymentInstance.descriptionHash, testDescription.sample.ipfsSha256); - assert.deepStrictEqual(paymentInstance.description, testDescription.sample.object); - assert.strictEqual(paymentInstance.amount, 10); - assert.strictEqual(paymentInstance.timestamp, timestamp); - assert.strictEqual(paymentInstance.receipt, 'my-receipt-id'); - assert.strictEqual(typeof paymentInstance.submitted, 'number'); - assert.strictEqual(paymentInstance.blockNumber, 123); - assert.strictEqual(paymentInstance.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/payments/instances/${paymentInstanceID}`) - .expect(200); - assert.deepStrictEqual(paymentInstance, getAssetInstanceResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/payments/authored.ts b/kat/src/test/ethereum/payments/authored.ts deleted file mode 100644 index 9d0256700e..0000000000 --- a/kat/src/test/ethereum/payments/authored.ts +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../common'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IDBPaymentDefinition, IDBPaymentInstance, IEventPaymentDefinitionCreated, IEventPaymentInstanceCreated } from '../../../lib/interfaces'; -import * as utils from '../../../lib/utils'; - -export const testAuthored = async () => { -describe('Payment definitions: authored', async () => { - - let paymentDefinitionID: string; - const timestamp = utils.getTimestamp(); - - describe('Create payment definition', () => { - - it('Checks that the payment definition can be added', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createPaymentDefinition?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - const result = await request(app) - .post('/api/v1/payments/definitions') - .send({ - name: 'authored', - author: '0x0000000000000000000000000000000000000001', - amount: 1 - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - paymentDefinitionID = result.body.paymentDefinitionID; - - const getPaymentDefinitionsResponse = await request(app) - .get('/api/v1/payments/definitions') - .expect(200); - const paymentDefinition = getPaymentDefinitionsResponse.body.find((paymentDefinition: IDBPaymentDefinition) => paymentDefinition.name === 'authored'); - assert.strictEqual(paymentDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(paymentDefinition.name, 'authored'); - assert.strictEqual(paymentDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(typeof paymentDefinition.submitted, 'number'); - }); - - it('Checks that the event stream notification for confirming the payment definition creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventPaymentDefinitionCreated = { - paymentDefinitionID: utils.uuidToHex(paymentDefinitionID), - author: '0x0000000000000000000000000000000000000001', - name: 'authored', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.DESCRIBED_PAYMENT_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the payment definition is confirmed', async () => { - const getPaymentDefinitionsResponse = await request(app) - .get('/api/v1/payments/definitions') - .expect(200); - const paymentDefinition = getPaymentDefinitionsResponse.body.find((paymentDefinition: IDBPaymentDefinition) => paymentDefinition.name === 'authored'); - assert.strictEqual(paymentDefinition.paymentDefinitionID, paymentDefinitionID); - assert.strictEqual(paymentDefinition.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(paymentDefinition.name, 'authored'); - assert.strictEqual(paymentDefinition.receipt, 'my-receipt-id'); - assert.strictEqual(typeof paymentDefinition.submitted, 'number'); - assert.strictEqual(paymentDefinition.timestamp, timestamp); - assert.strictEqual(paymentDefinition.blockNumber, 123); - assert.strictEqual(paymentDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getPaymentDefinitionResponse = await request(app) - .get(`/api/v1/payments/definitions/${paymentDefinitionID}`) - .expect(200); - assert.deepStrictEqual(paymentDefinition, getPaymentDefinitionResponse.body); - }); - - }); - - describe('Payment instances', async () => { - - let paymentInstanceID: string; - - it('Checks that a payment instance can be created', async () => { - - nock('https://apigateway.kaleido.io') - .post('/createPaymentInstance?kld-from=0x0000000000000000000000000000000000000001&kld-sync=false') - .reply(200, { id: 'my-receipt-id' }); - - const result = await request(app) - .post('/api/v1/payments/instances') - .send({ - paymentDefinitionID, - author: '0x0000000000000000000000000000000000000001', - member: '0x0000000000000000000000000000000000000002', - amount: 10 - }) - .expect(200); - assert.deepStrictEqual(result.body.status, 'submitted'); - paymentInstanceID = result.body.paymentInstanceID; - - const getPaymentInstancesResponse = await request(app) - .get('/api/v1/payments/instances') - .expect(200); - const paymentInstance = getPaymentInstancesResponse.body.find((paymentInstance: IDBPaymentInstance) => paymentInstance.paymentInstanceID === paymentInstanceID); - assert.strictEqual(paymentInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(paymentInstance.paymentDefinitionID, paymentDefinitionID); - assert.strictEqual(paymentInstance.member, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(paymentInstance.amount, 10); - assert.strictEqual(paymentInstance.receipt, 'my-receipt-id'); - assert.strictEqual(typeof paymentInstance.submitted, 'number'); - - const getPaymentInstanceResponse = await request(app) - .get(`/api/v1/payments/instances/${paymentInstanceID}`) - .expect(200); - assert.deepStrictEqual(paymentInstance, getPaymentInstanceResponse.body); - - }); - - it('Checks that the event stream notification for confirming the payment instance creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventPaymentInstanceCreated = { - paymentDefinitionID: utils.uuidToHex(paymentDefinitionID), - author: '0x0000000000000000000000000000000000000001', - paymentInstanceID: utils.uuidToHex(paymentInstanceID), - amount: '10', - member: '0x0000000000000000000000000000000000000002', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.PAYMENT_INSTANCE_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the payment instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get('/api/v1/payments/instances') - .expect(200); - const paymentInstance = getAssetInstancesResponse.body.find((paymentInstance: IDBPaymentInstance) => paymentInstance.paymentInstanceID === paymentInstanceID); - assert.strictEqual(paymentInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(paymentInstance.member, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(paymentInstance.paymentDefinitionID, paymentDefinitionID); - assert.strictEqual(paymentInstance.amount, 10); - assert.strictEqual(paymentInstance.receipt, 'my-receipt-id'); - assert.strictEqual(typeof paymentInstance.submitted, 'number'); - assert.strictEqual(paymentInstance.timestamp, timestamp); - assert.strictEqual(paymentInstance.blockNumber, 123); - assert.strictEqual(paymentInstance.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/payments/instances/${paymentInstanceID}`) - .expect(200); - assert.deepStrictEqual(paymentInstance, getAssetInstanceResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/payments/index.ts b/kat/src/test/ethereum/payments/index.ts deleted file mode 100644 index da7578f3e7..0000000000 --- a/kat/src/test/ethereum/payments/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { testPaymentArgumentValidation } from "./argument-validation"; -import { testAuthored } from "./authored"; -import { testAuthoredDescribed } from "./authored-described"; -import { testUnauthored } from "./unauthored"; -import { testUnauthoredDescribed } from "./unauthored-described"; - -export const testPayments = async () => { - describe('Payment tests', async () => { - testPaymentArgumentValidation(); - testAuthored(); - testAuthoredDescribed(); - testUnauthored(); - testUnauthoredDescribed(); - }); -}; \ No newline at end of file diff --git a/kat/src/test/ethereum/payments/unauthored-described.ts b/kat/src/test/ethereum/payments/unauthored-described.ts deleted file mode 100644 index 1747b3bbd3..0000000000 --- a/kat/src/test/ethereum/payments/unauthored-described.ts +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../common'; -import { testDescription } from '../../samples'; -import nock from 'nock'; -import request from 'supertest'; -import assert from 'assert'; -import { IEventPaymentDefinitionCreated, IDBPaymentDefinition, IDBPaymentInstance, IEventPaymentInstanceCreated } from '../../../lib/interfaces'; -import * as utils from '../../../lib/utils'; - -export const testUnauthoredDescribed = async () => { -describe('Payment definitions: unauthored - described', async () => { - - const paymentDefinitionID = '4b4a3be1-0732-4ba1-b492-6f315bb82f53'; - const timestamp = utils.getTimestamp(); - - describe('Payment definition event', async () => { - - it('Checks that the event stream notification for confirming the payment definition creation is handled', async () => { - - nock('https://ipfs.kaleido.io') - .get(`/ipfs/${testDescription.schema.ipfsMultiHash}`) - .reply(200, testDescription.schema.object); - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventPaymentDefinitionCreated = { - paymentDefinitionID: utils.uuidToHex(paymentDefinitionID), - author: '0x0000000000000000000000000000000000000002', - name: 'unauthored - described', - descriptionSchemaHash: testDescription.schema.ipfsSha256, - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.DESCRIBED_PAYMENT_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the payment definition event has been processed', async () => { - const getPaymentDefinitionsResponse = await request(app) - .get('/api/v1/payments/definitions') - .expect(200); - const paymentDefinition = getPaymentDefinitionsResponse.body.find((paymentDefinition: IDBPaymentDefinition) => paymentDefinition.name === 'unauthored - described'); - assert.strictEqual(paymentDefinition.paymentDefinitionID, paymentDefinitionID); - assert.strictEqual(paymentDefinition.author, '0x0000000000000000000000000000000000000002'); - assert.deepStrictEqual(paymentDefinition.descriptionSchema, testDescription.schema.object); - assert.strictEqual(paymentDefinition.name, 'unauthored - described'); - assert.strictEqual(paymentDefinition.timestamp, timestamp); - assert.strictEqual(paymentDefinition.blockNumber, 123); - assert.strictEqual(paymentDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getPaymentDefinitionResponse = await request(app) - .get(`/api/v1/payments/definitions/${paymentDefinitionID}`) - .expect(200); - assert.deepStrictEqual(paymentDefinition, getPaymentDefinitionResponse.body); - }); - - }); - - describe('Payment instances', async () => { - - const paymentInstanceID = 'f831b208-9567-4fe2-b388-8e994a6163e1'; - - it('Checks that the event stream notification for confirming the payment instance creation is handled', async () => { - nock('https://ipfs.kaleido.io') - .get(`/ipfs/${testDescription.sample.ipfsMultiHash}`) - .reply(200, testDescription.sample.object); - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventPaymentInstanceCreated = { - paymentDefinitionID: utils.uuidToHex(paymentDefinitionID), - author: '0x0000000000000000000000000000000000000001', - paymentInstanceID: utils.uuidToHex(paymentInstanceID), - descriptionHash: testDescription.sample.ipfsSha256, - amount: '10', - member: '0x0000000000000000000000000000000000000002', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.DESCRIBED_PAYMENT_INSTANCE_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the payment instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get('/api/v1/payments/instances') - .expect(200); - const paymentInstance = getAssetInstancesResponse.body.find((paymentInstance: IDBPaymentInstance) => paymentInstance.paymentInstanceID === paymentInstanceID); - assert.strictEqual(paymentInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(paymentInstance.member, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(paymentInstance.paymentDefinitionID, paymentDefinitionID); - assert.strictEqual(paymentInstance.descriptionHash, testDescription.sample.ipfsSha256); - assert.deepStrictEqual(paymentInstance.description, testDescription.sample.object); - assert.strictEqual(paymentInstance.submitted, undefined); - assert.strictEqual(paymentInstance.receipt, undefined); - assert.strictEqual(paymentInstance.amount, 10); - assert.strictEqual(paymentInstance.timestamp, timestamp); - assert.strictEqual(paymentInstance.blockNumber, 123); - assert.strictEqual(paymentInstance.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/payments/instances/${paymentInstanceID}`) - .expect(200); - assert.deepStrictEqual(paymentInstance, getAssetInstanceResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/ethereum/payments/unauthored.ts b/kat/src/test/ethereum/payments/unauthored.ts deleted file mode 100644 index 0cd63bb3bd..0000000000 --- a/kat/src/test/ethereum/payments/unauthored.ts +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - -import { app, mockEventStreamWebSocket } from '../../common'; -import request from 'supertest'; -import assert from 'assert'; -import { IEventPaymentDefinitionCreated, IDBPaymentDefinition, IEventPaymentInstanceCreated, IDBPaymentInstance } from '../../../lib/interfaces'; -import * as utils from '../../../lib/utils'; - -export const testUnauthored = async () => { - -describe('Payment definitions: unauthored', async () => { - - const paymentDefinitionID = 'f9812952-50f8-4090-9412-e7b0f3eeb930'; - const timestamp = utils.getTimestamp(); - - describe('Payment definition', async () => { - - it('Checks that the event stream notification for confirming the payment definition creation is handled', async () => { - - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventPaymentDefinitionCreated = { - paymentDefinitionID: utils.uuidToHex(paymentDefinitionID), - author: '0x0000000000000000000000000000000000000002', - name: 'unauthored', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.PAYMENT_DEFINITION_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the payment definition is confirmed', async () => { - const getPaymentDefinitionsResponse = await request(app) - .get('/api/v1/payments/definitions') - .expect(200); - const paymentDefinition = getPaymentDefinitionsResponse.body.find((paymentDefinition: IDBPaymentDefinition) => paymentDefinition.name === 'unauthored'); - assert.strictEqual(paymentDefinition.paymentDefinitionID, paymentDefinitionID); - assert.strictEqual(paymentDefinition.author, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(paymentDefinition.name, 'unauthored'); - assert.strictEqual(paymentDefinition.timestamp, timestamp); - assert.strictEqual(paymentDefinition.blockNumber, 123); - assert.strictEqual(paymentDefinition.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getPaymentDefinitionResponse = await request(app) - .get(`/api/v1/payments/definitions/${paymentDefinitionID}`) - .expect(200); - assert.deepStrictEqual(paymentDefinition, getPaymentDefinitionResponse.body); - }); - - }); - - describe('Payment instances', async () => { - - const paymentInstanceID = '646a2a24-319e-408b-a099-fc163ff3e692'; - - it('Checks that the event stream notification for confirming the payment instance creation is handled', async () => { - const eventPromise = new Promise((resolve) => { - mockEventStreamWebSocket.once('send', message => { - assert.strictEqual(message, '{"type":"ack","topic":"dev"}'); - resolve(); - }) - }); - const data: IEventPaymentInstanceCreated = { - paymentDefinitionID: utils.uuidToHex(paymentDefinitionID), - author: '0x0000000000000000000000000000000000000001', - paymentInstanceID: utils.uuidToHex(paymentInstanceID), - amount: '10', - member: '0x0000000000000000000000000000000000000002', - timestamp: timestamp.toString() - }; - mockEventStreamWebSocket.emit('message', JSON.stringify([{ - signature: utils.contractEventSignatures.PAYMENT_INSTANCE_CREATED, - data, - blockNumber: '123', - transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000' - }])); - await eventPromise; - }); - - it('Checks that the payment instance is confirmed', async () => { - const getAssetInstancesResponse = await request(app) - .get('/api/v1/payments/instances') - .expect(200); - const paymentInstance = getAssetInstancesResponse.body.find((paymentInstance: IDBPaymentInstance) => paymentInstance.paymentInstanceID === paymentInstanceID); - assert.strictEqual(paymentInstance.author, '0x0000000000000000000000000000000000000001'); - assert.strictEqual(paymentInstance.member, '0x0000000000000000000000000000000000000002'); - assert.strictEqual(paymentInstance.paymentDefinitionID, paymentDefinitionID); - assert.strictEqual(paymentInstance.submitted, undefined); - assert.strictEqual(paymentInstance.receipt, undefined); - assert.strictEqual(paymentInstance.amount, 10); - assert.strictEqual(paymentInstance.timestamp, timestamp); - assert.strictEqual(paymentInstance.blockNumber, 123); - assert.strictEqual(paymentInstance.transactionHash, '0x0000000000000000000000000000000000000000000000000000000000000000'); - - const getAssetInstanceResponse = await request(app) - .get(`/api/v1/payments/instances/${paymentInstanceID}`) - .expect(200); - assert.deepStrictEqual(paymentInstance, getAssetInstanceResponse.body); - }); - - }); - -}); -}; diff --git a/kat/src/test/samples.ts b/kat/src/test/samples.ts deleted file mode 100644 index 9b746d417f..0000000000 --- a/kat/src/test/samples.ts +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright © 2021 Kaleido, Inc. -// -// 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. - - -export const testDescription = { - schema: { - object: { - type: 'object', - required: ['my_description_string', 'my_description_number', 'my_description_boolean'], - properties: { - my_description_string: { - type: 'string' - }, - my_description_number: { - type: 'number' - }, - my_description_boolean: { - type: 'boolean' - } - } - }, - ipfsSha256: '0xbde03e0e77b5422ff3ce4889752ac9450343420a6a4354542b9fd14fd5fa435c', - ipfsMultiHash: 'Qmb7r5v11TYsJE8dYfnBFjwQsKapX1my7hzfAnd5GFq2io', - }, - sample: { - object: { - my_description_string: 'sample description string', - my_description_number: 123, - my_description_boolean: true - }, - ipfsSha256:'0x2ef1f576d187bb132068095b05a6796891bd0ee1bd69037c6c60f2a6b705d35a', - ipfsMultiHash: 'QmRVuTF2ktoKop95VbgARPZksdfZgpxx6xCJwFE3UbcMmT' - } -}; - -export const testContent = { - schema: { - object: { - type: 'object', - required: ['my_content_string', 'my_content_number', 'my_content_boolean'], - properties: { - my_content_string: { - type: 'string' - }, - my_content_number: { - type: 'number' - }, - my_content_boolean: { - type: 'boolean' - } - } - }, - }, - sample: { - object: { - my_content_string: 'sample content string', - my_content_number: 456, - my_content_boolean: true - }, - ipfsSha256: '0x12e850feabadae5158666a3d03b449fbd4f04582ef0c9b5a91247a02af110016', - ipfsMultiHash: 'QmPcTWXWiUEwect513QdDtw1wa9QWcRgGTVebGbjhMKNxV', - docExchangeSha256: '0xb681804d7f63b532394091f9a0eab0c94e82a92332b4d299ba7493903b27c9e1' - } -}; - -export const testIndexes = [ - { - fields: ["author"], - unique: false - }, - { - fields: ["author", "assetDefinitionID"], - unique: false - } -]; diff --git a/kat/test-resources/config-corda.json b/kat/test-resources/config-corda.json deleted file mode 100644 index 334912e04a..0000000000 --- a/kat/test-resources/config-corda.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "$schema": "../src/schemas/config.json", - "port": 3001, - "protocol": "corda", - "assetTrailInstanceID": "service-id", - "apiGateway": { - "apiEndpoint": "https://apigateway.kaleido.io", - "auth": { - "user": "testuser", - "password": "testpassword" - } - }, - "eventStreams": { - "wsEndpoint": "ws://eventstreams.kaleido.io", - "topic": "dev", - "auth": { - "user": "testuser", - "password": "testpassword" - }, - "skipSetup": true - }, - "ipfs": { - "apiEndpoint": "https://ipfs.kaleido.io" - }, - "app2app": { - "socketIOEndpoint": "wss://app2app.ws.kaleido.io", - "destinations": { - "kat": "kld://app2app/internal", - "client": "kld://app2app/external" - } - }, - "docExchange": { - "apiEndpoint": "https://docexchange.kaleido.io", - "socketIOEndpoint": "http://docexchange.ws.kaleido.io", - "destination": "kld://docstore/dest" - }, - "appCredentials": { - "user": "testuser", - "password": "testpassword" - } - } \ No newline at end of file diff --git a/kat/test-resources/config-ethereum.json b/kat/test-resources/config-ethereum.json deleted file mode 100644 index 16217240b1..0000000000 --- a/kat/test-resources/config-ethereum.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "../src/schemas/config.json", - "port": 3000, - "protocol": "ethereum", - "assetTrailInstanceID": "service-id", - "apiGateway": { - "apiEndpoint": "https://apigateway.kaleido.io" - }, - "eventStreams": { - "wsEndpoint": "ws://eventstreams.kaleido.io", - "topic": "dev", - "skipSetup": true - }, - "ipfs": { - "apiEndpoint": "https://ipfs.kaleido.io" - }, - "app2app": { - "socketIOEndpoint": "wss://app2app.ws.kaleido.io", - "destinations": { - "kat": "kld://app2app/internal", - "client": "kld://app2app/external" - } - }, - "docExchange": { - "apiEndpoint": "https://docexchange.kaleido.io", - "socketIOEndpoint": "http://docexchange.ws.kaleido.io", - "destination": "kld://docstore/dest" - }, - "appCredentials": { - "user": "testuser", - "password": "testpassword" - } -} \ No newline at end of file diff --git a/kat/test-resources/settings.json b/kat/test-resources/settings.json deleted file mode 100644 index 5590ea9b92..0000000000 --- a/kat/test-resources/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "clientEvents": ["asset-instance-submitted"] -} \ No newline at end of file diff --git a/kat/tsconfig.json b/kat/tsconfig.json deleted file mode 100644 index 009168bb58..0000000000 --- a/kat/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "include": ["src/**/*.ts"], - "compilerOptions": { - "target": "es6", - "module": "commonjs", - "lib": ["es6"], - "allowJs": true, - "outDir": "build", - "rootDir": "src", - "strict": true, - "sourceMap": true, - "strictNullChecks": true, - "noImplicitAny": true, - "esModuleInterop": true, - "resolveJsonModule": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - } -} \ No newline at end of file From 31b135dd6f4f28c44a13bcba497007b53abc2fab Mon Sep 17 00:00:00 2001 From: Peter Broadhurst Date: Mon, 11 Oct 2021 23:38:03 -0400 Subject: [PATCH 2/3] More updates to README Signed-off-by: Peter Broadhurst --- README.md | 104 +- images/event_driven_programming_model.png | Bin 0 -> 81454 bytes images/intro_to_firefly_teaser.svg | 2277 --------------------- images/multi_party_systems.png | Bin 0 -> 121096 bytes 4 files changed, 78 insertions(+), 2303 deletions(-) create mode 100644 images/event_driven_programming_model.png delete mode 100644 images/intro_to_firefly_teaser.svg create mode 100644 images/multi_party_systems.png diff --git a/README.md b/README.md index cdc41349a3..fcefdd0490 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,28 @@ ![Hyperledger FireFly](./images/hyperledger_firefly_logo.png) -Hyperledger FireFly is an API and data orchestration layer to build enterprise multi-party systems, on top of blockchain tech. +Hyperledger FireFly is an API and data orchestration layer on top of core blockchain technologies. + +It implements a [multi-party system](#multi-party-systems) for building enterprise decentralized applications. - Transaction submission and event streaming - Radically simplified API access to your on-chain smart contracts - Multi-protocol blockchain integration - - Hyperledger Fabric - - Enterprise Ethereum - Hyperledger Besu & Quorum - - Corda *(work in progress)* + - [Hyperledger Fabric](https://www.hyperledger.org/use/fabric) + - Enterprise Ethereum - [Hyperledger Besu](https://www.hyperledger.org/use/besu) & [Quorum](https://github.com/ConsenSys/quorum) + - [Corda](https://www.corda.net/) *(work in progress)* - Developer friendly event-driven REST & WebSocket APIs - For building multi-party business applications that solve real enterprise use cases - Digital assets - - Tokens and NFTs ready for use, and easy to extend + customize + - Tokens and NFTs ready for use, with indexed transaction history, and easy extension/customization - On-chain/off-chain orchestration - Enterprise data flows backed by blockchain, with secure off-chain transfer of private docs+data -- Microservice architecture, for docker deployment + - Pluggable private data exchange / messaging (inc. [HTTPS + Mutual TLS](https://github.com/hyperledger/firefly-dataexchange-https)) +- Identity, data format, and interface distribution + - Broadcast data schema, proven identity, and on-chain logic integration APIs across the network + - Pluggable data distribution network with batch optimization (inc. [IPFS](https://ipfs.io/)) + - *Pluggable DIDs for identity and multi-protocol on-chain interface definition are work in progress* +- Microservice architecture, optimized for docker deployment - Fully pluggable architecture, embracing multiple runtime technologies (Go, Node.js, Java etc.) - Built by developers for developers - Ready to go in minutes, with a CLI, built-in UI explorer, OpenAPI spec, and samples @@ -48,7 +55,66 @@ Or you can check out the [latest API here](https://hyperledger.github.io/firefly https://hyperledger.github.io/firefly -## Components +## Multi-party Systems + +Hyperledger Firefly is an implementation of a multi-party system. + +![Multi-party System](./images/multi_party_systems.png) + +Multi-party systems have the potential to unlock the next wave of digitization in core transaction processing systems. They combine the best features of the existing secure data exchange models for API/WebService/Messaging integration of business data/processes today, with the new technologies of the blockchain revolution. + +Working within existing regulatory environments, and existing IT and data security governance frameworks, multi-party systems provide a secure gateway for organizations to participate securely in blockchain backed business ecosystems. + +They are the middleware tier for decentralized applications, which are fundamentally different to centralized/SaaS applications because they are hosted independently by each IT organization, and can be customized by each organization to their own IT landscape. These applications communicate through a mix of blockchain, and private data exchange, to execute multi-party transactions at scale - powered by revolutionary new programming constructs like digital assets. + +The next wave of business applications that build in a decentralized way on multi-party systems, can orchestrate data and business process flows across organizational boundaries. The integrity of the end-to-end transactions can be established throughout its lifecycle, rather than requiring complex handoff and compensation logic each time a new party performs its step. Yet the autonomy of each business and IT team is maintained in a way that could not be by pooling data and business logic in a 3rd party centralized business application. + +Blockchain and other advanced cryptography technologies like zero-knowledge proofs (ZKPs), and trusted execution environments (TEEs), are the core technologies that enable this new model of cross-organizational data flow. + +In an enterprise context these raw technologies are necessary, but not sufficient. Organizations need a comprehensive toolset at the boundary of their *existing core systems of record* to govern the flow of data out of their own secure IT infrastructure. +- To store the private data staged in canonical formats ready for exchange with other parties +- For retrieval of the state of transaction and data flows in-flight in the system +- To provide an audit record and reporting system for what has been shared so far +- Providing event-driven integration APIs fit for purpose to integrate to the core systems of record + +This all needs to be fast, secure and reliable. + +[Learn more in the Hyperledger FireFly Documentation](https://hyperledger.github.io/firefly/) + +## Event-driven programming model + +The core programming model of FireFly is event-driven: +- FireFly delivers data and actions from your application instance, reliably to on-chain logic and privately to other parties in the network +- FireFly receives data and actions from on-chain, and other parties in the network, correlates them, and once complete and verified delivers them to your application for processing + +For this reason FireFly has a pluggable database that keeps track of all those interactions. + +This database is *not intended to replace* your application database (apart from in early PoC scenarios). Instead it complements it. + +You process the events from the network as they happen, **including ones you submit** because they have to be ordered with other events in the network ([learn more](https://hyperledger.github.io/firefly/keyconcepts/multiparty_process_flow.html)). + +Then you update the indexed business objects in your own database, as a result of the ordered state changes that come from the network. At any point you can go back and retrieve the set of events that caused that update to your "latest" state, whether that's on-chain transaction events, digital asset transfers (Tokens/NFTs), private data transfers, or a combination. + +![FireFly Event-driven Programming API Model](images/event_driven_programming_model.png) + +## Learn more about Hyperledger FireFly Architecture + +- [YouTube Channel](https://www.youtube.com/playlist?list=PL0MZ85B_96CFVEdBNsHRoX_f15AJacZJD) + - Check out the architecture series +- [Architecture reference documentation](https://hyperledger.github.io/firefly/architecture/node_component_architecture.html) + - Still evolving, and open for feedback - let us know what you think [on Rocket Chat](https://chat.hyperledger.org/channel/firefly) +- [Tagged git issues](https://github.com/hyperledger/firefly/issues?q=is%3Aissue+is%3Aopen+label%3Aarchitecture) + - Watch out for a new formalized Feature Improvement Request (FIR) process coming soon + +## Hyperledger FireFly project status + +A number projects are actively building on Hyperledger FireFly today, and the current feature set and API is sufficient to build many decentralized applications. Some of the microservice components have matured through a number of years (including production adoption), others are new, and some areas are still evolving quickly and subject to flux in the APIs and feature set. + +Overall, the community is working hard towards a V1.0 release. + +A good reference for the scope of the V1.0 release is included in issue #117. You might be interested in getting involved. + +## Git repositories There are multiple Git repos making up the Hyperledger FireFly project, and this list is likely to grow as additional pluggable extensions come online in the community: @@ -62,27 +128,13 @@ list is likely to grow as additional pluggable extensions come online in the com - Hyperledger Fabric connector - in design phase, including collaboration with https://github.com/hyperledger/fabric-smart-client - FireFly Explorer UI - https://github.com/hyperledger/firefly-ui -## Multi-party Systems - -![Introducing FireFly](./images/intro_to_firefly_teaser.svg) - -## FireFly repos - -FireFly has a plugin based architecture design, with a microservice runtime footprint. -As such there are a number of repos, and the list will grow as the community evolves. - -But not to worry, one of those repos is a CLI designed to get you running with all the components you need in minutes! - - -> Note only the projects that are primarily built to support FireFly are listed here, not all -> of the ecosystem of projects that integrate underneath the plugins. See [below](#firefly-code-hierarchy) for -> more information on the landscape of plugins and components. +## Contributing -## Getting Started +Interested in contributing to the community? -Use the FireFly CLI for fast bootstrap: https://github.com/hyperledger/firefly-cli +Check out our [Contributor Guide](https://hyperledger.github.io/firefly/contributors/contributors.html), and **welcome!**. -## Navigating this repo +## Navigating this core repo Directories: @@ -93,7 +145,7 @@ Directories: [Full code layout here](#firefly-code-hierarchy) -## FireFly code hierarchy +## FireFly Core code hierarchy ``` ┌──────────┐ ┌───────────────┐ diff --git a/images/event_driven_programming_model.png b/images/event_driven_programming_model.png new file mode 100644 index 0000000000000000000000000000000000000000..3fea1fd08a51af98f2facbdea5ae6b053aa6c11c GIT binary patch literal 81454 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

    to3#hX)G9Dv!D@%Lj<(dkIK!|rSfSMCD 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 DhlIlD literal 0 HcmV?d00001 diff --git a/images/intro_to_firefly_teaser.svg b/images/intro_to_firefly_teaser.svg deleted file mode 100644 index 88c3b21f8a..0000000000 --- a/images/intro_to_firefly_teaser.svg +++ /dev/null @@ -1,2277 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/images/multi_party_systems.png b/images/multi_party_systems.png new file mode 100644 index 0000000000000000000000000000000000000000..17a008735fca1c8fcfcbfa6a59d1456eb51eb5d4 GIT binary patch literal 121096 zcmb@ucT`l{vo+f4Q4vH?M3i_?0m+gjD=0{oEU^V7C&?L9Kv0t83?ez_Ov4crBtw%V zwgOGgIrFMHzx&3x-?-y@_m8(d*vAI;T6?WpRkLQz>W?qvB?L4KTyr=w&afnb)FmE zuS23-$E)qC>{en0e>-(m&&J%odg&ZY0`Zu@P?`kyKZu{GvzO0qXYc>Li+du(6IlNk@)oX-=LH_>4V!wXWH~Uw3c({6@ zuE)vIet}MH{lP-6POT$Py`fs6u8!O}mbaWbC?i zuG?msnsMJ=J>=rDv$b6q%pYB@#E889NlZXMAYzWdJ?FMd`De8EkiHTG({YAL+{znSvu3w(uy8$g_j-oD=RoG4(99M@&5Kjc79tWysWIu zX~JdpSFu5R6svh(hFqV;CxPhr_`@-~?(wboYl-reFs=Q~S%p~6beqCu2~)bW-R_z8 z@$q?WXgEANN}=q$I)Ms$Il!!5;N#~fGdfhDlgr&4NWsT;|Nis_wtZz~Wp~2OdRh19 zw{L%TMy=IX7}?lPHoHZqrluk_4))fk%!dj*=F_9&jFkIXy}uQ~5*yBKZ=PKn8zsfX z)o=cYX=`i0ex0UU7>!?uY^XPA2|hVFkvn>S?#u>Rkv2B#?=D=FDUZPWETDtWk6=4abMOm;d_fDmi!7 z4(@$O==RxL<%kup$_YW-njH5I2sExr1Ru${&_l43|u`gb>im%E>jHo*bGDj<7y>P<6OcD6HlZj&C;Nl_?`!zc1wL9*#apHZMs2;wL-f3rV5b`|QJ1`MIB9XAHjQ&v(5!wx& zI{9kR%yxeoec9{x?s9ULeEITt!qnV+G+(RIZKc|HZ|x5$(IFVyDSV-Kx1y%Row3y92s;|M~AH83M(rs48IH$(O%z59|-G8;NP4MR}fkI=YlFv0I_~& z9M6*{Pq6jpA7(Hf?5=ukOiP)1y?F5=ot8^PL{~aZ%-?Z ^U-J|lApi=|^&1EZ~7 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%0DBlCt>pVpUVi?Q%kslWEAvz|f7YtR_;#FJomj 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

  1. Hq=Rb>vFr>Y=a2oFX*$2RxQtJGCK|Fqk0=^dhCFq zf!q%WTtPqe1K(Su%z+Z3n$zqCDLph+-V!z z4Z{4&T%^r-UK6ieKKe)MdnaQ>C5tg2v*1Xq-N-f_x}sNjn$XH7ZMy{N(vR3kb}%ps zuU~O`P8UYODFbJ*TjdFKtSde#ZS~Ezop0t+tRf;~jL);q5*Y_&I{c92zw<)rGu*s|bRf#GIi?`%X_QQl8{Lid6CioCJ!E+BP}*mQ9p{?G zS-l#CT?C4B*Lv!wEW>SCbBpBRfGWk!+us{&dv zHFv>s_)9uY!@TbWV43(2zsL9Xt6*e|4EzR|aZN62Zno+?=<2=Kg6=uS&gHr|&26W` zO)4F8mE}Ln)PNTY*VmMyf5#n{IJCyz7WRdE>-lS4k5zPVx&DGsda!_7N4G*e_nLIrmWvj9!!ZzWrjp^Zn=g$37=0oTE zHr(p`#mtx44x5*EgRH58Wdj%F#mGycfdwFc2nDXI zP!~5ZhQ-l}E1xWNWf#4eRn2vYQj__{|8Lto397h$-S_NZ8b;X0a~NMkeHaR}wNnXY zuo*!|qkD>udVyYU_p4vjl{2H)o_t|f{9Ti1{nbOs&H)}1=?oHb@t-T5%DB|RFL6vc z`T3PJ*=93)Wcl1j8^H7o1Auh<81GTQCa1yW%CCe?%ymKFh8mIX1^ybeumo#1%!1)n z{cx;rFX^%0I)LbS0rOY=6L72|hyo-7@Xb+U{c5kMRY@DQUsNu3S(xH!u2p*)oJ0(p zPE=nA5A*g@%87yh=D}f|oQCSQZdH0f*SkIp8ft{zcXs3 zeT9s{{|SKZJotlInApb9ag&UrJd4MfKHayxAul`3i|ca#$)=ngd&r7ItLDrMp! zbHAI@4_9Cm`C_*)Ra(|x>U%6f=!xi0i+&pP{`Q_Z%=5ePtHKx>JmNkzVeJ=3P0a|mG>NqHZgs;* z^!B9|W!#ihLQbY{)O?}128}T&53;qV@$9@9)d175f^e_Yb3b%*M`yepMYmoZ)(4c< zEp_e!2d-QSXD9DpwNV|^6VxrTZwC>PAf$lZ)Rb(zc zf>PfpVSv{3mliQ39wk}v)MqaD1^S6V;bV?kr`T zWLLQ#KF=ZEZ96Lpu8g0o-1fqGzX4_Y(MZu^$Km?TY*@IcVTIXZ;!~L_n0Kjw8?v0$ z-^aSN?r)HHLqdc6b^*-n$>ff{UJ6BarT#7S=xfhe7B1<9rng4&Xe?@*el3OW`r|3b zvluXQ!X-4QbaLvd`P(_|&%??xk$*uUBSN%bUDI!pl#dUgSG<_D=j&%Epgg#}8^BGk zzJoq2>nG){p|)kasSx)TckAttH|4)4M{xY|L+B&G{lvtKURs7CEi#{mU|bvF>cu3E zRARvMxrO;)a+=v6>9<`mL9I&JIpO6Sgoj{vC-Y^V8pDE=*o zY({XJ&z>_@gbjX5A^dC3vpb(Y?A2+?oXc&57|LQLbhKdli$ujvV+h}z5z>Xdtj+}! z#OBlrX(~n}MH;ZZ(u>H?ZMs=Dv#6|qD)TGwDQw$vH9%0FIV;1V4^KXfC)#k^V z8(~$ADY7P7Yb0VSwH68mpoTCFg=1Tf=hT^vv>cn7TvNq%s}4K)EKhZljns&XBrX~4 zt(Zz5=TSI1&B|*2dNcJ{_DqW`V_Zx7wUt2q3%FYFALpM|+re(ZdUGOA>3R_w%~c-Y zUzPobTPZ}LnUZHJ4U>MgAJsLk?$i~n)p<f^0;YPtn=a8qX<1TlZ?3 z@Z(4#)CI^Ky~!P&^HV-IoCya}!I4t6Di%f`2V_sjWquLjbqgQoAZ zt=ZWV6g%!OvIA)Xk951lcky$Nr%$^J?dPkr;GSV9kR%aCQbs{$``a@`mNM%nlT@XX z-Pm*rxKv^aSt9edhXgt0O1t|fd+IaG5Drbgx)>?4Fduo_=W%IFMSE}<d>jQ-(Io30CggrB^O~!yAc3Nf+R?3OaT%^-)J>kI89xO+T`?V zrvma~{Z45+LDDCURoUTJ9R_1|p*?5gom|&jGl&>(JP#oQ3Wof(b;;m3zt8dwkEum| z3`Cgt$JzR(;U|M97|)WVh4P)}P%DzRXSnm6S0kU@8Xugjj8L#)lLwfoDYc}X%jXQO zLP_y4R3hKpFf?ug+kCwd9yVjvD#FTs=6K&B`gb2^m1q^spZ5i_bI!=>vz*>pGGShG z?g{W%JoCbB454(@kFYqM~U>5ApEoIvg{veE0 z*c<87Q7-*r`564>0s<7dEbsdCPS;$eF{}j(Uz~_qH(l^#qMuulbPJyt!|NKKN->rb zneNwZ<;Fj9?5+0F&PW>Bs4SEB&`Bv1xiZ}8TWJ0%K1IqXSi?By@xLf(HHN5u(*pnc zTy;&y#`5jBG-&2qf`nCr0E=QL+Pkw2GBgGu2<6Skn<^!tb=Y(%<*}27G%rkl325{2 zH7tKIS&P3pc}`bv+iPA&-iD@Hm+Kdi=>}=IHBQ5kKT?>BXb2Jd-`a*K8@>RR8$h$cwDs$BqtIS0DeDc ztx3wgd?V!_(nUi5*-L=Ug#QBm9l-dMOp?Nehwe5JgMW<{ zfXva#i>ylLK>C;a%+G?Qs6Gu|eClwM>Y&b87h2#=$NuFQ1`%ONt8*ErNY}9F;LReS z0|r|vJ=;Y*zkSPtCTX3p?UPgHmP{8vL}Xu(h?)d$xcbbv#^*RwiW!J`PaK|><`Y`T zM3ZgVPQ-Lv_peFHzX-vxZ8_tR_0oh=^56DOhQXlx_%`aEMma1d`!ZrC3FoeM>jzG< z0nSh9!uZN(>mj^i>FO1Q3&gR7#aSo9txtjuN>e-akt!5FM*j%%%!G*AdvkH`|Cw}FHQkso4p z^sA@I6>(LwijNUSyft})Gv)0<-PXx7dN}Mpnf9-vI{i zjdO3~I1}BnN--)uBk1retRv|x7VxULM>>!)YQyUIXZGp=u}DXm31G0O_mS);Ckza-*9-ID|*c z*fW#Q((2D=yBWcLRa$Wv*X-dIbgn&V$_wonL#=M~pD_j}@1f(jj2kwYXcsoS5+*|A z{)ODh3;i>7wWPP`OUd_3CY>+%?`5s!R?r$3DC``x)4Ei>dxST!_qRe4EsR1YaE(8A zO?~Q2Kr65^(O1})E#-BxH=6O(YJc0s15aY9L&K@n(B|>@!)jEYis6<11DyhTui= zEDC;#@^4IxJ*$4{Fb9x2xB7T=v!*XZax3doD*5X2I<&Y0zk2B83$(1X!<^5lS6>HUjTi@q8u^sxoheZzg5X~LS>a=8HZ=+7#?KWuVB0-qTnQ)JB@i)Kj(Mzp z>5R&7>bG*IAKCxZ`4c^LeV^E4f}{)ki_A4MW_fq0)XK|SRfJPJIfZ@;7Q-)jd{^!T ze>&DuG>`Jq)J;9K0T^9`_YW2M@AH2(_&<;NzZ?9&{?Cc}TWKlL XXH@xBduZmsM~^ Date: Tue, 12 Oct 2021 15:12:06 -0400 Subject: [PATCH 3/3] Update FabConnect link Signed-off-by: Peter Broadhurst --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fcefdd0490..db8212f900 100644 --- a/README.md +++ b/README.md @@ -123,9 +123,9 @@ list is likely to grow as additional pluggable extensions come online in the com - Core (this repo) - https://github.com/hyperledger/firefly - Sample applications - https://github.com/hyperledger/firefly-samples - HTTPS Data Exchange - https://github.com/hyperledger/firefly-dataexchange-https -- Ethereum (Hyperledger Besu / Quorum) connector: https://github.com/hyperledger/firefly-ethconnect +- Hyperledger Fabric connector - https://github.com/hyperledger/firefly-fabconnect +- Ethereum (Hyperledger Besu / Quorum) connector - https://github.com/hyperledger/firefly-ethconnect - Corda connector: https://github.com/hyperledger/firefly-cordaconnect - contributed from Kaleido generation 1 - porting to generation 2 -- Hyperledger Fabric connector - in design phase, including collaboration with https://github.com/hyperledger/fabric-smart-client - FireFly Explorer UI - https://github.com/hyperledger/firefly-ui ## Contributing