diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..759e5e9
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "C_Cpp.errorSquiggles": "Disabled"
+}
diff --git a/Office Door/.pio/build/esp32dev/idedata.json b/Office Door/.pio/build/esp32dev/idedata.json
new file mode 100644
index 0000000..09d7761
--- /dev/null
+++ b/Office Door/.pio/build/esp32dev/idedata.json
@@ -0,0 +1 @@
+{"env_name": "esp32dev", "libsource_dirs": ["/home/developer/Web3E-Application/Office Door/lib", "/home/developer/Web3E-Application/Office Door/.pio/libdeps/esp32dev", "/home/developer/.platformio/lib", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries"], "defines": ["PLATFORMIO=50200", "ARDUINO_ESP32_DEV", "ESP32", "ESP_PLATFORM", "F_CPU=240000000L", "HAVE_CONFIG_H", "MBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\"", "ARDUINO=10805", "ARDUINO_ARCH_ESP32", "ARDUINO_VARIANT=\"esp32\"", "ARDUINO_BOARD=\"Espressif ESP32 Dev Module\""], "includes": {"build": ["/home/developer/Web3E-Application/Office Door/include", "/home/developer/Web3E-Application/Office Door/src", "/home/developer/Web3E-Application/Office Door/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src", "/home/developer/Web3E-Application/Office Door/.pio/libdeps/esp32dev/Web3E/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/WiFiClientSecure/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/EEPROM/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/config", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/app_trace", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/app_update", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/asio", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/bootloader_support", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/bt", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/coap", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/console", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/driver", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/efuse", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp-tls", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp32", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_adc_cal", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_event", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_http_client", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_http_server", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_https_ota", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_https_server", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_ringbuf", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_websocket_client", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/espcoredump", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/ethernet", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/expat", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/fatfs", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/freemodbus", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/freertos", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/heap", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/idf_test", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/jsmn", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/json", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/libsodium", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/log", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/lwip", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mbedtls", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mdns", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/micro-ecc", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mqtt", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/newlib", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/nghttp", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/nvs_flash", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/openssl", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/protobuf-c", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/protocomm", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/pthread", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/sdmmc", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/smartconfig_ack", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/soc", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/spi_flash", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/spiffs", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/tcp_transport", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/tcpip_adapter", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/ulp", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/unity", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/vfs", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wear_levelling", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wifi_provisioning", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wpa_supplicant", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/xtensa-debug-module", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp-face", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp32-camera", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp-face", "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/fb_gfx", "/home/developer/.platformio/packages/framework-arduinoespressif32/cores/esp32", "/home/developer/.platformio/packages/framework-arduinoespressif32/variants/esp32"], "compatlib": ["/home/developer/Web3E-Application/Office Door/.pio/libdeps/esp32dev/Web3E/src", "/home/developer/Web3E-Application/Office Door/.pio/libdeps/esp32dev/Web3E/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/WiFiClientSecure/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/EEPROM/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/EEPROM/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/WiFiClientSecure/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/ArduinoOTA/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/AsyncUDP/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/AzureIoT/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/BLE/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/BluetoothSerial/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/DNSServer/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/ESP32/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/ESPmDNS/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/FFat/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/FS/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdate/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdateServer/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/NetBIOS/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/Preferences/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/SD/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/SD_MMC/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/SPI/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/SPIFFS/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/SimpleBLE/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/Ticker/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/Update/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src", "/home/developer/.platformio/packages/framework-arduinoespressif32/libraries/WiFiProv/src"], "toolchain": ["/home/developer/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0", "/home/developer/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/xtensa-esp32-elf", "/home/developer/.platformio/packages/toolchain-xtensa32/lib/gcc/xtensa-esp32-elf/5.2.0/include-fixed", "/home/developer/.platformio/packages/toolchain-xtensa32/lib/gcc/xtensa-esp32-elf/5.2.0/include", "/home/developer/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include"], "unity": []}, "cc_path": "/home/developer/.platformio/packages/toolchain-xtensa32/bin/xtensa-esp32-elf-gcc", "cxx_path": "/home/developer/.platformio/packages/toolchain-xtensa32/bin/xtensa-esp32-elf-g++", "gdb_path": "/home/developer/.platformio/packages/toolchain-xtensa32/bin/xtensa-esp32-elf-gdb", "prog_path": "/home/developer/Web3E-Application/Office Door/.pio/build/esp32dev/firmware.elf", "svd_path": null, "compiler_type": "gcc", "targets": [{"name": "buildfs", "title": "Build Filesystem Image", "description": null, "group": "Platform"}, {"name": "size", "title": "Program Size", "description": "Calculate program size", "group": "Platform"}, {"name": "upload", "title": "Upload", "description": null, "group": "Platform"}, {"name": "uploadfs", "title": "Upload Filesystem Image", "description": null, "group": "Platform"}, {"name": "uploadfsota", "title": "Upload Filesystem Image OTA", "description": null, "group": "Platform"}, {"name": "erase", "title": "Erase Flash", "description": null, "group": "Platform"}, {"name": "compiledb", "title": "Compilation Database", "description": "Generate compilation database `compile_commands.json`", "group": "Advanced"}, {"name": "clean", "title": "Clean", "group": "Generic"}], "extra": {"flash_images": [{"offset": "0x1000", "path": "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/sdk/bin/bootloader_dio_40m.bin"}, {"offset": "0x8000", "path": "/home/developer/Web3E-Application/Office Door/.pio/build/esp32dev/partitions.bin"}, {"offset": "0xe000", "path": "/home/developer/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin"}]}, "cc_flags": "-std=gnu99 -Wno-old-style-declaration -Os -g3 -Wall -nostdlib -Wpointer-arith -Wno-error=unused-but-set-variable -Wno-error=unused-variable -mlongcalls -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -Wno-error=deprecated-declarations -Wno-error=unused-function -Wno-unused-parameter -Wno-sign-compare -fstack-protector -fexceptions -Werror=reorder", "cxx_flags": "-fno-rtti -fno-exceptions -std=gnu++11 -Os -g3 -Wall -nostdlib -Wpointer-arith -Wno-error=unused-but-set-variable -Wno-error=unused-variable -mlongcalls -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -Wno-error=deprecated-declarations -Wno-error=unused-function -Wno-unused-parameter -Wno-sign-compare -fstack-protector -fexceptions -Werror=reorder"}
\ No newline at end of file
diff --git a/Office Door/.pio/build/project.checksum b/Office Door/.pio/build/project.checksum
new file mode 100644
index 0000000..7d05648
--- /dev/null
+++ b/Office Door/.pio/build/project.checksum
@@ -0,0 +1 @@
+6267ff0de5f64c008486cb9c301cc10998ab4acb
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/.gitignore b/Office Door/.pio/libdeps/esp32dev/Web3E/.gitignore
new file mode 100644
index 0000000..49a05e7
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/.gitignore
@@ -0,0 +1,2 @@
+# Visual Studio Code project files
+.vscode/
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/.piopm b/Office Door/.pio/libdeps/esp32dev/Web3E/.piopm
new file mode 100644
index 0000000..6f4a73e
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/.piopm
@@ -0,0 +1 @@
+{"type": "library", "name": "Web3E", "version": "1.10.0", "spec": {"owner": "alphawallet", "id": 5781, "name": "Web3E", "requirements": null, "url": null}}
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/LICENSE b/Office Door/.pio/libdeps/esp32dev/Web3E/LICENSE
new file mode 100644
index 0000000..c5502a8
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2018 Stormbird/Alpha Wallet
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/README.md b/Office Door/.pio/libdeps/esp32dev/Web3E/README.md
new file mode 100644
index 0000000..1be4318
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/README.md
@@ -0,0 +1,344 @@
+# Web3E Ethereum for Embedded devices
+
+
+
+## Version 1.10
+
+Web3E is a fully functional Web3 framework for Embedded devices running Arduino. Web3E now has methods which allow you to use TokenScript in your IoT solution for rapid deployment. Tested mainly on ESP32 and working on ESP8266. Also included is a rapid development DApp injector to convert your embedded server into a fully integrated Ethereum DApp.
+
+Starting from a simple requirement - write a DApp capable of running on an ESP32 which can serve as a security door entry system. Some brave attempts can be found in scattered repos but ultimately even the best are just dapp veneers or have ingeneous and clunky hand-rolled communication systems like the Arduino wallet attempts.
+
+What is required is a method to write simple, fully embedded DApps which give you a zero infrastucture and total security solution.
+It is possible that as Ethereum runs natively on embedded devices a new revolution in the blockchain saga will begin. Now you have the ability to write a fully embedded DApp that gives you the seurity and flexibility of Ethereum in an embedded device.
+
+## New Features
+
+- TokenScript/API interface [TokenScript](https://tokenscript.org)
+- uint256 class added to correctly handle Ethereum types.
+- usability methods added for converting between doubles and Wei values.
+- usability methods added for displaying Wei values as doubles.
+- random number generation uses Mersenne Twister.
+- memory usage improved.
+
+## Features
+
+- Web3E now has a streamlined [TokenScript](https://tokenscript.org) interface for smooth integration with AlphaWallet, and other TokenScript powered wallet.
+- Web3E has a Ready-to-Go DApp injection system that turns any device hosted site instantly into an Ethereum DApp with ECDSA crypto!
+- Cryptography has been overhauled to use a cut-down version of Trezor Wallet's heavily optimised and production proven library.
+- Transaction system is fully optimised and has been tested on ERC20 and ERC875 contracts.
+- Usability has been a priority.
+
+## Installation
+
+- It is recommended to use [Platformio](https://platformio.org/install/) for best experience. Web3E is now part of the Platformio libraries so no need to clone the repo.
+- Using Web3E is a one step process:
+ 1. Create a new project in Platformio and edit the platformio.ini so it looks similar to:
+
+```
+[env:esp32dev]
+platform = espressif32
+board = esp32dev
+framework = arduino
+
+; Serial Monitor options
+monitor_speed = 115200
+
+lib_deps =
+ # Using a library name
+ Web3E
+```
+
+## Example TokenScript flow
+
+- Two API end points are exposed on the embedded device, '/api/getChallenge' and 'api/checkSignature?sig='
+- Device creates a challenge string, lets say 'Oranges 22853'.
+- Tokenscript enabled phone runs embedded JavaScript that does a 'fetch' on 'getChallenge', returning 'Oranges 22853'.
+- User is asked to sign this message using Ethereum SignPersonalMessage, with the same key that owns an entry token.
+- Signature is sent back to embedded device using 'fetch' on 'api/checkSignature?sig='.
+- Device ECRecover's an Ethereum Address from the signature using the current challenge.
+- If address from ECRecover holds a token then open the door.
+- Report pass/fail to callee.
+
+The advantage of using TokenScript rather than a dapp is evident from looking at the code example. You will have a very nice user interface defined with html/css with the calling code written in small JavaScript functions. The user would quickly find the entry token in their wallet.
+
+## Example Web3E DApp flow
+
+- Device creates a challenge string, lets say 'Oranges 22853'.
+- Sign button containing a JavaScript Web3 call will instruct the wallet browser to ask the user to use their private key to sign 'Oranges 22853'.
+- After user signs, the signature and the user's address are passed back into the code running on the firmware.
+- Web3E can perform ECRecover on the signature and the challenge string it created.
+- The device code compares the recovered address with the address from the user. If they match then we have verified the user holds the private key for that address.
+- Web3E can now check for specific permission tokens held by the user address. If the tokens are present the user has permission to operate whatever is connected to the device, could be a security door, safe, the office printer, a shared bitcoin hardware wallet etc.
+- All operations are offchain ie gasless, but using on-chain attestations which an owner can issue at will.
+
+## AlphaWallet Security Door
+
+https://github.com/alpha-wallet/Web3E-Application
+
+Full source code for the [system active at the AlphaWallet office](https://www.youtube.com/watch?v=D_pMOMxXrYY). To get it working you need:
+- [Platformio](https://platformio.org/)
+- [AlphaWallet](https://www.alphawallet.com)
+- [Testnet Eth Kovan](https://faucet.kovan.network). Visit this site on the DApp browser.
+- [Testnet Eth Goerli](https://goerli-faucet.slock.it/). Visit this site on your DApp browser.
+Choose NonFungible token standard ERC721 or ERC875. Note the samples are written for ERC875 so you may need to adapt them for the ERC721 balance check.
+- [Mint some ERC721 tokens](https://mintable.app/create) Visit here on your DApp browser.
+- [Mint some ERC875 tokens](https://tf.alphawallet.com) Visit here on your DApp browser.
+- Take a note of the contract address. Copy/paste contract address into source code inside the 'STORMBIRD_CONTRACT' define.
+- Build and deploy the sample to your Arduino framework device.
+- Use the transfer or MagicLink on AlphaWallet to give out the tokens.
+
+## Included in the package are seven samples
+
+- Simple DApp. Shows the power of the library to create a DApp server truly embedded in the device. The on-board cryptography engine can fully interact with user input. Signing, recovery/verification takes milliseconds on ESP32.
+- Query Wallet balances, Token balances and for the first time Non-Fungible-Token (NFT) balances.
+- Push transactions, showing token transfer of ERC20 and ERC875 tokens.
+- Send Eth, showing how to send native eth.
+- Wallet Bridge 1: Introduction to simple TokenScript connection to wallet.
+- Wallet Bridge 2: Use simple authentication to check pre-defined addresses.
+- Wallet Bridge 3: Use Ethereum Tokens as security attestations to interct with your IoT directly via the wallet.
+
+The push transaction sample requires a little work to get running. You have to have an Ethereum wallet, some testnet ETH, the private key for that testnet eth, and then create some ERC20 and ERC875 tokens in the account.
+
+## Usage
+See Wallet Bridge 1, 2 and 3 examples for complete source
+
+## Standard: Using ScriptProxy Bridge
+### This style of connection will work in almost every situation, from inside or outside of the WiFi connection
+In this usage pattern, your IoT device will connect to a proxy server which provides a bridge to the TokenScript running on your wallet.
+The source code for the proxy server can be found here: [Script Proxy](https://github.com/AlphaWallet/Web3E-Application/tree/master/ScriptProxy)
+
+- Set up API routes
+```
+ const char *apiRoute = "api/";
+ enum APIRoutes {
+ api_getChallenge,
+ api_checkSignature,
+ api_End };
+
+ s_apiRoutes["getChallenge"] = api_getChallenge;
+ s_apiRoutes["checkSignature"] = api_checkSignature;
+ s_apiRoutes["end"] = api_End;
+```
+
+Declare UdpBridge, KeyID and Web3 in globals:
+
+```
+UdpBridge *udpConnection;
+Web3 *web3;
+KeyID *keyID;
+```
+
+Start UDP bridge after connecting to WiFi:
+
+```
+ udpConnection = new UdpBridge();
+ udpConnection->setKey(keyID, web3);
+ udpConnection->startConnection();
+```
+
+Within your loop() check for API call:
+
+```
+ udpConnection->checkClientAPI(&handleAPI);
+```
+
+Handle API call in the callback:
+
+```
+void handleAPI(APIReturn *apiReturn, UdpBridge *udpBridge, int methodId)
+{
+ switch (s_apiRoutes[apiReturn->apiName.c_str()])
+ {
+ case api_getChallenge:
+ Serial.println(currentChallenge.c_str());
+ udpBridge->sendResponse(currentChallenge, methodId);
+ break;
+ case api_checkSignature:
+ {
+ //EC-Recover address from signature and challenge
+ string address = Crypto::ECRecoverFromPersonalMessage(&apiReturn->params["sig"], ¤tChallenge);
+ //Check if this address has our entry token
+ boolean hasToken = QueryBalance(&address);
+ updateChallenge(); //generate a new challenge after each check
+ if (hasToken)
+ {
+ udpBridge->sendResponse("pass", methodId);
+ OpenDoor(); //Call your code that opens a door or performs the required 'pass' action
+ }
+ else
+ {
+ udpBridge->sendResponse("fail: doesn't have token", methodId);
+ }
+ }
+ break;
+```
+
+
+## Advanced: Direct TCP connection
+### Use this if you have admin control of your WiFi Router, as you need to set up port forwarding to access the unit from outside your WiFi
+In this usage pattern, the TokenScript running on the wallet will connect directly to the IoT device. Notice that this means your IoT is directly accessible to the internet, which may be susceptible to exploit.
+
+- Declare the TCP server in globals:
+```
+WiFiServer server(8082);
+```
+- Ensure your Device is locked to a fixed IP Address for port forwarding (adjust local IP address as required):
+```
+IPAddress ipStat(192, 168, 1, 100);
+IPAddress gateway(192, 168, 1, 1);
+IPAddress subnet(255, 255, 255, 0);
+IPAddress dns(192, 168, 1, 1);
+WiFi.config(ipStat, gateway, subnet, dns, dns);
+```
+
+
+- Set up API routes
+```
+ const char *apiRoute = "api/";
+ enum APIRoutes {
+ api_getChallenge,
+ api_checkSignature,
+ api_End };
+
+ s_apiRoutes["getChallenge"] = api_getChallenge;
+ s_apiRoutes["checkSignature"] = api_checkSignature;
+ s_apiRoutes["end"] = api_End;
+```
+- Listen for API call:
+```
+ WiFiClient c = server.available(); // Listen for incoming clients
+ ScriptClient *client = (ScriptClient*) &c;
+
+ if (*client)
+ {
+ Serial.println("New Client.");
+ client->checkClientAPI(apiRoute, &handleAPI); //method handles connection close etc.
+ }
+```
+- Handle API return:
+```
+void handleAPI(APIReturn *apiReturn, ScriptClient *client)
+{
+ switch(s_apiRoutes[apiReturn->apiName.c_str()])
+ {
+ case api_getChallenge:
+ client->print(currentChallenge.c_str());
+ break;
+ case api_checkSignature:
+ {
+ //EC-Recover address from signature and challenge
+ string address = Crypto::ECRecoverFromPersonalMessage(&apiReturn->params["sig"], ¤tChallenge);
+ //Check if this address has our entry token
+ boolean hasToken = QueryBalance(&address);
+ updateChallenge(); //generate a new challenge after each check
+ if (hasToken)
+ {
+ client->print("pass");
+ OpenDoor(); //Call your code that opens a door or performs the required 'pass' action
+ }
+ else
+ {
+ client->print("fail: doesn't have token");
+ }
+ }
+ break;
+ }
+```
+
+## Ethereum transaction (ie send ETH to address):
+
+```
+// Setup Web3 and Contract with Private Key
+...
+
+Contract contract(&web3, "");
+contract.SetPrivateKey(PRIVATE_KEY);
+uint32_t nonceVal = (uint32_t)web3.EthGetTransactionCount(&address); //obtain the next nonce
+uint256_t weiValue = Util::ConvertToWei(0.25, 18); //send 0.25 eth
+unsigned long long gasPriceVal = 1000000000ULL;
+uint32_t gasLimitVal = 90000;
+string emptyString = "";
+string toAddress = "0xC067A53c91258ba513059919E03B81CF93f57Ac7";
+string result = contract.SendTransaction(nonceVal, gasPriceVal, gasLimitVal, &toAddress, &weiValue, &emptyString);
+```
+
+## Query ETH balance:
+```
+uint256_t balance = web3.EthGetBalance(&address); //obtain balance in Wei
+string balanceStr = Util::ConvertWeiToEthString(&balance, 18); //get string balance as Eth (18 decimals)
+```
+
+## Query ERC20 Balance:
+```
+string address = string("0x007bee82bdd9e866b2bd114780a47f2261c684e3");
+Contract contract(&web3, "0x20fe562d797a42dcb3399062ae9546cd06f63280"); //contract is on Ropsten
+
+//Obtain decimals to correctly display ERC20 balance (if you already know this you can skip this step)
+string param = contract.SetupContractData("decimals()", &address);
+string result = contract.ViewCall(¶m);
+int decimals = web3.getInt(&result);
+
+//Fetch the balance in base units
+param = contract.SetupContractData("balanceOf(address)", &address);
+result = contract.ViewCall(¶m);
+
+uint256_t baseBalance = web3.getUint256(&result);
+string balanceStr = Util::ConvertWeiToEthString(&baseBalance, decimals); //convert balance to double style using decimal places
+```
+
+## Send ERC20 Token:
+```
+string contractAddr = "0x20fe562d797a42dcb3399062ae9546cd06f63280";
+Contract contract(&web3, contractAddr.c_str());
+contract.SetPrivateKey();
+
+//Get contract name
+string param = contract.SetupContractData("name()", &addr);
+string result = contract.ViewCall(¶m);
+string interpreted = Util::InterpretStringResult(web3.getString(&result).c_str());
+Serial.println(interpreted.c_str());
+
+//Get Contract decimals
+param = contract.SetupContractData("decimals()", &addr);
+result = contract.ViewCall(¶m);
+int decimals = web3.getInt(&result);
+Serial.println(decimals);
+
+unsigned long long gasPriceVal = 22000000000ULL;
+uint32_t gasLimitVal = 4300000;
+
+//amount of erc20 token to send, note we use decimal value obtained earlier
+uint256_t weiValue = Util::ConvertToWei(0.1, decimals);
+
+//get nonce
+uint32_t nonceVal = (uint32_t)web3.EthGetTransactionCount(&addr);
+string toAddress = "0x007bee82bdd9e866b2bd114780a47f2261c684e3";
+string valueStr = "0x00";
+
+//Setup contract function call
+string p = contract.SetupContractData("transfer(address,uint256)", &toAddress, &weiValue); //ERC20 function plus params
+
+//push transaction to ethereum
+result = contract.SendTransaction(nonceVal, gasPriceVal, gasLimitVal, &contractAddr, &valueStr, &p);
+string transactionHash = web3.getString(&result);
+```
+
+Originally forked https://github.com/kopanitsa/web3-arduino but with almost a complete re-write it is a new framework entirely.
+
+Libraries used:
+- Web3 Arduino https://github.com/kopanitsa/web3-arduino - skeleton of framework.
+- Trezor Crypto https://github.com/trezor/trezor-crypto - ECDSA sign, recover, verify, keccak256.
+- cJSON https://github.com/DaveGamble/cJSON
+- uint256 https://github.com/calccrypto/uint256_t - Lightweight uint256 implementation perfect for embedded devices.
+- Mersenne Twister https://github.com/MersenneTwister-Lab/TinyMT.git - For the most optimal random number generation for embedded.
+
+Coming soon:
+
+- Security door using NFT access (currently live at AlphaWallet office!).
+- ERC1155 balance enquiry.
+- Use Templates in library code for more flexible development.
+
+# Donations
+If you support the cause, we could certainly use donations to help fund development:
+
+0xbc8dAfeacA658Ae0857C80D8Aa6dE4D487577c63
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Push Transaction/main.cpp b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Push Transaction/main.cpp
new file mode 100644
index 0000000..2a6f4a0
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Push Transaction/main.cpp
@@ -0,0 +1,256 @@
+#include
+#include
+#include
+#include
+
+// To get this sample working correctly there is some preparation work you need to do.
+// Feel free to skip the majority of these instructions if you're an experienced ETH user - you probably just jump in at stage 6
+// If you already have Kovan or any other testnet ETH.
+//
+// 1. Choose an Ethereum test network (or if you're brave mainnet). I like Kovan as it's nice and fast.
+// If you're using Infura you should sign up and use your own key. This is a test key I use, I wouldn't use it for anything serious.
+// 2. Download a good ethereum wallet. The best one on Android and iOS is probably 'AlphaWallet' in the respective app stores. You
+// can also use MetaMask on desktop which works fine, but doesn't display the Non-Fungible Token standards such as ERC875 and ERC1155.
+// 3. In Metamask ensure you created an account. If you already have an account with mainnet ETH in it create a new one.
+// Export the private key and import it into AlphaWallet (or just use the browser with Metamask). Also,
+// Copy/Paste the private key into the 'PRIVATE_KEY' constant below. This is why you shouldn't use any account containing real eth.
+// - you may accidentally commit the code to a public repo then you'll have all your eth gone very quickly.
+// 4. Obtain some testnet Eth. If you're using Kovan there are two good faucets we know about:
+// https://gitter.im/kovan-testnet/faucet : requres a github account. Just find your address in your wallet,
+// and copy/paste it into the chat. The bot will pick it up and drop 3 ETH into your account.
+// https://faucet.kovan.network/ : also requires github account and will give you 1 ETH per day.
+// 5. Ensure that you switch network to Koven in the wallet. Got to settings and click on 'Network'. Select Kovan.
+// 6. Create an ERC20 contract. Once you gave some Kovan in your wallet open the DApp browser in AlphaWallet and go here:
+// http://thetokenfactory.com/#/factory Create a name and symbol for your token,
+// choose 4 decimal places and a supply of say 5000000. This will give you 500 tokens in the account (50 0000 - 4 decimal places).
+// 7. Click create and your wallet will receive a message to spend Kovan ETH to create the token.
+// 8. Once the contract has been created and the tokens appear in your wallet copy/paste the contract address into ERC20CONTRACT below
+// 9. To create ERC875 tokens go to this website in AlphaWallet or Metamask enabled desktop browser:
+// https://alpha-wallet.github.io/ERC875-token-factory/index.html
+// and just fill in name and symbol then create. The tokens will be assigned to the creation address.
+// Once the tokens appear in your AlphaWallet, click on them and get the contract address (top right menu icon).
+// Paste the contract address in the 'ERC875CONTRACT' setting below.
+//10. Set up a second account in you wallet and copy the Address (not private key!) into the 'TARGETADDRESS' setting below.
+// This way you get to catch all the sent tokens in your second account.
+
+
+const char *ssid = "";
+const char *password = "";
+#define MY_ADDRESS "0xDA358D1547238335Cc666E318c511Fed455Ed77C" //Put your wallet address here
+#define ERC875CONTRACT "0x0181540116ea1047d7b5a22ce3394d5cecc0c3f1" //Put your ERC875 contract address here
+#define ERC20CONTRACT "0x0ab0c2f54afe26cbd2ed2b56a27816e41092d040" //Put your ERC20 contract address here
+#define INFURA_HOST "kovan.infura.io"
+#define INFURA_PATH "/v3/c7df4c29472d4d54a39f7aa78f146853" //please change this Infura key to your own once you have the sample running
+#define TARGETADDRESS "0x007bEe82BDd9e866b2bd114780a47f2261C684E3" //put your second address here
+#define ETHERSCAN_TX "https://kovan.etherscan.io/tx/"
+
+// Copy/paste the private key from MetaMask in here
+const char *PRIVATE_KEY = "DabbaD00DabbaD00DabbaD00DabbaD00DabbaD00DabbaD00DabbaD00DabbaD00"; //32 Byte Private key
+
+int wificounter = 0;
+Web3 web3(INFURA_HOST, INFURA_PATH);
+
+void setup_wifi();
+void PushERC875Transaction();
+void queryERC875Balance(const char *userAddress);
+void sendEthToAddress(double eth, const char *destination);
+void PushERC20Transaction(double tokens, const char *toAddr, const char *contractAddr);
+
+void setup() {
+ Serial.begin(115200);
+
+ setup_wifi();
+
+ sendEthToAddress(0.1, TARGETADDRESS);
+ PushERC20Transaction(0.1, TARGETADDRESS, ERC20CONTRACT);
+ queryERC875Balance(MY_ADDRESS);
+ PushERC20Transaction();
+ PushERC875Transaction();
+}
+
+void loop() {
+
+}
+
+void sendEthToAddress(double eth, const char *destination)
+{
+ //obtain a contract object, for just sending eth doesn't need a contract address
+ Contract contract(&web3, "");
+ contract.SetPrivateKey(PRIVATE_KEY);
+ unsigned long long gasPriceVal = 22000000000ULL;
+ uint32_t gasLimitVal = 90000;
+ string address = MY_ADDRESS;
+
+ //convert eth value to Wei
+ uint256_t weiValue = Util::ConvertToWei(eth, 18);
+ string emptyString = "";
+ string destinationAddress = destination;
+
+ Serial.print("Get Nonce: ");
+ uint32_t nonceVal = (uint32_t)web3.EthGetTransactionCount(&address);
+ Serial.println(nonceVal);
+ Serial.println("Send TX");
+ string result = contract.SendTransaction(nonceVal, gasPriceVal, gasLimitVal, &destinationAddress, &weiValue, &emptyString);
+ Serial.println(result.c_str());
+
+ string transactionHash = web3.getString(&result);
+ Serial.println("TX on Etherscan:");
+ Serial.print(ETHERSCAN_TX);
+ Serial.println(transactionHash.c_str()); //you can go straight to etherscan and see the pending transaction
+}
+
+void PushERC20Transaction(double tokens, const char *toAddr, const char *contractAddr)
+{
+ string contractAddrStr = contractAddr;
+ Contract contract(&web3, contractAddr);
+ contract.SetPrivateKey();
+
+ //Get contract name (This isn't needed to push the transaction)
+ string param = contract.SetupContractData("name()", &addr);
+ string result = contract.ViewCall(¶m);
+ string interpreted = Util::InterpretStringResult(web3.getString(&result).c_str());
+ Serial.println(interpreted.c_str());
+
+ //Get Contract decimals
+ param = contract.SetupContractData("decimals()", &addr);
+ result = contract.ViewCall(¶m);
+ int decimals = web3.getInt(&result);
+ Serial.println(decimals);
+
+ unsigned long long gasPriceVal = 22000000000ULL;
+ uint32_t gasLimitVal = 4300000;
+
+ //amount of erc20 token to send, note we use decimal value obtained earlier
+ uint256_t weiValue = Util::ConvertToWei(tokens, decimals);
+
+ //get nonce
+ uint32_t nonceVal = (uint32_t)web3.EthGetTransactionCount(&addr);
+ string toAddress = toAddr;
+ string valueStr = "0x00";
+
+ //Setup contract function call
+ string p = contract.SetupContractData("transfer(address,uint256)", &toAddress, &weiValue); //ERC20 function plus params
+
+ //push transaction to ethereum
+ result = contract.SendTransaction(nonceVal, gasPriceVal, gasLimitVal, &contractAddrStr, &valueStr, &p);
+ string transactionHash = web3.getString(&result);
+}
+
+
+/* Query balance of ERC875 tokens */
+void queryERC875Balance(const char *userAddress)
+{
+ // transaction
+ Contract contract(&web3, ERC875CONTRACT);
+
+ String myAddr = userAddress;
+
+ String func = "balanceOf(address)";
+ Serial.println("Start");
+ string param = contract.SetupContractData(func.c_str(), &myAddr);
+ string result = contract.ViewCall(¶m);
+
+ Serial.println(result.c_str());
+
+ Serial.print("Balance of Contract ");
+ Serial.println(ERC875CONTRACT);
+ Serial.print("for user: ");
+ Serial.println(myAddr.c_str());
+ Serial.println();
+
+ //break down the result
+ vector *vectorResult = Util::InterpretVectorResult(&result);
+ int count = 0;
+ char buffer[128];
+ for (auto itr = vectorResult->begin(); itr != vectorResult->end(); itr++)
+ {
+ snprintf(buffer, 128, "%d: %s", count++, itr->c_str());
+ Serial.println(buffer);
+ }
+
+ delete(vectorResult);
+
+ //Call contract name function
+ param = contract.SetupContractData("name()", &userAddress);
+ result = contract.ViewCall(¶m);
+ string contractName = web3.getString(&result);
+ Serial.println("NAME: ");
+ // recover actual string name
+ string interpreted = Util::InterpretStringResult(contractName.c_str());
+ Serial.println(interpreted.c_str());
+}
+
+void PushERC875Transaction()
+{
+ Contract contract(&web3, ERC875CONTRACT);
+ contract.SetPrivateKey(PRIVATE_KEY);
+ string addr = MY_ADDRESS;
+ uint32_t nonceVal = (uint32_t)web3.EthGetTransactionCount(&addr);
+
+ unsigned long long gasPriceVal = 22000000000ULL;
+ uint32_t gasLimitVal = 4300000;
+ uint8_t dataStr[100];
+ memset(dataStr, 0, 100);
+ string address = TARGETADDRESS;
+ vector indices;
+ indices.push_back(1); // transfer NFT index 1 (ie the second token, since index 0 is the first token)
+ string p = contract.SetupContractData("transfer(address,uint256[])", &address, &indices);
+ string contractAddr = ERC875CONTRACT;
+ string valueStrThis = "0x00";
+
+ string result = contract.SendTransaction(nonceVal, gasPriceVal, gasLimitVal, &contractAddr, &valueStrThis, &p);
+ Serial.println(result.c_str());
+ string transactionHash = web3.getString(&result);
+ Serial.println("TX on Etherscan:");
+ Serial.print(ETHERSCAN_TX);
+ Serial.println(transactionHash.c_str()); //you can go straight to etherscan and see the pending transaction
+}
+
+
+/* This routine is specifically geared for ESP32 perculiarities */
+/* You may need to change the code as required */
+/* It should work on 8266 as well */
+void setup_wifi()
+{
+ if (WiFi.status() == WL_CONNECTED)
+ {
+ return;
+ }
+
+ Serial.println();
+ Serial.print("Connecting to ");
+ Serial.println(ssid);
+
+ if (WiFi.status() != WL_CONNECTED)
+ {
+ WiFi.persistent(false);
+ WiFi.mode(WIFI_OFF);
+ WiFi.mode(WIFI_STA);
+
+ WiFi.begin(ssid, password);
+ }
+
+ wificounter = 0;
+ while (WiFi.status() != WL_CONNECTED && wificounter < 10)
+ {
+ for (int i = 0; i < 500; i++)
+ {
+ delay(1);
+ }
+ Serial.print(".");
+ wificounter++;
+ }
+
+ if (wificounter >= 10)
+ {
+ Serial.println("Restarting ...");
+ ESP.restart(); //targetting 8266 & Esp32 - you may need to replace this
+ }
+
+ delay(10);
+
+ Serial.println("");
+ Serial.println("WiFi connected.");
+ Serial.println("IP address: ");
+ Serial.println(WiFi.localIP());
+}
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Query Token Balance/main.cpp b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Query Token Balance/main.cpp
new file mode 100644
index 0000000..8be3439
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Query Token Balance/main.cpp
@@ -0,0 +1,158 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// This sample should work straight 'out of the box' after you plug in your WiFi credentials
+
+const char *ssid = "";
+const char *password = "";
+const char *INFURA_HOST = "kovan.infura.io";
+const char *INFURA_PATH = "/v3/"; //this is an anonymous infura public API key for courtesy testing, please don't use it for production
+#define NATIVE_ETH_TOKENS "Kovan ETH" //if you switch chains you might want to change this
+#define ERC875CONTRACT "0x0b70dd9f8ada11eee393c8ab0dd0d3df6a172876" //an ERC875 token contract on Kovan
+#define ERC20CONTRACT "0xb06d72a24df50d4e2cac133b320c5e7de3ef94cb" //and ERC20 token contract on Kovan
+#define USERACCOUNT "0x835bb27deec61e1cd81b3a2feec9fbd76b15971d" //a user account that holds Kovan ETH and balances of tokens in the two above contracts
+
+Web3 web3(INFURA_HOST, INFURA_PATH);
+int wificounter = 0;
+
+void queryERC875Balance(const char* Address, const char* ERC875ContractAddress);
+void queryERC20Balance(const char* Address, const char* ERC875ContractAddress);
+void setup_wifi();
+void TestERC20();
+void QueryEthBalance(const char* Address);
+
+void setup()
+{
+ Serial.begin(115200); //ensure you set your Arduino IDE port config or platformio.ini with monitor_speed = 115200
+ setup_wifi();
+
+ string userAddress = USERACCOUNT;
+
+ queryERC20Balance(ERC20CONTRACT, USERACCOUNT);
+ queryERC875Balance(ERC875CONTRACT, USERACCOUNT);
+}
+
+
+void loop()
+{
+ // put your main code here, to run repeatedly.
+}
+
+/* Query balance of ERC875 tokens */
+void queryERC875Balance(const char* ContractAddress, const char *userAddress)
+{
+ // transaction
+ Contract contract(&web3, ContractAddress);
+
+ String myAddr = userAddress;
+
+ String func = "balanceOf(address)";
+ Serial.println("Start");
+ string param = contract.SetupContractData(func.c_str(), &myAddr);
+ string result = contract.ViewCall(¶m);
+
+ Serial.println(result.c_str());
+
+ Serial.print("Balance of Contract ");
+ Serial.println(ContractAddress);
+ Serial.print("for user: ");
+ Serial.println(myAddr.c_str());
+ Serial.println();
+
+ //break down the result
+ vector *vectorResult = Util::InterpretVectorResult(&result);
+ int count = 1;
+ char buffer[128];
+ for (auto itr = vectorResult->begin(); itr != vectorResult->end(); itr++)
+ {
+ snprintf(buffer, 128, "%d: %s", count++, itr->c_str());
+ Serial.println(buffer);
+ }
+
+ delete(vectorResult);
+
+ //Call contract name function
+ param = contract.SetupContractData("name()", &userAddress);
+ result = contract.ViewCall(¶m);
+ string contractName = web3.getString(&result);
+ Serial.println("NAME: ");
+ // recover actual string name
+ string interpreted = Util::InterpretStringResult(contractName.c_str());
+ Serial.println(interpreted.c_str());
+}
+
+// Query balance of ERC20 token
+void queryERC20Balance(const char* ContractAddress, const char *userAddress)
+{
+ Contract contract(&web3, contractAddr);
+ String address = userAddress;
+ string param = contract.SetupContractData("balanceOf(address)", &address);
+ string result = contract.ViewCall(¶m);
+
+ param = contract.SetupContractData("decimals()", &address);
+ result = contract.ViewCall(¶m);
+ int decimals = web3.getInt(&result);
+
+ uint256_t baseBalance = web3.getUint256(&result);
+ string balanceStr = Util::ConvertWeiToEthString(&baseBalance, decimals); //use decimals to calculate value, not all ERC20 use 18 decimals
+
+ Serial.print("ERC20 Balance: ");
+ Serial.println(balanceStr.c_str());
+}
+
+
+/* This routine is specifically geared for ESP32 perculiarities */
+/* You may need to change the code as required */
+/* It should work on 8266 as well */
+void setup_wifi()
+{
+ if (WiFi.status() == WL_CONNECTED)
+ {
+ return;
+ }
+
+ Serial.println();
+ Serial.print("Connecting to ");
+ Serial.println(ssid);
+
+ if (WiFi.status() != WL_CONNECTED)
+ {
+ WiFi.persistent(false);
+ WiFi.mode(WIFI_OFF);
+ WiFi.mode(WIFI_STA);
+
+ WiFi.begin(ssid, password);
+ }
+
+ wificounter = 0;
+ while (WiFi.status() != WL_CONNECTED && wificounter < 10)
+ {
+ for (int i = 0; i < 500; i++)
+ {
+ delay(1);
+ }
+ Serial.print(".");
+ wificounter++;
+ }
+
+ if (wificounter >= 10)
+ {
+ Serial.println("Restarting ...");
+ ESP.restart(); //targetting 8266 & Esp32 - you may need to replace this
+ }
+
+ delay(10);
+
+ Serial.println("");
+ Serial.println("WiFi connected.");
+ Serial.println("IP address: ");
+ Serial.println(WiFi.localIP());
+}
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Send Eth to Address/main.cpp b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Send Eth to Address/main.cpp
new file mode 100644
index 0000000..2618ec4
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Send Eth to Address/main.cpp
@@ -0,0 +1,157 @@
+#include
+#include
+#include
+#include
+
+// To get this sample working correctly there is some preparation work you need to do.
+// Feel free to skip the majority of these instructions if you're an experienced ETH user - you probably just need
+// to fill in your private key and accounts
+//
+// 1. Choose an Ethereum test network (or if you're brave mainnet). I like Kovan as it's nice and fast.
+// If you're using Infura you should sign up and use your own key. This is a test key I use, I wouldn't use it for anything serious.
+// 2. Download a good ethereum wallet. The best one on Android and iOS is probably 'AlphaWallet' in the respective app stores. You
+// can also use MetaMask on desktop which works fine, but doesn't display the Non-Fungible Token standards such as ERC875 and ERC1155.
+// 3. In Metamask ensure you created an account. If you already have an account with mainnet ETH in it create a new one.
+// Export the private key and import it into AlphaWallet (or just use the browser with Metamask). Also,
+// Copy/Paste the private key into the 'PRIVATE_KEY' constant below. This is why you shouldn't use any account containing real eth for testing.
+// - you may accidentally commit the code to a public repo then you'll have all your eth gone very quickly.
+// 4. Obtain some testnet Eth. If you're using Kovan there are two good faucets we know about:
+// https://gitter.im/kovan-testnet/faucet : requres a github account. Just find your address in your wallet,
+// and copy/paste it into the chat. The bot will pick it up and drop 3 ETH into your account.
+// https://faucet.kovan.network/ : also requires github account and will give you 1 ETH per day.
+// 5. Ensure that you switch network to Koven in the wallet. Got to settings and click on 'Network'. Select Kovan.
+// 6. Set up a second account in you wallet and copy the Address (not private key!) into the 'TARGETADDRESS' setting below.
+// This way you get to catch all the sent ETH in your second account.
+
+
+const char *ssid = "";
+const char *password = "";
+#define MY_ADDRESS "0xDA358D1547238335Cc666E318c511Fed455Ed77C" //Put your wallet address here
+#define INFURA_HOST "kovan.infura.io"
+#define INFURA_PATH "/v3/c7df4c29472d4d54a39f7aa78f146853" //please change this Infura key to your own once you have the sample running
+#define TARGETADDRESS "0x007bEe82BDd9e866b2bd114780a47f2261C684E3" //put your second address here
+#define ETHERSCAN_TX "https://kovan.etherscan.io/tx/"
+
+// Copy/paste the private key from MetaMask in here
+const char *PRIVATE_KEY = "DabbaD00DabbaD00DabbaD00DabbaD00DabbaD00DabbaD00DabbaD00DabbaD00"; //32 Byte Private key
+
+int wificounter = 0;
+Web3 web3(INFURA_HOST, INFURA_PATH);
+
+void setup_wifi();
+void sendEthToAddress(double eth, const char *destination);
+double queryAccountBalance(const char *address);
+
+void setup() {
+ Serial.begin(115200);
+
+ setup_wifi();
+
+ double balance = queryAccountBalance(MY_ADDRESS);
+ Serial.print("My Address: ");
+ Serial.println(MY_ADDRESS);
+ Serial.print("Balance of Address: ");
+ Serial.println(balance);
+
+ Serial.println("Try to send 0.1 ETH");
+ Serial.print("To Address: ");
+ Serial.println(TARGETADDRESS);
+
+ if (balance < 0.11) //allow for gas
+ {
+ sendEthToAddress(0.1, TARGETADDRESS);
+ }
+ else
+ {
+ Serial.println("Balance is insufficient, cannot send ... Go to Eth faucet.");
+ }
+}
+
+double queryAccountBalance(const char *address)
+{
+ uint256_t balance = web3.EthGetBalance(&address); //obtain balance in Wei
+ string balanceStr = Util::ConvertWeiToEthString(&balance, 18); //Eth uses 18 decimal
+ Serial.print("Balance: ");
+ Serial.println(balanceStr.c_str());
+ double balanceDbl = atof(balanceStr.c_str());
+ return balanceDbl;
+}
+
+void sendEthToAddress(double eth, const char *destination)
+{
+ //obtain a contract object, for just sending eth doesn't need a contract address
+ Contract contract(&web3, "");
+ contract.SetPrivateKey(PRIVATE_KEY);
+ unsigned long long gasPriceVal = 22000000000ULL;
+ uint32_t gasLimitVal = 90000;
+
+ //convert eth value to Wei
+ uint256_t weiValue = Util::ConvertToWei(eth, 18);
+ string emptyString = "";
+ string destinationAddress = destination;
+
+ Serial.print("Get Nonce: ");
+ uint32_t nonceVal = (uint32_t)web3.EthGetTransactionCount(&address);
+ Serial.println(nonceVal);
+ Serial.println("Send TX");
+ string result = contract.SendTransaction(nonceVal, gasPriceVal, gasLimitVal, &destinationAddress, &weiValue, &emptyString);
+ Serial.println(result.c_str());
+
+ string transactionHash = web3.getString(&result);
+ Serial.println("TX on Etherscan:");
+ Serial.print(ETHERSCAN_TX);
+ Serial.println(transactionHash.c_str()); //you can go straight to etherscan and see the pending transaction
+}
+
+void loop() {
+
+}
+
+
+/* This routine is specifically geared for ESP32 perculiarities */
+/* You may need to change the code as required */
+/* It should work on 8266 as well */
+void setup_wifi()
+{
+ if (WiFi.status() == WL_CONNECTED)
+ {
+ return;
+ }
+
+ Serial.println();
+ Serial.print("Connecting to ");
+ Serial.println(ssid);
+
+ if (WiFi.status() != WL_CONNECTED)
+ {
+ WiFi.persistent(false);
+ WiFi.mode(WIFI_OFF);
+ WiFi.mode(WIFI_STA);
+
+ WiFi.begin(ssid, password);
+ }
+
+ wificounter = 0;
+ while (WiFi.status() != WL_CONNECTED && wificounter < 10)
+ {
+ for (int i = 0; i < 500; i++)
+ {
+ delay(1);
+ }
+ Serial.print(".");
+ wificounter++;
+ }
+
+ if (wificounter >= 10)
+ {
+ Serial.println("Restarting ...");
+ ESP.restart(); //targetting 8266 & Esp32 - you may need to replace this
+ }
+
+ delay(10);
+
+ Serial.println("");
+ Serial.println("WiFi connected.");
+ Serial.println("IP address: ");
+ Serial.println(WiFi.localIP());
+}
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 1/.gitignore b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 1/.gitignore
new file mode 100644
index 0000000..89cc49c
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 1/.gitignore
@@ -0,0 +1,5 @@
+.pio
+.vscode/.browse.c_cpp.db*
+.vscode/c_cpp_properties.json
+.vscode/launch.json
+.vscode/ipch
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 1/platformio.ini b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 1/platformio.ini
new file mode 100644
index 0000000..e850d49
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 1/platformio.ini
@@ -0,0 +1,20 @@
+;PlatformIO Project Configuration File
+;
+; Build options: build flags, source filter
+; Upload options: custom upload port, speed and extra flags
+; Library options: dependencies, extra library storages
+; Advanced options: extra scripting
+;
+; Please visit documentation for the other options and examples
+; https://docs.platformio.org/page/projectconf.html
+
+[env:esp32dev]
+platform = espressif32
+board = esp32dev
+framework = arduino
+
+monitor_speed = 115200
+
+lib_deps =
+ Web3E
+ Ticker
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 1/src/main.cpp b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 1/src/main.cpp
new file mode 100644
index 0000000..0356598
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 1/src/main.cpp
@@ -0,0 +1,194 @@
+/**
+ * Part 1 of TokenScript example
+ *
+ * This demo shows a very simple connection between wallet and IoT device
+ * To get up and running you will need to:
+ * 1. Install AlphaWallet on iOS or Android
+ * 2. Copy your wallet address from Settings/My Wallet Address
+ * 3. Visit the faucet here: https://goerli-faucet.slock.it/ and paste your address in the box and get some Goerli. You may want to repeat to get 0.1 Goerli.
+ * 4. Enable Goerli testnet in Settings/Networks and wait until you have Goerli in your wallet. The contract fee will be about 0.005
+ * 5. In Dapp Browser ensure you are on Goerli network (top right network select button) type 'NFT' in the top URL bar and click on NFT Token Factory
+ * 6. Fill in Contract Name and Token Symbol with the text you want your test token to appear in the wallet and press Deploy. Other fields are optional.
+ * 7. When the contract is deployed and the tokens show up in the wallet you will need to find the contract address.
+ * Go to Transactions and look for the 'Constructor' call. Click this and find the Token address from the 'To:' field. Make a note of this address eg in Telegram/Saved Messages
+ * If you have iOS: find the latest 'Send' transaction with apparantely 0 eth, click for details then click on 'More Details' and get contract address on the webpage
+ * 8. Replace the text "" in the bundled .xml file with this token address.
+ * 9. Setup the WiFi in this program to your wifi credentials.
+ * 10. Flash this program to your ESP32/ESP8266
+ * 11. Run the program and study the log for the Address. This is now the Device Address for this device.
+ * 12. Copy that address and replace "" in the bundled .xml file with the Device Address you created in step 11
+ * 13. Send the .xml to your mobile phone via Telegram/Saved Messages or email etc. Click on the xml and open with AlphaWallet.
+ * 14. Open AlphaWallet and click on your token you created in step 6.
+ * 15. Long click on the token picture and select 'Action'
+ * 16. Wait to receive the challenge. Once received, sign the challenge, and once complete you should see the LED on the device blink.
+ *
+ * All the groundwork is now done to try the second and third examples. These will only require a simple update to get running.
+ *
+ **/
+
+#include "esp_wifi.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+const char *ssid = "MySpectrumWiFi54-2G";
+const char *password = "littlebunny540";
+
+const char *INFURA_HOST = "ropsten.infura.io";
+const char *INFURA_PATH = "/v3/5d99b4df68564865ab9814ee77f03b90";
+
+#define BLUE_LED 22 // Little blue LED on the ESP32 TTGO
+
+UdpBridge *udpConnection;
+Web3 web3(INFURA_HOST, INFURA_PATH);
+KeyID *keyID;
+std::string challenge;
+boolean blinkLEDOn = false;
+
+void resetChallenge();
+void blink();
+void setupWifi();
+void handleUDPAPI(APIReturn *apiReturn, UdpBridge *udpBridge, int methodId);
+
+Ticker blinkTicker(blink, 500, 6); //ticker to blink the LED
+
+//define API routes
+enum APIRoutes
+{
+ api_unknown,
+ api_getChallenge,
+ api_checkSignature,
+ api_End
+};
+
+std::map s_apiRoutes;
+
+//Format for API call from wallet/utilitiy using the bridge is //?=&= etc.
+//When you call the API this is the extension you use EG www.bridgeserver.com/0x123456789ABCDEF0000/getChallenge
+void Initialize()
+{
+ s_apiRoutes["getChallenge"] = api_getChallenge;
+ s_apiRoutes["checkSignature"] = api_checkSignature;
+ s_apiRoutes["end"] = api_End;
+
+ random32v(micros()); //initial init of random seed AFTER wifi connection - since startup after wifi will be a different value of micros each start cycle
+}
+
+void setup()
+{
+ Serial.begin(115200);
+ keyID = new KeyID(&web3);
+ pinMode(BLUE_LED, OUTPUT);
+ setupWifi();
+ Initialize(); //init after wifi setup to change startup delay
+
+ udpConnection = new UdpBridge();
+ udpConnection->setKey(keyID, &web3);
+ udpConnection->startConnection();
+ resetChallenge();
+}
+
+void loop()
+{
+ setupWifi();
+ delay(1);
+ udpConnection->checkClientAPI(&handleUDPAPI);
+ blinkTicker.update();
+}
+
+/* This routine is specifically geared for ESP32 perculiarities */
+/* You may need to change the code as required */
+/* It should work on 8266 as well */
+void setupWifi()
+{
+ if (WiFi.status() == WL_CONNECTED)
+ {
+ return;
+ }
+
+ Serial.println();
+ Serial.print("Connecting to ");
+ Serial.println(ssid);
+
+ if (WiFi.status() != WL_CONNECTED)
+ {
+ WiFi.persistent(false);
+ WiFi.mode(WIFI_OFF);
+ WiFi.mode(WIFI_STA);
+ WiFi.begin(ssid, password);
+ }
+
+ int wificounter = 0;
+ while (WiFi.status() != WL_CONNECTED && wificounter < 10)
+ {
+ delay(500);
+ Serial.print(".");
+ wificounter++;
+ }
+
+ if (wificounter >= 10)
+ {
+ Serial.println("Restarting ...");
+ ESP.restart(); //targetting 8266 & Esp32 - you may need to replace this
+ }
+
+ esp_wifi_set_ps(WIFI_PS_NONE);
+ delay(10);
+
+ Serial.println("");
+ Serial.println("WiFi connected.");
+ Serial.println("IP address: ");
+ Serial.println(WiFi.localIP());
+}
+
+// Handle API call from tokenscript
+// NB: every path must return a response to the server via udpBridge->sendResponse(, methodId);
+void handleUDPAPI(APIReturn *apiReturn, UdpBridge *udpBridge, int methodId)
+{
+ std::string address;
+ //handle the returned API call
+ Serial.println(apiReturn->apiName.c_str());
+
+ switch (s_apiRoutes[apiReturn->apiName.c_str()])
+ {
+ case api_getChallenge:
+ resetChallenge(); //generate a new challenge after each check. Advantage is that we've done a full refresh of the mersenne twister
+ Serial.println(challenge.c_str());
+ udpBridge->sendResponse(challenge, methodId);
+ break;
+ case api_checkSignature:
+ {
+ address = Crypto::ECRecoverFromPersonalMessage(&apiReturn->params["sig"], &challenge);
+ int intervalTime = strtol(apiReturn->params["interval"].c_str(), NULL, 10);
+ Serial.print("0x0000000000000000000000000000000000000000");
+ Serial.println(address.c_str());
+ blinkLEDOn = false;
+ if (intervalTime > 0) blinkTicker.interval(intervalTime);
+ blinkTicker.start();
+ udpBridge->sendResponse("pass", methodId);
+ }
+ break;
+ default:
+ Serial.println("Unknown API route: ");
+ Serial.println(apiReturn->apiName.c_str());
+ udpBridge->sendResponse("fail", methodId);
+ break;
+ }
+}
+
+void resetChallenge()
+{
+ char buffer[32];
+ long challengeVal = random32();
+ challenge = "0x0000000000000000000000000000000000000000000000000000000000000000";
+ challenge += itoa(challengeVal, buffer, 16);
+}
+
+void blink()
+{
+ digitalWrite(BLUE_LED, blinkLEDOn);
+ blinkLEDOn = !blinkLEDOn;
+}
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 2/.gitignore b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 2/.gitignore
new file mode 100644
index 0000000..89cc49c
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 2/.gitignore
@@ -0,0 +1,5 @@
+.pio
+.vscode/.browse.c_cpp.db*
+.vscode/c_cpp_properties.json
+.vscode/launch.json
+.vscode/ipch
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 2/platformio.ini b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 2/platformio.ini
new file mode 100644
index 0000000..e850d49
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 2/platformio.ini
@@ -0,0 +1,20 @@
+;PlatformIO Project Configuration File
+;
+; Build options: build flags, source filter
+; Upload options: custom upload port, speed and extra flags
+; Library options: dependencies, extra library storages
+; Advanced options: extra scripting
+;
+; Please visit documentation for the other options and examples
+; https://docs.platformio.org/page/projectconf.html
+
+[env:esp32dev]
+platform = espressif32
+board = esp32dev
+framework = arduino
+
+monitor_speed = 115200
+
+lib_deps =
+ Web3E
+ Ticker
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 2/src/main.cpp b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 2/src/main.cpp
new file mode 100644
index 0000000..6d017e9
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 2/src/main.cpp
@@ -0,0 +1,216 @@
+/**
+ * Part 2 of TokenScript example
+ *
+ * This demo builds on the example 1 adding cryptography and full but inflexible security
+ * To get up and running you will need to:
+ * 1. Complete Wallet Bridge 1 example
+ * 2. Fill in WiFi credentials.
+ * 3. Copy wallet address in AlphaWallet (Settings/My Wallet Address) and add into the 'allowedAccounts' below. You may add other accounts here too.
+ * 4. Flash the example and run on your ESP32/8266
+ * 5. Find the token in AlphaWallet and click through to 'Action'
+ **/
+
+#include "esp_wifi.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+const char *ssid = "";
+const char *password = " s_apiRoutes;
+
+//Format for API call from wallet/utilitiy using the bridge is //?=&= etc.
+//When you call the API this is the extension you use EG www.bridgeserver.com/0x123456789ABCDEF0000/getChallenge
+void Initialize()
+{
+ s_apiRoutes["getChallenge"] = api_getChallenge;
+ s_apiRoutes["checkSignature"] = api_checkSignature;
+ s_apiRoutes["end"] = api_End;
+
+ random32v(micros()); //initial init of random seed AFTER wifi connection - since startup after wifi will be a different value of micros each start cycle
+}
+
+void setup()
+{
+ Serial.begin(115200);
+ keyID = new KeyID(&web3);
+ pinMode(BLUE_LED, OUTPUT);
+ setupWifi();
+ Initialize(); //init after wifi setup to change startup delay
+
+ udpConnection = new UdpBridge();
+ udpConnection->setKey(keyID, &web3);
+ udpConnection->startConnection();
+ resetChallenge();
+}
+
+void loop()
+{
+ setupWifi();
+ delay(1);
+ udpConnection->checkClientAPI(&handleUDPAPI);
+ blinkTicker.update();
+}
+
+/* This routine is specifically geared for ESP32 perculiarities */
+/* You may need to change the code as required */
+/* It should work on 8266 as well */
+void setupWifi()
+{
+ if (WiFi.status() == WL_CONNECTED)
+ {
+ return;
+ }
+
+ Serial.println();
+ Serial.print("Connecting to ");
+ Serial.println(ssid);
+
+ if (WiFi.status() != WL_CONNECTED)
+ {
+ WiFi.persistent(false);
+ WiFi.mode(WIFI_OFF);
+ WiFi.mode(WIFI_STA);
+ WiFi.begin(ssid, password);
+ }
+
+ int wificounter = 0;
+ while (WiFi.status() != WL_CONNECTED && wificounter < 10)
+ {
+ delay(500);
+ Serial.print(".");
+ wificounter++;
+ }
+
+ if (wificounter >= 10)
+ {
+ Serial.println("Restarting ...");
+ ESP.restart(); //targetting 8266 & Esp32 - you may need to replace this
+ }
+
+ esp_wifi_set_ps(WIFI_PS_NONE);
+ delay(10);
+
+ Serial.println("");
+ Serial.println("WiFi connected.");
+ Serial.println("IP address: ");
+ Serial.println(WiFi.localIP());
+}
+
+// Handle API call from tokenscript
+// NB: every path must return a response to the server via udpBridge->sendResponse(, methodId);
+void handleUDPAPI(APIReturn *apiReturn, UdpBridge *udpBridge, int methodId)
+{
+ std::string address;
+ //handle the returned API call
+ Serial.println(apiReturn->apiName.c_str());
+
+ switch (s_apiRoutes[apiReturn->apiName.c_str()])
+ {
+ case api_getChallenge:
+ Serial.println(challenge.c_str());
+ udpBridge->sendResponse(challenge, methodId);
+ break;
+ case api_checkSignature:
+ {
+ address = Crypto::ECRecoverFromPersonalMessage(&apiReturn->params["sig"], &challenge);
+ int intervalTime = strtol(apiReturn->params["interval"].c_str(), NULL, 10);
+ Serial.print("EC-Addr: ");
+ Serial.println(address.c_str()); //The signer's address, ec-recover'd from the signature and challenge
+ if (isValidAccount(address)) //if address ec-recovered from signature matches one of the specified addresses then pass
+ {
+ blinkLEDOn = false;
+ if (intervalTime > 0)
+ blinkTicker.interval(intervalTime);
+ blinkTicker.start();
+ udpBridge->sendResponse("pass", methodId);
+ }
+ else
+ {
+ udpBridge->sendResponse("fail : Invalid account", methodId);
+ }
+ resetChallenge(); //generate a new challenge after each check.
+ }
+ break;
+ default:
+ Serial.println("Unknown API route: ");
+ Serial.println(apiReturn->apiName.c_str());
+ udpBridge->sendResponse("fail", methodId);
+ break;
+ }
+}
+
+void resetChallenge()
+{
+ char buffer[32];
+ long challengeVal = random32();
+ challenge = "Sign This! ";
+ challenge += itoa(challengeVal, buffer, 16);
+}
+
+void blink()
+{
+ digitalWrite(BLUE_LED, blinkLEDOn);
+ blinkLEDOn = !blinkLEDOn;
+}
+
+bool iequals(const string &a, const string &b)
+{
+ unsigned int sz = a.size();
+ if (b.size() != sz)
+ return false;
+ for (unsigned int i = 0; i < sz; ++i)
+ if (tolower(a[i]) != tolower(b[i]))
+ return false;
+ return true;
+}
+
+boolean isValidAccount(std::string address)
+{
+ int accountsSize = (sizeof(allowedAccounts) / sizeof(*allowedAccounts));
+ for (int index = 0; index < accountsSize; index++)
+ {
+ if (iequals(address, allowedAccounts[index]))
+ return true;
+ }
+
+ return false;
+}
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 3/.gitignore b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 3/.gitignore
new file mode 100644
index 0000000..89cc49c
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 3/.gitignore
@@ -0,0 +1,5 @@
+.pio
+.vscode/.browse.c_cpp.db*
+.vscode/c_cpp_properties.json
+.vscode/launch.json
+.vscode/ipch
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 3/platformio.ini b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 3/platformio.ini
new file mode 100644
index 0000000..e850d49
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 3/platformio.ini
@@ -0,0 +1,20 @@
+;PlatformIO Project Configuration File
+;
+; Build options: build flags, source filter
+; Upload options: custom upload port, speed and extra flags
+; Library options: dependencies, extra library storages
+; Advanced options: extra scripting
+;
+; Please visit documentation for the other options and examples
+; https://docs.platformio.org/page/projectconf.html
+
+[env:esp32dev]
+platform = espressif32
+board = esp32dev
+framework = arduino
+
+monitor_speed = 115200
+
+lib_deps =
+ Web3E
+ Ticker
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 3/src/main.cpp b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 3/src/main.cpp
new file mode 100644
index 0000000..bb36155
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/examples/Wallet Bridge 3/src/main.cpp
@@ -0,0 +1,239 @@
+/**
+ * Part 3 of TokenScript example
+ *
+ * This demo builds on the example 2 adding Token checking.
+ * You can now transfer a token to another account and that account will be able to operate the device.
+ * To get up and running you will need to:
+ * 1. Complete Wallet Bridge 1 example to set up your contract
+ * 2. Fill in WiFi credentials.
+ * 3. Find the contract address from Example 1, setp 7 and add into the constant TOKEN_CONTRACT below
+ * 4. Flash the example and run on your ESP32/8266
+ * 5. Find the token in AlphaWallet and click through to 'Action'
+ * 6. Create a new account in AlphaWallet.
+ * 7. Transfer the token to that account (you will have to copy the destination account to clipboard, then go to the previous account and transfer)
+ * 8. Verify the new account with the token can operate the device
+ **/
+
+#include "esp_wifi.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+const char *ssid = "";
+const char *password = " s_apiRoutes;
+
+//Format for API call from wallet/utilitiy using the bridge is //?=&= etc.
+//When you call the API this is the extension you use EG www.bridgeserver.com/0x123456789ABCDEF0000/getChallenge
+void Initialize()
+{
+ s_apiRoutes["getChallenge"] = api_getChallenge;
+ s_apiRoutes["checkSignature"] = api_checkSignature;
+ s_apiRoutes["end"] = api_End;
+
+ random32v(micros()); //initial init of random seed AFTER wifi connection - since startup after wifi will be a different value of micros each start cycle
+}
+
+void setup()
+{
+ Serial.begin(115200);
+ keyID = new KeyID(&web3);
+ pinMode(BLUE_LED, OUTPUT);
+ digitalWrite(BLUE_LED, 0);
+ setupWifi();
+ Initialize(); //init after wifi setup to change startup delay
+
+ udpConnection = new UdpBridge();
+ udpConnection->setKey(keyID, &web3);
+ udpConnection->startConnection();
+ resetChallenge();
+}
+
+void loop()
+{
+ setupWifi();
+ delay(1);
+ udpConnection->checkClientAPI(&handleUDPAPI);
+ blinkTicker.update();
+}
+
+/* This routine is specifically geared for ESP32 perculiarities */
+/* You may need to change the code as required */
+/* It should work on 8266 as well */
+void setupWifi()
+{
+ if (WiFi.status() == WL_CONNECTED)
+ {
+ return;
+ }
+
+ Serial.println();
+ Serial.print("Connecting to ");
+ Serial.println(ssid);
+
+ if (WiFi.status() != WL_CONNECTED)
+ {
+ WiFi.persistent(false);
+ WiFi.mode(WIFI_OFF);
+ WiFi.mode(WIFI_STA);
+ WiFi.begin(ssid, password);
+ }
+
+ int wificounter = 0;
+ while (WiFi.status() != WL_CONNECTED && wificounter < 10)
+ {
+ delay(500);
+ Serial.print(".");
+ wificounter++;
+ }
+
+ if (wificounter >= 10)
+ {
+ Serial.println("Restarting ...");
+ ESP.restart(); //targetting 8266 & Esp32 - you may need to replace this
+ }
+
+ esp_wifi_set_ps(WIFI_PS_NONE);
+ delay(10);
+
+ Serial.println("");
+ Serial.println("WiFi connected.");
+ Serial.println("IP address: ");
+ Serial.println(WiFi.localIP());
+}
+
+// Handle API call from tokenscript
+// NB: every path must return a response to the server via udpBridge->sendResponse(, methodId);
+void handleUDPAPI(APIReturn *apiReturn, UdpBridge *udpBridge, int methodId)
+{
+ std::string address;
+ //handle the returned API call
+ Serial.println(apiReturn->apiName.c_str());
+
+ switch (s_apiRoutes[apiReturn->apiName.c_str()])
+ {
+ case api_getChallenge:
+ resetChallenge(); //generate a new challenge after each check. Advantage is that we've done a full refresh of the mersenne twister
+ Serial.println(challenge.c_str());
+ udpBridge->sendResponse(challenge, methodId);
+ break;
+ case api_checkSignature:
+ {
+ address = Crypto::ECRecoverFromPersonalMessage(&apiReturn->params["sig"], &challenge);
+ int intervalTime = strtol(apiReturn->params["interval"].c_str(), NULL, 10);
+ Serial.print("EC-Addr: ");
+ Serial.println(address.c_str());
+ if (hasToken(address)) //Check if address is admin or has token
+ {
+ blinkLEDOn = false;
+ if (intervalTime > 0)
+ blinkTicker.interval(intervalTime);
+ blinkTicker.start(); //Perform PASS action
+ udpBridge->sendResponse("pass", methodId);
+ }
+ else
+ {
+ udpBridge->sendResponse("fail : Invalid account", methodId);
+ }
+ }
+ break;
+ default:
+ Serial.println("Unknown API route: ");
+ Serial.println(apiReturn->apiName.c_str());
+ udpBridge->sendResponse("fail", methodId);
+ break;
+ }
+}
+
+void resetChallenge()
+{
+ char buffer[32];
+ long challengeVal = random32();
+ challenge = "Sign This! ";
+ challenge += itoa(challengeVal, buffer, 16);
+}
+
+void blink()
+{
+ blinkLEDOn = !blinkLEDOn;
+ digitalWrite(BLUE_LED, blinkLEDOn);
+}
+
+bool hasToken(const std::string &userAddress)
+{
+ boolean hasToken = false;
+ const char *contractAddr = TOKEN_CONTRACT;
+ Contract contract(&web3, contractAddr);
+ string func = "balanceOf(address)";
+ string param = contract.SetupContractData(func.c_str(), userAddress);
+ string result = contract.ViewCall(¶m);
+
+ Serial.println(result.c_str());
+
+ BYTE tokenVal[32];
+
+ //break down the result
+ vector *vectorResult = Util::InterpretVectorResult(&result);
+ for (auto itr = vectorResult->begin(); itr != vectorResult->end(); itr++)
+ {
+ Util::ConvertHexToBytes(tokenVal, itr->c_str(), 32);
+ if (hasValue(tokenVal, 32))
+ {
+ hasToken = true;
+ Serial.println("Has token");
+ break;
+ }
+ }
+
+ delete (vectorResult);
+ return hasToken;
+}
+
+bool hasValue(BYTE *value, int length)
+{
+ for (int i = 0; i < length; i++)
+ {
+ if ((*value++) != 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/keywords.txt b/Office Door/.pio/libdeps/esp32dev/Web3E/keywords.txt
new file mode 100644
index 0000000..70e0c98
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/keywords.txt
@@ -0,0 +1,96 @@
+#######################################
+
+# Syntax Coloring Map For Web3
+
+#######################################
+
+# Class (KEYWORD1)
+
+#######################################
+
+
+
+Web3 KEYWORD1
+
+
+
+#######################################
+
+# Methods and Functions (KEYWORD2)
+
+#######################################
+
+
+
+Web3ClientVersion KEYWORD2
+Web3Sha3 KEYWORD2
+NetVersion KEYWORD2
+NetListening KEYWORD2
+NetPeerCount KEYWORD2
+EthProtocolVersion KEYWORD2
+EthSyncing KEYWORD2
+EthMining KEYWORD2
+EthHashrate KEYWORD2
+EthGasPrice KEYWORD2
+EthAccounts KEYWORD2
+EthBlockNumber KEYWORD2
+EthGetBalance KEYWORD2
+EthGetTransactionCount KEYWORD2
+EthViewCall KEYWORD2
+UdpBridge KEYWORD2
+ScriptClient KEYWORD2
+
+EthCall KEYWORD2
+EthSendSignedTransaction KEYWORD2
+getDAppCode KEYWORD2
+
+getLongLong KEYWORD2
+getString KEYWORD2
+getInt KEYWORD2
+
+
+RlpEncodeWholeHeader KEYWORD2
+RlpEncodeWholeHeaderWithVector KEYWORD2
+RlpEncodeItem KEYWORD2
+RlpEncodeItemWithVector KEYWORD2
+ConvertNumberToUintArray KEYWORD2
+ConvertNumberToVector KEYWORD2
+ConvertCharStrToUintArray KEYWORD2
+ConvertHexToVector KEYWORD2
+ConvertToString KEYWORD2
+
+HexToInt KEYWORD2
+VectorToCharStr KEYWORD2
+VectorToString KEYWORD2
+ConvertBytesToHex KEYWORD2
+ConvertHexToBytes KEYWORD2
+ConvertBase KEYWORD2
+ConvertDecimal KEYWORD2
+ConvertString KEYWORD2
+ConvertHexToASCII KEYWORD2
+InterpretStringResult KEYWORD2
+InterpretVectorResult KEYWORD2
+PadForward KEYWORD2
+ConvertCharStrToVector32 KEYWORD2
+Crypto KEYWORD2
+Sign KEYWORD2
+SetPrivateKey KEYWORD2
+
+ECRecover KEYWORD2
+Verify KEYWORD2
+PrivateKeyToPublic KEYWORD2
+PublicKeyToAddress KEYWORD2
+Keccak256 KEYWORD2
+
+Contract KEYWORD2
+SetPrivateKey KEYWORD2
+SetupContractData KEYWORD2
+Call KEYWORD2
+ViewCall KEYWORD2
+SendTransaction KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
+BYTE LITERAL1
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/library.json b/Office Door/.pio/libdeps/esp32dev/Web3E/library.json
new file mode 100644
index 0000000..ea0fb6b
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/library.json
@@ -0,0 +1,31 @@
+{
+ "description": "Web3E (Ethereum Embedded) interface for devices running Arduino with easy to use TokenScript integration.",
+ "repository": {
+ "url": "https://github.com/AlphaWallet/Web3E",
+ "type": "git"
+ },
+ "platforms": [
+ "espressif32",
+ "espressif8266"
+ ],
+ "authors": [
+ {
+ "maintainer": true,
+ "name": "James Brown",
+ "url": "https://github.com/JamesSmartCell",
+ "email": "james.brown@alphawallet.com"
+ }
+ ],
+ "frameworks": "arduino",
+ "keywords": [
+ "Web3",
+ "Web3E",
+ "Ethereum",
+ "DApp",
+ "TokenScript",
+ "AlphaWallet"
+ ],
+ "name": "Web3E",
+ "version": "1.10",
+ "homepage": "https://alphawallet.com"
+}
\ No newline at end of file
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/library.properties b/Office Door/.pio/libdeps/esp32dev/Web3E/library.properties
new file mode 100644
index 0000000..ecd53b1
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/library.properties
@@ -0,0 +1,10 @@
+name=Web3E
+version=1.10
+author=James Brown
+maintainer=James Brown
+sentence=Web3E (Ethereum For Embedded) interface for Arduino and compitable devices.
+paragraph=Web3E (Ethereum For Embedded) interface for Arduino and compitable devices.
+category=Framework
+url=https://github.com/AlphaWallet/Web3E
+architectures=ESP32,ESP8266
+license=MIT
diff --git a/Office Door/.pio/libdeps/esp32dev/Web3E/src/APIReturn.h b/Office Door/.pio/libdeps/esp32dev/Web3E/src/APIReturn.h
new file mode 100644
index 0000000..a72a6dc
--- /dev/null
+++ b/Office Door/.pio/libdeps/esp32dev/Web3E/src/APIReturn.h
@@ -0,0 +1,16 @@
+#ifndef _API_RETURN_H
+#define _API_RETURN_H
+#include
+#include