# Project export: De-UNOS

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2024
- Tagline: Decentralizing UNOS' organ donation and transplant system
- Devpost: https://devpost.com/software/de-unos
- GitHub: https://github.com/KennethRuan/treehacks24.git
- Video: https://www.youtube.com/embed/2lBRd62FVdM?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 4 GitHub contributor(s) — Roselyn Huynh (21 commits), Evin Li (15 commits), Kenneth Ruan (11 commits), tia-kun (4 commits)

## Devpost submission (written by the team)

### Inspiration

This project was inspired partially by Grey's Anatomy ✨👩‍⚕️, but mostly by stories we've heard from friends studying medicine and by the incredible amount of research recently published in this field. Despite the life-saving potential of organ transplants, we learned that the process is often plagued by issues such as lack of transparency, unfair access, susceptibility to cyberattacks, and the existence of a black market. De-UNOS is a web app project that uses a Hyperledger Fabric blockchain network to decentralize the way that UNOS currently manages organ donation and transplants in the United States in attempts to reduce system inefficiencies. We used Hyperledger Fabric because it allows for a permissioned blockchain which means not EVERYONE in the general public will have access to this data - only doctors and patients, allowing for a more secure, transparent, and equitable solution. Background As hospitals embrace the digital age and electronic patient healthcare records become prevalent, there is a need to manage this ever-growing amount of sensitive data, paying maximum attention to security and digital privacy. A great effort has been made by UNOS to design a transparent and fair organ allocation system with a centralized system and centralized data storage. The problem however, is that centralized database systems are far more prone to cyberattacks and hacking, like the last ransomware attack on COVID-19 vaccination registration portal in 2021 in Lazio (an Italian region). This is where blockchain has been proposed by many researchers as a solution (https://www.ncbi.nlm.nih.gov/pmc/articles/PMC9945518/pdf/ti-36-10800.pdf).

### What it does

The app works as follows. When doctors login to the web app, they will have access to the entire list of transplant patients as well as donors that have recently become available. Doctors can add patients and donors onto the list by pulling from their electronic health record (EHR) and current bedside vitals using the Terra API. Patients can then view their current status on the transplant list by going to their profile. To maintain confidentiality and respect HIPAA, all patient/donor names are redacted when presented on the app and encrypted on the blockchain. When a new patient/donor or transplant goes through in the software, a new block is created on the chain and the distributed ledger is updated for everyone. This allows for guaranteed transparency, trustworthiness, and auditability by any node in the network.

### How we built it

We built the frontend of our web app using Reflex, React Leaflet, and Python (yes, Python) with all our designs and wireframes prototyped in Figma. For our backend, we used Hyperledger Fabric to build out a local test network for our blockchain, Terra API to push real-time IoT patient vitals through our system, and Node.js to integrate everything with our frontend UI. To automate the UNOS donor-to-patient matching process, we developed smart contracts using Solidity based on UNOS' existing criteria (e.g., geographic proximity, blood type, human leukocyte antigen (HLA) match, medical urgency, pediatric priority, etc).

### Challenges we ran into

Setting up the blockchain framework (had multiple near breakdowns at 4am sunday) Wrapping Leaflet.js in Reflex which is Python frontend framework... a big shoutout to previous devs and the CEO for supporting us through on Github issues Dependencies being finnicky Sleep loss

### Accomplishments we're proud of

Super proud of all our teammates for forgoing their old, familiar tech stacks and learning something COMPLETELY new. It was all of our first times using Terra API, Reflex, and Blockchain, and we’re proud that we were able to piece it all together at the very end :))

### What's next

More regional and national research to inform viability of project More research into blockchain so we can optimize our backend Improved, more nuanced matching algorithm with a wider range of medical criteria

## README (from the GitHub repository)

## De-UNOS Organ Donation and Transplant System
A decentralized hyperledger blockchain approach to managing organ donations and transplants.


![alt text](assets/image3.png)


## Detected evidence (automated analysis)

