{"id":21850488,"url":"https://github.com/circlefin/chainmail","last_synced_at":"2025-10-31T14:30:47.775Z","repository":{"id":224763571,"uuid":"745361347","full_name":"circlefin/chainmail","owner":"circlefin","description":"Chainmail: authenticated email using the blockchain.","archived":false,"fork":false,"pushed_at":"2024-07-06T01:44:59.000Z","size":67,"stargazers_count":7,"open_issues_count":8,"forks_count":6,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-28T03:51:09.024Z","etag":null,"topics":["email","pgp","phishing","research"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/circlefin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-01-19T07:02:22.000Z","updated_at":"2025-03-03T14:22:14.000Z","dependencies_parsed_at":"2024-04-18T17:39:41.809Z","dependency_job_id":"ead29995-0fd0-4c66-82b1-5261267f0028","html_url":"https://github.com/circlefin/chainmail","commit_stats":null,"previous_names":["circlefin/chainmail"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fchainmail","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fchainmail/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fchainmail/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fchainmail/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/circlefin","download_url":"https://codeload.github.com/circlefin/chainmail/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248903564,"owners_count":21180828,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["email","pgp","phishing","research"],"created_at":"2024-11-28T00:17:48.562Z","updated_at":"2025-10-31T14:30:47.739Z","avatar_url":"https://github.com/circlefin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Chainmail\nProtecting email recipients using the blockchain.\n\n## License\nThis work is licensed under Apache 2.0.\n\n`SPDX-License-Identifier: Apache-2.0`\n\n## Setup\n\n### Install GnuPG\nInstall GPG and GPA https://www.gnupg.org/.\n\nFor Mac:\n```\nbrew install GnuPG\nbrew install gpa\n```\n\n### Install Foundry and Anvil\nYou will need Foundry to make `cast send` RPC calls to the Ethereum testchain. You\nwill also need to use anvil if you want to have a local test node.\n```\ncurl -L https://foundry.paradigm.xyz | bash\nfoundryup\n```\n\n### Configure Virtual Environment\nTo create a virtual environment, execute the following commands\n```\n# Create virtual environment .venv in local dir\npython3 -m venv ./.venv\n\n# start virtual environment\nsource ./.venv/bin/activate\n\n# Install packages (this will take a few minutes).\npip install -r requirements.txt\n```\n\nTo exit the virtual environment\n```\ndeactivate\n```\n\nTo restart the virtual environment\n```\nsource ./.venv/bin/activate\n```\n\n### (Optional) Generate your own PGP key\nThe project comes with a default PGP key in `test_data/alice_private_key.asc` that will be automatically installed\nwhen you run `register-for-demo.py`. You can generate your own key\nusing GPG that you installed earlier. Update the `sender` field in `config.yaml` with the email address and\nfingerprint associated with the key. Note: PGP format automatically inserts the key's username and email address into\nevery signature.\n\n### (Optional) Install Mailvelope\nMailvelope can sign emails with PGP and automatically verifies PGP signed messages.\n\nAdd Mailvelope to Google Chrome https://chrome.google.com/webstore/detail/mailvelope/kajibbejlbohfaggdiogboambcijhkke\n\nAdd a PGP key for signing here: chrome-extension://kajibbejlbohfaggdiogboambcijhkke/app/app.html#/settings/general\n\nWhen you compose a new email in the browser, a Mailvelope red logo will appear in the corner of the New Email window. Click it to send a secure email.\n\n## Run\nOverview of all the steps, with more details provided above/below.\n\nTo send emails:\n1. Open a fresh terminal window to run the web server. Activate the virtual environment and then run `python runwebsite.py`.\n1. Open your browser to `http://127.0.0.1:5000`\n1. There is a form at the bottom of the page for sending emails. Since this is a demo, no email will actually be sent.\n   Instead, the signed email text will appear in the side panel.\n\nTo verify emails using an anvil node\n1. (Default) The configuration file `config.yaml` is set to use anvil by default. If you have modified the configuration\n file, you need to set `local_key_file: './test_data/anvil_keys.yaml'`.\n1. Open a separate window, activate the virtual environment, and run the script `python register-for-demo.py`. This will deploy a fresh contract and register\n   the email sender in the `config.yaml` file and the sender address in `test_data/anvil_keys.yaml`.\n1. Open a fresh terminal window to start the web server. Activate the virtual environment and then run `python runwebsite.py`.\n1. Open your browser to `http://127.0.0.1:5000`. You can now enter emails to verify.\n\nTo verify emails using the deployed testnet contract\n1. Follow the instructions below to connect to Ethereum using an Infura RPC key.\n1. Open a fresh terminal window to start the web server. Activate the virtual environment and then run `python runwebsite.py`.\n1. Open your browser to `http://127.0.0.1:5000`. You can now enter emails to verify.\n\n### To run the webserver\nIf you are using anvil as your network, run `anvil` in a separate window.\n\nActivate your virtual environment and run `python runwebsite.py`\n\nOpen a browser window to http://127.0.0.1:5000\n\nEnter the raw text of a message sent by Chainmail into the textarea and click on the `Verify` button.\nThe send email form signs the email message and displays the result.\n\n### Connect to anvil\nYou can run a local anvil node to test Chainmail. Make sure that the config file `config.yaml` has the line:\n```\nlocal_key_file: './test_data/anvil_keys.yaml'\n```\nThe file `./test_data/anvil_keys.yaml` is configured with\nthe correct `rpc_url` and an `owner` and `sender` anvil account. These are all default keys that ship with every\nanvil.\n\nIn a separate window, execute the command `anvil`. This will start a fresh instance of local anvil node.\nYou will need to deploy a fresh copy of the `Chainmail.sol` contract each time you start `anvil`. Start the\nvirtual environment and run `python register-for-demo.py`. You can also deploy and interact with the\ncontract on the commandline using `python chainlink.py`.\n\n## Connect to Ethereum using Infura\nTo connect to Ethereum, you need to create a `local_test_data/keys.yaml` file with\nprivate key information and an RPC URL.\n\nMake a copy of `test_data/anvil_keys.yaml` and rename it something like `local_test_data/keys.yaml`. Configure\n`config.yaml` to point to this new file:\n```\n# config.yaml\n\nlocal_key_file: './local_test_data/keys.yaml'\n```\n\nYou will need to do the following to your new key file:\n- (Optional) Obtain Ethereum accounts for contract owner and message sender. Set the owner and sender information\n  in the `keys.yaml` file using funded accounts. You can skip this step if you don't plan to deploy a contract or register\n  email addresses. Email verificatin does not require funded accounts.\n- Obtain an Infura API key by registering here:  https://app.infura.io/register\n- Set your `rpc_url` in the `keys.yaml` file to point at the appropriate network and include an Infura API key.\n  The URL will look something like `rpc_url: 'https://goerli.infura.io/v3/\u003ctoken\u003e'\n  `\n- Set the contract address in the file `.chainmail_env`. We currently have a contract on the Goerli test network at\n  `0x1866053Ec573dC3a50EB4A27f3836d867c622D41` that you can\n  view at https://goerli.etherscan.io/address/0x1866053ec573dc3a50eb4a27f3836d867c622d41\n\n```\n# .chainmail_env\n\ncontract_address: '0x1866053Ec573dC3a50EB4A27f3836d867c622D41'\n```\n\n### Command Line Interface\nThe `chainlink.py` script interacts with an Ethereum network. Use the configuration file `config.yaml` to configure your\nconnection to use anvil, testnet, or mainnet.\n\nActivate the virtual environment and run `python chainlink.py` to get the exact usage instructions. You can\n- Deploy an instance of the Chainmail contract.\n- Register an email address, fingerprint, and sender Ethereum address.\n- Register an email message.\n- Verify a fingerprint corresponds to an email address.\n- Verify an email message has been registered.\n\nThere is a script `python register-for-demo.py` that will automatically deploy a contract, register the email sender in\n`config.yaml` and the email in `test_data/good_sent_email.asc`.\n\n### Test Files\nThe directory `test_data` has some test email messages. You can use them as test data on the command\nline with `python chainlink.py` or copy+paste into the web browser for verification (don't forget to activate your virtual environment).\n- `good_sent_email.asc`. This email is signed using the default PGP fingerprint and the script `register-for-demo.py` will\n  register both the PGP fingerprint and the contents of the email.\n- `ok_sent_email.asc`. This email has a valid PGP signature and `register-for-demo.py` will register the signer PGP key.\n  However, the text of the message is not registered.\n- `unregistered_signed_email.asc`. This email has a valid PGP signature, however the PGP fingerprint is not registered.\n- `bad_sent_email.asc`. This email has an invalid PGP signature.\n\n### Generate mainnet/testnet address ###\nYou need an Ethereum  address with ETH to register keys. The following command line command will generate an Ethereum \naccount and private key. Activate your virtual environment and execute:\n```\npython3 -c \"from web3 import Web3; w3 = Web3(); acc = w3.eth.account.create(); print(f'private key={w3.to_hex(acc._private_key)}, account={acc.address}')\"\n```\n\nStore the information in `local_test_data/keys.yaml` in the format:\n```\ntestnet_account:\n  private key: # private key goes here\n  address: 0x4a7b50811D0ADbE2A1AB6218eA4a5EC0a47c9DCb\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcirclefin%2Fchainmail","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcirclefin%2Fchainmail","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcirclefin%2Fchainmail/lists"}