Indexed codebase: 93 recognized source files, 433 KB.
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- Docker (technology) — claimed on Devpost, not found in the code
- Node.js (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (120 of 121)

```
backend/.gitignore
backend/nodemon.json
backend/package.json
backend/src/app.ts
backend/src/chaincode.ts
backend/src/gateway.ts
backend/tsconfig.json
frontend/.gitignore
frontend/.web/package.json
frontend/.web/pages/_app.js
frontend/.web/reflex.json
frontend/.web/utils/context.js
frontend/assets/fonts/montserrat.css
frontend/assets/fonts/MontserratBold.otf
frontend/assets/fonts/MontserratSemibold.otf
frontend/frontend/__init__.py
frontend/frontend/components/header.py
frontend/frontend/components/internal_template.py
frontend/frontend/components/nav_bar.py
frontend/frontend/components/nav_item.py
frontend/frontend/components/sidebar.py
frontend/frontend/components/transitions.py
frontend/frontend/data/organ_data.py
frontend/frontend/data/organ.json
frontend/frontend/data/patient_data.json
frontend/frontend/data/patient_data.py
frontend/frontend/frontend.py
frontend/frontend/pages/dashboard.py
frontend/frontend/pages/data_table.py
frontend/frontend/pages/landing.py
frontend/frontend/pages/login.py
frontend/frontend/pages/register_donor.py
frontend/frontend/pages/register_patient.py
frontend/frontend/terra/API.py
frontend/package.json
frontend/patient_data.json
frontend/requirements.txt
frontend/rxconfig.py
README.md
test-network/.gitignore
test-network/addOrg3/addOrg3.sh
test-network/addOrg3/ccp-generate.sh
test-network/addOrg3/ccp-template.json
test-network/addOrg3/ccp-template.yaml
test-network/addOrg3/compose/compose-ca-org3.yaml
test-network/addOrg3/compose/compose-couch-org3.yaml
test-network/addOrg3/compose/compose-org3.yaml
test-network/addOrg3/compose/docker/docker-compose-ca-org3.yaml
test-network/addOrg3/compose/docker/docker-compose-couch-org3.yaml
test-network/addOrg3/compose/docker/docker-compose-org3.yaml
test-network/addOrg3/compose/docker/peercfg/core.yaml
test-network/addOrg3/compose/podman/peercfg/core.yaml
test-network/addOrg3/compose/podman/podman-compose-ca-org3.yaml
test-network/addOrg3/compose/podman/podman-compose-couch-org3.yaml
test-network/addOrg3/compose/podman/podman-compose-org3.yaml
test-network/addOrg3/configtx.yaml
test-network/addOrg3/fabric-ca/org3/fabric-ca-server-config.yaml
test-network/addOrg3/fabric-ca/registerEnroll.sh
test-network/addOrg3/org3-crypto.yaml
test-network/addOrg3/README.md
test-network/bft-config/configtx.yaml
test-network/CHAINCODE_AS_A_SERVICE_TUTORIAL.md
test-network/compose/compose-bft-test-net.yaml
test-network/compose/compose-ca.yaml
test-network/compose/compose-couch.yaml
test-network/compose/compose-test-net.yaml
test-network/compose/docker/docker-compose-bft-test-net.yaml
test-network/compose/docker/docker-compose-ca.yaml
test-network/compose/docker/docker-compose-couch.yaml
test-network/compose/docker/docker-compose-test-net.yaml
test-network/compose/docker/peercfg/core.yaml
test-network/compose/podman/peercfg/core.yaml
test-network/compose/podman/podman-compose-ca.yaml
test-network/compose/podman/podman-compose-couch.yaml
test-network/compose/podman/podman-compose-test-net.yaml
test-network/configtx/configtx.yaml
test-network/monitordocker.sh
test-network/network.config
test-network/network.sh
test-network/organizations/ccp-generate.sh
test-network/organizations/ccp-template.json
test-network/organizations/ccp-template.yaml
test-network/organizations/cfssl/admin-csr-template.json
test-network/organizations/cfssl/ca-orderer.json
test-network/organizations/cfssl/ca-peer.json
test-network/organizations/cfssl/cert-signing-config.json
test-network/organizations/cfssl/client-csr-template.json
test-network/organizations/cfssl/orderer-csr-template.json
test-network/organizations/cfssl/peer-csr-template.json
test-network/organizations/cfssl/registerEnroll.sh
test-network/organizations/cryptogen/crypto-config-orderer.yaml
test-network/organizations/cryptogen/crypto-config-org1.yaml
test-network/organizations/cryptogen/crypto-config-org2.yaml
test-network/organizations/fabric-ca/registerEnroll.sh
test-network/prometheus-grafana/docker-compose.yaml
test-network/prometheus-grafana/grafana_db/grafana.db
test-network/prometheus-grafana/grafana/config.monitoring
test-network/prometheus-grafana/grafana/provisioning/dashboards/dashboard.yml
test-network/prometheus-grafana/grafana/provisioning/dashboards/hlf-performances.json
test-network/prometheus-grafana/grafana/provisioning/datasources/datasource.yml
test-network/prometheus-grafana/prometheus/prometheus.yml
test-network/prometheus-grafana/README.md
test-network/README.md
test-network/scripts/add_new_orderer_to_config.py
test-network/scripts/ccutils.sh
test-network/scripts/configUpdate.sh
test-network/scripts/createChannel.sh
test-network/scripts/deployCC.sh
test-network/scripts/deployCCAAS.sh
test-network/scripts/envVar.sh
test-network/scripts/orderer.sh
test-network/scripts/orderer2.sh
test-network/scripts/orderer3.sh
test-network/scripts/orderer4.sh
test-network/scripts/org3-scripts/joinChannel.sh
test-network/scripts/org3-scripts/updateChannelConfig.sh
test-network/scripts/packageCC.sh
test-network/scripts/pkgcc.sh
test-network/scripts/setAnchorPeer.sh
test-network/scripts/utils.sh
[1 more files omitted for size]
```

### Dependencies

- backend/package.json: @hyperledger/fabric-gateway@^1.4.0, @types/express@^4.17.21, @types/node@^20.11.19, @types/uuid@^9.0.8, express@^4.18.2, nodemon@^3.0.3, ts-node@^10.9.2, typescript@^5.3.3, uuid@^9.0.1
- frontend/.web/package.json: @chakra-ui/react@2.6.1, @chakra-ui/system@2.5.7, @emotion/react@^11.11.1, @radix-ui/react-form@^0.0.3, @radix-ui/themes@^2.0.0, autoprefixer@10.4.14, axios@1.4.0, framer-motion@10.16.4, gridjs@6.0.6, gridjs-react@6.0.1, json5@2.2.3, leaflet@^1.9.4, lucide-react@0.314.0, next@14.0.1, next-sitemap@4.1.8, next-themes@0.2.0, postcss@8.4.31, react@18.2.0, react-dom@18.2.0, react-leaflet@^4.2.1, silly@^0.2.0, socket.io-client@4.6.1, tailwindcss@3.3.2, universal-cookie@4.0.4
- frontend/package.json: leaflet@^1.9.4, react@^18.2.0, react-leaflet@^4.2.1
- frontend/requirements.txt: argparse, datetime, reflex@==0.4.0, requests, terra-python

### Recent commits (newest first)

- Update README.md
- Merge branch 'main' of https://github.com/KennethRuan/treehacks24
- updated readme
- Merge branch 'main' of https://github.com/KennethRuan/treehacks24
- panik
- page title deunos
- CAPITALIZZE UNOS
- Merge pull request #5 from KennethRuan/frontend-3
- WHAT ARE THESE CHANGES
- remove unused
- Merge branch 'main' into frontend-3
- Add matching modal
- Merge pull request #4 from KennethRuan/dashboard
- merged main
- Merge branch 'main' of https://github.com/KennethRuan/treehacks24
- added patients onto OSM map
- Update README.md
- Update README.md
- Create README.md
- Fixed up chain code

## Key source files (fetched from GitHub, selected and truncated for size)

### test-network/CHAINCODE_AS_A_SERVICE_TUTORIAL.md

```markdown
# Running Chaincode as Service with the Test Network

The chaincode-as-a-service feature is a very useful and practical way to run 'Smart Contracts'. Traditionally the Fabric Peer has taken on the role of orchestrating the complete lifecycle of the chaincode. It required access to the Docker Daemon to create images, and start containers. Java, Node.js and Go chaincode frameworks were explicitly known to the peer including how they should be built and started.

As a result this makes it very hard to deploy into Kubernetes (K8S) style environments, or to run in any form of debug mode. Additionally, the code is being rebuilt by the peer therefore there is some degree of uncertainty about what dependencies have been pulled in.

Chaincode-as-service requires you to orchestrate the build and deployment phase yourself. Whilst this is an additional step, it gives control back. The Peer still requires a 'chaincode package' to be installed. In this case this doesn't contain code, but the information about where the chaincode is hosted. (Hostname,Port,TLS config etc)

## Fabric v2.4.1 Improvements

We need to use the latest 2.4.1 release as this contains some improvements to make this process easier. The core functionality is available in earlier releases but requires more configuration.

- The docker image for the peer contains a builder for chaincode-as-a-service preconfigured. This is named 'ccaasbuilder'. This removes the need to build your own external builder and repackage and configure the peer
- The `ccaasbuilder` applications are included in the binary tgz archive download for use in other circumstances. The `sampleconfig/core.yaml` is updated as well to refer to 'ccaasbuilder'
- The 2.4.1 Java Chaincode release has been updated to remove the need to write a custom bootstrap main class, similar  to the Node.js Chaincode. It is intended that this will be added to the go chaincode as well.

## End-to-end with the the test-network

The `test-network` and some of the chaincodes have been updated to support running chaincode-as-a-service. The commands below assume that you've got the latest fabric-samples cloned, along with the latest Fabric docker images.

It's useful to have two terminal windows open, one for starting the Fabric Network, and a second for monitoring all the docker containers.

In your 'monitoring' window, run this to watch all activity from the all the docker containers on the `fabric_test` network; this will monitor all the docker containers that are added to the `fabric-test` network. The network is usually created by the `./network.sh up` command, so remember to delay running this until at least the network is created. It is possible to precreate the network with `docker network create fabric-test` if you wish.

```bash
# from the fabric-samples repo
./test-network/monitordocker.sh
```

In the 'Fabric Network' window, start the test network

```bash
cd test-network
./network.sh up createChannel -ca
```

You can run other variants of
[truncated — 10717 more characters]
```

### frontend/requirements.txt

```
reflex==0.4.0
terra-python
requests
datetime
argparse
```

### frontend/package.json

```
{
  "dependencies": {
    "leaflet": "^1.9.4",
    "react": "^18.2.0",
    "react-leaflet": "^4.2.1"
  }
}

```

### backend/package.json

```
{
  "name": "backend",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "npx nodemon"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@hyperledger/fabric-gateway": "^1.4.0",
    "express": "^4.18.2",
    "nodemon": "^3.0.3",
    "uuid": "^9.0.1"
  },
  "devDependencies": {
    "@types/express": "^4.17.21",
    "@types/node": "^20.11.19",
    "@types/uuid": "^9.0.8",
    "ts-node": "^10.9.2",
    "typescript": "^5.3.3"
  }
}

```

### frontend/.web/package.json

```
{
  "name": "reflex",
  "scripts": {
    "dev": "next dev",
    "export": "next build",
    "export-sitemap": "next build && next-sitemap",
    "prod": "next start"
  },
  "dependencies": {
    "@chakra-ui/react": "2.6.1",
    "@chakra-ui/system": "2.5.7",
    "@emotion/react": "^11.11.1",
    "@radix-ui/react-form": "^0.0.3",
    "@radix-ui/themes": "^2.0.0",
    "axios": "1.4.0",
    "framer-motion": "10.16.4",
    "gridjs": "6.0.6",
    "gridjs-react": "6.0.1",
    "json5": "2.2.3",
    "leaflet": "^1.9.4",
    "lucide-react": "0.314.0",
    "next": "14.0.1",
    "next-sitemap": "4.1.8",
    "next-themes": "0.2.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-leaflet": "^4.2.1",
    "silly": "^0.2.0",
    "socket.io-client": "4.6.1",
    "universal-cookie": "4.0.4"
  },
  "devDependencies": {
    "autoprefixer": "10.4.14",
    "postcss": "8.4.31",
    "tailwindcss": "3.3.2"
  }
}
```

### test-network/prometheus-grafana/docker-compose.yaml

```yaml
version: '3'

volumes:
    prometheus_data: {}
    grafana_storage: {}

services:
  prometheus:
    image: prom/prometheus:v2.32.1
    container_name: prometheus
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/usr/share/prometheus/console_libraries'
      - '--web.console.templates=/usr/share/prometheus/consoles'
    ports:
      - "9090:9090"
    
  grafana:
    image: grafana/grafana:8.3.4
    container_name: grafana
    user: "104"
    depends_on:
      - prometheus
    ports:
      - 3000:3000
    volumes:
      - grafana_storage:/var/lib/grafana
      - ./grafana/provisioning/:/etc/grafana/provisioning/
    env_file:
      - ./grafana/config.monitoring
    restart: always

  cadvisor:
    image: google/cadvisor:latest # gcr.io/cadvisor/cadvisor:latest for ios
    privileged: true
    container_name: cadvisor
    volumes:
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
      # - /cgroup:/cgroup:ro
    ports:
      - 8080:8080
    restart: always

  node-exporter:
    image: prom/node-exporter:v1.3.1
    container_name: node-exporter
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - --collector.filesystem.ignored-mount-points
      - "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)"
    ports:
      - 9100:9100
    restart: always

networks:
  default:
      external: true
      name: fabric_test

```

### backend/src/app.ts

```typescript
import express, { Request, Response } from "express";
import { connectToGateway } from "./gateway";
import {
  createDonation,
  createDonor,
  createPatient,
  getAllDonors,
  getAllPatients,
  getDonor,
  getPatient,
} from "./chaincode";
import { v4 as uuidv4 } from "uuid";

const app = express();
app.use(express.json());

const PORT = process.env.PORT || 3051;

app.listen(PORT, () => {
  console.log("Server Listening on PORT:", PORT);
});

// Hyperledger Fabric API Endpoints to hit SDK
app.post("/api/add-patient", async (req: Request, res: Response) => {
  res.send("Added Patient");
  const patientId = uuidv4();
  const {
    age,
    height,
    bloodType,
    pediatricStatus,
    location,
    meldScore,
    organNeeded,
    hlaB27Antibodies,
    terraWearableId,
  } = req.body;
  const { client, gateway, network, contract } = await connectToGateway();
  try {
    await createPatient(
      contract,
      patientId,
      age,
      bloodType,
      hlaB27Antibodies,
      height,
      location,
      meldScore,
      organNeeded,
      pediatricStatus,
      terraWearableId
    );
  } finally {
    gateway.close();
    client.close();
  }
});

app.get("/api/query-all-patients", async (req: Request, res: Response) => {
  const { client, gateway, network, contract } = await connectToGateway();
  try {
    // Asynchronous operation to get all patients
    const data = await getAllPatients(contract);
    console.log("Success", data);
    // Send the response here, after fetching the data successfully
    res.send(data);
  } catch (error) {
    // Handle any errors that occur during the fetch
    console.error("Failed to fetch patients", error);
    res.status(500).send("Failed to query all patients");
  } finally {
    // Close the gateway and client connections in the finally block
    gateway.close();
    client.close();
  }
});

app.get("/api/query-patient/:id", async (req: Request, res: Response) => {
  res.send("Query Patient");
  const patientId = req.params.id;
  const { client, gateway, network, contract } = await connectToGateway();
  try {
    const data = await getPatient(contract, patientId);
    console.log("Success", data);
    res.send(data);
  } finally {
    gateway.close();
    client.close();
  }
});

const findMatch = async (ctx: any, donor: any) => {
  let allPatients = await getAllPatients(ctx);
  console.log("Searching through patients", allPatients);
  console.log("Donor", donor);
  let matches = allPatients.filter(
    (patient) =>
      patient.organNeeded === donor.organ &&
      patient.bloodType === donor.bloodType &&
      // patient.age <= donor.age + 2 &&
      // patient.age >= donor.age - 2 &&
      patient.hlaB27Antibodies == donor.hlaB27AntigenTest
  );
  console.log("Matches", matches);
  if (matches.length == 0) {
    return null;
  }

  matches.forEach((patient) => {
    // const distanceScore = calculateDistanceScore(patient, donor);
    const distanceScore = 1;
    const meldScore = patient.meldScore;
    patient.totalScore = meldScore * 0.75 + distanceScore * 0.25;
  });

  // Sort based on total score, highest scores at top of list
  matches.sort((a, b) => b.totalScore - a.totalScore);

  const id = uuidv4();
  // createDonation(ctx, id, donor.id, matches[0].id);
  return matches[0];
};

function calculateDistanceScore(patient: any, donor: any) {
  const R = 6371; // Earth's radius in kilometers
  const lat1 = patient.latitude * (Math.PI / 180); // Convert degrees to radians
  const lat2 = donor.latitude * (Math.PI / 180);
  const deltaLat = (donor.latitude - patient.latitude) * (Math.PI / 180);
  const deltaLon = (donor.longitude - patient.longitude) * (Math.PI / 180);

  const a =
    Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
    Math.cos(lat1) *
      Math.cos(lat2) *
      Math.sin(deltaLon / 2) *
      Math.sin(deltaLon / 2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

  const distance = R * c; // Distance in kilometers
  return distance;
}

app.post("/api/add-donor", async (req: Request, res: Response) => {
  res.send("Added Donor");
  const donationId = uuidv4();
  const {
    organ,
    age,
    height,
    blood_type,
    pediatric_status,
    location,
    antigen_test,
  } = req.body;
  const { client, gateway, network, contract } = await connectToGateway();
  try {
    await createDonor(
      contract,
      donationId,
      organ,
      age,
      height,
      blood_type,
      pediatric_status,
      location,
      antigen_test
    );

    await findMatch(contract, {
      id: donationId,
      organ,
      age,
      height,
      bloodType: blood_type,
      pediatricStatus: pediatric_status,
      location,
      hlaB27AntigenTest: antigen_test,
    });
  } finally {
    gateway.close();
    client.close();
  }
});

app.get("/api/query-all-donors", async (req: Request, res: Response) => {
  res.send("Query All Donors");
  const { client, gateway, network, contract } = await connectToGateway();
  try {
    const data = await getAllDonors(contract);
    console.log("Success", data);
    res.send(data);
  } finally {
    gateway.close();
    client.close();
  }
});

app.get("/api/query-donor/:id", async (req: Request, res: Response) => {
  res.send("Query Donor");
  const donorId = req.params.id;
  const { client, gateway, network, contract } = await connectToGateway();
  try {
    const data = await getDonor(contract, donorId);
    console.log("Success", data);
    res.send(data);
  } finally {
    gateway.close();
    client.close();
  }
});

app.get("/api/add-donation", async (req: Request, res: Response) => {
  res.send("Added Donation");
  const { client, gateway, network, contract } = await connectToGateway();
  try {
    // await createDonation(contract, donationId, organ, age, height, bloodType, pediatricStatus, location, hlaB27AntigenTest);
  } finally {
    gateway.close();
    client.close();
  }
});

```

### frontend/rxconfig.py

```python
import reflex as rx

config = rx.Config(
    app_name="frontend",
    frontend_packages=["react-leaflet", "leaflet"]
)
```

### test-network/monitordocker.sh

```shell
#!/bin/bash

# This script uses the logspout and http stream tools to let you watch the docker containers
# in action.
#
# More information at https://github.com/gliderlabs/logspout/tree/master/httpstream

if [ -z "$1" ]; then
   DOCKER_NETWORK=fabric_test
else
   DOCKER_NETWORK="$1"
fi

if [ -z "$2" ]; then
   PORT=8000
else
   PORT="$2"
fi

echo Starting monitoring on all containers on the network ${DOCKER_NETWORK}

docker kill logspout 2> /dev/null 1>&2 || true
docker rm logspout 2> /dev/null 1>&2 || true

trap "docker kill logspout" SIGINT

docker run -d --rm --name="logspout" \
	--volume=/var/run/docker.sock:/var/run/docker.sock \
	--publish=127.0.0.1:${PORT}:80 \
	--network  ${DOCKER_NETWORK} \
	gliderlabs/logspout
sleep 3
curl http://127.0.0.1:${PORT}/logs

```

### test-network/setOrgEnv.sh

```shell
#!/bin/bash
#
# SPDX-License-Identifier: Apache-2.0




# default to using Org1
ORG=${1:-Org1}

# Exit on first error, print all commands.
set -e
set -o pipefail

# Where am I?
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"

ORDERER_CA=${DIR}/test-network/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem
PEER0_ORG1_CA=${DIR}/test-network/organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem
PEER0_ORG2_CA=${DIR}/test-network/organizations/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem
PEER0_ORG3_CA=${DIR}/test-network/organizations/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem


if [[ ${ORG,,} == "org1" || ${ORG,,} == "digibank" ]]; then

   CORE_PEER_LOCALMSPID=Org1MSP
   CORE_PEER_MSPCONFIGPATH=${DIR}/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
   CORE_PEER_ADDRESS=localhost:7051
   CORE_PEER_TLS_ROOTCERT_FILE=${DIR}/test-network/organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem

elif [[ ${ORG,,} == "org2" || ${ORG,,} == "magnetocorp" ]]; then

   CORE_PEER_LOCALMSPID=Org2MSP
   CORE_PEER_MSPCONFIGPATH=${DIR}/test-network/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
   CORE_PEER_ADDRESS=localhost:9051
   CORE_PEER_TLS_ROOTCERT_FILE=${DIR}/test-network/organizations/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem

else
   echo "Unknown \"$ORG\", please choose Org1/Digibank or Org2/Magnetocorp"
   echo "For example to get the environment variables to set upa Org2 shell environment run:  ./setOrgEnv.sh Org2"
   echo
   echo "This can be automated to set them as well with:"
   echo
   echo 'export $(./setOrgEnv.sh Org2 | xargs)'
   exit 1
fi

# output the variables that need to be set
echo "CORE_PEER_TLS_ENABLED=true"
echo "ORDERER_CA=${ORDERER_CA}"
echo "PEER0_ORG1_CA=${PEER0_ORG1_CA}"
echo "PEER0_ORG2_CA=${PEER0_ORG2_CA}"
echo "PEER0_ORG3_CA=${PEER0_ORG3_CA}"

echo "CORE_PEER_MSPCONFIGPATH=${CORE_PEER_MSPCONFIGPATH}"
echo "CORE_PEER_ADDRESS=${CORE_PEER_ADDRESS}"
echo "CORE_PEER_TLS_ROOTCERT_FILE=${CORE_PEER_TLS_ROOTCERT_FILE}"

echo "CORE_PEER_LOCALMSPID=${CORE_PEER_LOCALMSPID}"

```

[82 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]