diff --git a/.gitmodules b/.gitmodules
index 8bfcb16..a03cfb3 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,3 +7,6 @@
[submodule "public-gateway/lib/solmate"]
path = public-gateway/lib/solmate
url = https://github.com/transmissions11/solmate
+[submodule "TNLS-Gateways/public-gateway/lib/openzeppelin-contracts"]
+ path = TNLS-Gateways/public-gateway/lib/openzeppelin-contracts
+ url = https://github.com/OpenZeppelin/openzeppelin-contracts
diff --git a/TNLS-Clients/VRFDemo/.editorconfig b/TNLS-Clients/VRFDemo/.editorconfig
new file mode 100644
index 0000000..a148ba8
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/.editorconfig
@@ -0,0 +1,10 @@
+root = true
+
+[*]
+end_of_line = lf
+insert_final_newline = true
+
+[*.{js,json,yml,ts}]
+charset = utf-8
+indent_style = space
+indent_size = 2
diff --git a/TNLS-Clients/VRFDemo/.gitignore b/TNLS-Clients/VRFDemo/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/TNLS-Clients/VRFDemo/index.html b/TNLS-Clients/VRFDemo/index.html
new file mode 100644
index 0000000..5589ef6
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+ Snakepath Demo
+
+
+
+
+
+
+
+
+
+
diff --git a/TNLS-Clients/VRFDemo/package-lock.json b/TNLS-Clients/VRFDemo/package-lock.json
new file mode 100644
index 0000000..fb09a65
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/package-lock.json
@@ -0,0 +1,2325 @@
+{
+ "name": "create-payload",
+ "version": "0.1.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "create-payload",
+ "version": "0.1.0",
+ "dependencies": {
+ "buffer": "^6.0.3",
+ "ethers": "^5.6.9",
+ "secure-random": "^1.1.2"
+ },
+ "devDependencies": {
+ "@rushstack/eslint-patch": "^1.1.4",
+ "@types/node": "^16.11.47",
+ "@types/secure-random": "^1.1.0",
+ "eslint": "^8.21.0",
+ "eslint-plugin-vue": "^9.3.0",
+ "prettier": "^2.7.1",
+ "typescript": "^4.6.4",
+ "vite": "^3.1.0",
+ "vite-plugin-wasm": "^2"
+ },
+ "engines": {
+ "node": "20.x"
+ }
+ },
+ "node_modules/@aashutoshrathi/word-wrap": {
+ "version": "1.2.6",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.10.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.56.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@ethersproject/abi": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/address": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/constants": "^5.7.0",
+ "@ethersproject/hash": "^5.7.0",
+ "@ethersproject/keccak256": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/abstract-provider": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/networks": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/transactions": "^5.7.0",
+ "@ethersproject/web": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/abstract-signer": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-provider": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/address": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/keccak256": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/rlp": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/base64": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/basex": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/bignumber": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "bn.js": "^5.2.1"
+ }
+ },
+ "node_modules/@ethersproject/bytes": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/logger": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/constants": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/contracts": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abi": "^5.7.0",
+ "@ethersproject/abstract-provider": "^5.7.0",
+ "@ethersproject/abstract-signer": "^5.7.0",
+ "@ethersproject/address": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/constants": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/transactions": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/hash": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-signer": "^5.7.0",
+ "@ethersproject/address": "^5.7.0",
+ "@ethersproject/base64": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/keccak256": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/hdnode": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-signer": "^5.7.0",
+ "@ethersproject/basex": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/pbkdf2": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/sha2": "^5.7.0",
+ "@ethersproject/signing-key": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0",
+ "@ethersproject/transactions": "^5.7.0",
+ "@ethersproject/wordlists": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/json-wallets": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-signer": "^5.7.0",
+ "@ethersproject/address": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/hdnode": "^5.7.0",
+ "@ethersproject/keccak256": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/pbkdf2": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/random": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0",
+ "@ethersproject/transactions": "^5.7.0",
+ "aes-js": "3.0.0",
+ "scrypt-js": "3.0.1"
+ }
+ },
+ "node_modules/@ethersproject/keccak256": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "js-sha3": "0.8.0"
+ }
+ },
+ "node_modules/@ethersproject/logger": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/@ethersproject/networks": {
+ "version": "5.7.1",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/logger": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/pbkdf2": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/sha2": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/properties": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/logger": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/providers": {
+ "version": "5.7.2",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-provider": "^5.7.0",
+ "@ethersproject/abstract-signer": "^5.7.0",
+ "@ethersproject/address": "^5.7.0",
+ "@ethersproject/base64": "^5.7.0",
+ "@ethersproject/basex": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/constants": "^5.7.0",
+ "@ethersproject/hash": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/networks": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/random": "^5.7.0",
+ "@ethersproject/rlp": "^5.7.0",
+ "@ethersproject/sha2": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0",
+ "@ethersproject/transactions": "^5.7.0",
+ "@ethersproject/web": "^5.7.0",
+ "bech32": "1.1.4",
+ "ws": "7.4.6"
+ }
+ },
+ "node_modules/@ethersproject/random": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/rlp": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/sha2": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "hash.js": "1.1.7"
+ }
+ },
+ "node_modules/@ethersproject/signing-key": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "bn.js": "^5.2.1",
+ "elliptic": "6.5.4",
+ "hash.js": "1.1.7"
+ }
+ },
+ "node_modules/@ethersproject/solidity": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/keccak256": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/sha2": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/strings": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/constants": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/transactions": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/address": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/constants": "^5.7.0",
+ "@ethersproject/keccak256": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/rlp": "^5.7.0",
+ "@ethersproject/signing-key": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/units": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/constants": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/wallet": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-provider": "^5.7.0",
+ "@ethersproject/abstract-signer": "^5.7.0",
+ "@ethersproject/address": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/hash": "^5.7.0",
+ "@ethersproject/hdnode": "^5.7.0",
+ "@ethersproject/json-wallets": "^5.7.0",
+ "@ethersproject/keccak256": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/random": "^5.7.0",
+ "@ethersproject/signing-key": "^5.7.0",
+ "@ethersproject/transactions": "^5.7.0",
+ "@ethersproject/wordlists": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/web": {
+ "version": "5.7.1",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/base64": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0"
+ }
+ },
+ "node_modules/@ethersproject/wordlists": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/hash": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.11.13",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^2.0.1",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@rushstack/eslint-patch": {
+ "version": "1.6.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "16.18.68",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/secure-random": {
+ "version": "1.1.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/secure-random/node_modules/@types/node": {
+ "version": "20.10.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.2.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/acorn": {
+ "version": "8.11.2",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/aes-js": {
+ "version": "3.0.0",
+ "license": "MIT"
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/bech32": {
+ "version": "1.1.4",
+ "license": "MIT"
+ },
+ "node_modules/bn.js": {
+ "version": "5.2.1",
+ "license": "MIT"
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/brorand": {
+ "version": "1.1.0",
+ "license": "MIT"
+ },
+ "node_modules/buffer": {
+ "version": "6.0.3",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/elliptic": {
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
+ "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
+ "dependencies": {
+ "bn.js": "^4.11.9",
+ "brorand": "^1.1.0",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.1",
+ "inherits": "^2.0.4",
+ "minimalistic-assert": "^1.0.1",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "node_modules/elliptic/node_modules/bn.js": {
+ "version": "4.12.0",
+ "license": "MIT"
+ },
+ "node_modules/esbuild": {
+ "version": "0.15.18",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.15.18",
+ "@esbuild/linux-loong64": "0.15.18",
+ "esbuild-android-64": "0.15.18",
+ "esbuild-android-arm64": "0.15.18",
+ "esbuild-darwin-64": "0.15.18",
+ "esbuild-darwin-arm64": "0.15.18",
+ "esbuild-freebsd-64": "0.15.18",
+ "esbuild-freebsd-arm64": "0.15.18",
+ "esbuild-linux-32": "0.15.18",
+ "esbuild-linux-64": "0.15.18",
+ "esbuild-linux-arm": "0.15.18",
+ "esbuild-linux-arm64": "0.15.18",
+ "esbuild-linux-mips64le": "0.15.18",
+ "esbuild-linux-ppc64le": "0.15.18",
+ "esbuild-linux-riscv64": "0.15.18",
+ "esbuild-linux-s390x": "0.15.18",
+ "esbuild-netbsd-64": "0.15.18",
+ "esbuild-openbsd-64": "0.15.18",
+ "esbuild-sunos-64": "0.15.18",
+ "esbuild-windows-32": "0.15.18",
+ "esbuild-windows-64": "0.15.18",
+ "esbuild-windows-arm64": "0.15.18"
+ }
+ },
+ "node_modules/esbuild-darwin-arm64": {
+ "version": "0.15.18",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.56.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.56.0",
+ "@humanwhocodes/config-array": "^0.11.13",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-plugin-vue": {
+ "version": "9.19.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "natural-compare": "^1.4.0",
+ "nth-check": "^2.1.1",
+ "postcss-selector-parser": "^6.0.13",
+ "semver": "^7.5.4",
+ "vue-eslint-parser": "^9.3.1",
+ "xml-name-validator": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.5.0",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ethers": {
+ "version": "5.7.2",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abi": "5.7.0",
+ "@ethersproject/abstract-provider": "5.7.0",
+ "@ethersproject/abstract-signer": "5.7.0",
+ "@ethersproject/address": "5.7.0",
+ "@ethersproject/base64": "5.7.0",
+ "@ethersproject/basex": "5.7.0",
+ "@ethersproject/bignumber": "5.7.0",
+ "@ethersproject/bytes": "5.7.0",
+ "@ethersproject/constants": "5.7.0",
+ "@ethersproject/contracts": "5.7.0",
+ "@ethersproject/hash": "5.7.0",
+ "@ethersproject/hdnode": "5.7.0",
+ "@ethersproject/json-wallets": "5.7.0",
+ "@ethersproject/keccak256": "5.7.0",
+ "@ethersproject/logger": "5.7.0",
+ "@ethersproject/networks": "5.7.1",
+ "@ethersproject/pbkdf2": "5.7.0",
+ "@ethersproject/properties": "5.7.0",
+ "@ethersproject/providers": "5.7.2",
+ "@ethersproject/random": "5.7.0",
+ "@ethersproject/rlp": "5.7.0",
+ "@ethersproject/sha2": "5.7.0",
+ "@ethersproject/signing-key": "5.7.0",
+ "@ethersproject/solidity": "5.7.0",
+ "@ethersproject/strings": "5.7.0",
+ "@ethersproject/transactions": "5.7.0",
+ "@ethersproject/units": "5.7.0",
+ "@ethersproject/wallet": "5.7.0",
+ "@ethersproject/web": "5.7.1",
+ "@ethersproject/wordlists": "5.7.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.15.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.2.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.2.9",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "13.24.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/hash.js": {
+ "version": "1.1.7",
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hmac-drbg": {
+ "version": "1.0.1",
+ "license": "MIT",
+ "dependencies": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ignore": {
+ "version": "5.3.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "license": "ISC"
+ },
+ "node_modules/is-core-module": {
+ "version": "2.13.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/js-sha3": {
+ "version": "0.8.0",
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/minimalistic-assert": {
+ "version": "1.0.1",
+ "license": "ISC"
+ },
+ "node_modules/minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "license": "MIT"
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.7",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@aashutoshrathi/word-wrap": "^1.2.3",
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/postcss": {
+ "version": "8.4.32",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.0.13",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "2.8.8",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/resolve": {
+ "version": "1.22.8",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "2.79.1",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/scrypt-js": {
+ "version": "3.0.1",
+ "license": "MIT"
+ },
+ "node_modules/secure-random": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.2.tgz",
+ "integrity": "sha512-H2bdSKERKdBV1SwoqYm6C0y+9EA94v6SUBOWO8kDndc4NoUih7Dv6Tsgma7zO1lv27wIvjlD0ZpMQk7um5dheQ=="
+ },
+ "node_modules/semver": {
+ "version": "7.5.4",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "4.9.5",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "5.26.5",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vite": {
+ "version": "3.2.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.15.9",
+ "postcss": "^8.4.18",
+ "resolve": "^1.22.1",
+ "rollup": "^2.79.1"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ },
+ "peerDependencies": {
+ "@types/node": ">= 14",
+ "less": "*",
+ "sass": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-plugin-wasm": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "vite": "^3"
+ }
+ },
+ "node_modules/vue-eslint-parser": {
+ "version": "9.3.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4",
+ "eslint-scope": "^7.1.1",
+ "eslint-visitor-keys": "^3.3.0",
+ "espree": "^9.3.1",
+ "esquery": "^1.4.0",
+ "lodash": "^4.17.21",
+ "semver": "^7.3.6"
+ },
+ "engines": {
+ "node": "^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ws": {
+ "version": "7.4.6",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xml-name-validator": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/TNLS-Clients/VRFDemo/package.json b/TNLS-Clients/VRFDemo/package.json
new file mode 100644
index 0000000..aec79c1
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "create-payload",
+ "private": true,
+ "version": "0.1.0",
+ "type": "module",
+ "engines": {
+ "node": "20.x"
+ },
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "buffer": "^6.0.3",
+ "ethers": "^5.6.9",
+ "secure-random": "^1.1.2"
+ },
+ "devDependencies": {
+ "@rushstack/eslint-patch": "^1.1.4",
+ "@types/node": "^16.11.47",
+ "@types/secure-random": "^1.1.0",
+ "eslint": "^8.21.0",
+ "eslint-plugin-vue": "^9.3.0",
+ "prettier": "^2.7.1",
+ "typescript": "^4.6.4",
+ "vite": "^3.1.0",
+ "vite-plugin-wasm": "^2"
+ }
+}
diff --git a/TNLS-Clients/VRFDemo/public/vite.svg b/TNLS-Clients/VRFDemo/public/vite.svg
new file mode 100644
index 0000000..e7b8dfb
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/TNLS-Clients/VRFDemo/src/connect.ts b/TNLS-Clients/VRFDemo/src/connect.ts
new file mode 100644
index 0000000..e308f86
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/src/connect.ts
@@ -0,0 +1,16 @@
+import { ethers } from 'ethers';
+
+export function setupConnect(element: HTMLButtonElement) {
+ element.innerHTML = `Connect`
+ let myAddress : string
+ const connect = async () => {
+ // @ts-ignore
+ const provider = new ethers.providers.Web3Provider(window.ethereum);
+ [myAddress] = await provider.send("eth_requestAccounts", []);
+ element.innerHTML = `Connected`
+ document.querySelector('#account')!.innerHTML = `
+ Connected account: ${myAddress}
+ `
+ }
+ element.addEventListener('click', () => connect())
+}
\ No newline at end of file
diff --git a/TNLS-Clients/VRFDemo/src/main.ts b/TNLS-Clients/VRFDemo/src/main.ts
new file mode 100644
index 0000000..fa2a58f
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/src/main.ts
@@ -0,0 +1,48 @@
+import './style.css'
+import { setupConnect } from './connect'
+import { setupSubmit } from './submit'
+
+document.querySelector('#app')!.innerHTML = `
+
+
+
Sample Application: Random Number Generation using Secret VRF
+
+
+
+
+
+
+
+
+`
+setupSubmit(document.querySelector('#submit')!)
+setupConnect(document.querySelector('#connect')!)
\ No newline at end of file
diff --git a/TNLS-Clients/VRFDemo/src/style.css b/TNLS-Clients/VRFDemo/src/style.css
new file mode 100644
index 0000000..c8d6da9
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/src/style.css
@@ -0,0 +1,192 @@
+:root {
+ font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+#links {
+ display: flex;
+ place-items: center;
+ justify-content: center;
+}
+
+header h1 {
+ margin-bottom: 0;
+}
+
+header .card {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.4em 1.2em;
+ width: 20ch;
+ margin: 1em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+
+header .card:hover {
+ border-color: #646cff;
+}
+header .card:focus,
+header .card:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+ animation: fadeIn 2s;
+ -webkit-animation: fadeIn 2s;
+ -moz-animation: fadeIn 2s;
+ -o-animation: fadeIn 2s;
+ -ms-animation: fadeIn 2s;
+}
+
+.logo {
+ height: 6em;
+ padding: 1.5em;
+ will-change: filter;
+}
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.vanilla:hover {
+ filter: drop-shadow(0 0 2em #3178c6aa);
+}
+
+.card {
+ padding: 2em;
+}
+
+form {
+ display: inline-block;
+ align-items: center;
+ text-align: left;
+ max-width: 400px;
+}
+
+#preview {
+ max-width: 800px;
+ text-align: left;
+}
+#wallet {
+ position: absolute;
+ top: 6%;
+ right: 5%;
+}
+#account {
+ display: inline-block;
+ position: absolute;
+ text-shadow: 2px 2px 5px #242424;
+ top: 0;
+ right: 5%;
+}
+
+.read-the-docs {
+ color: #888;
+}
+
+input {
+ width: 100%;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+#submit {
+ margin-top: 0.6em;
+ width:100%;
+}
+
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
+}
+
+@keyframes fadeIn {
+ 0% { opacity: 0; }
+ 100% { opacity: 1; }
+}
+
+@-moz-keyframes fadeIn {
+ 0% { opacity: 0; }
+ 100% { opacity: 1; }
+}
+
+@-webkit-keyframes fadeIn {
+ 0% { opacity: 0; }
+ 100% { opacity: 1; }
+}
+
+@-o-keyframes fadeIn {
+ 0% { opacity: 0; }
+ 100% { opacity: 1; }
+}
+
+@-ms-keyframes fadeIn {
+ 0% { opacity: 0; }
+ 100% { opacity: 1; }
+}
\ No newline at end of file
diff --git a/TNLS-Clients/VRFDemo/src/submit.ts b/TNLS-Clients/VRFDemo/src/submit.ts
new file mode 100644
index 0000000..dd8d7f7
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/src/submit.ts
@@ -0,0 +1,84 @@
+import { ethers } from "ethers";
+import { arrayify, hexlify, SigningKey, keccak256, recoverPublicKey, computeAddress, sha256 } from "ethers/lib/utils";
+import { Buffer } from "buffer";
+import secureRandom from "secure-random";
+
+export function setupSubmit(element: HTMLButtonElement) {
+
+ const publicClientAddress = '0x62A76e4fFB2fa4b4FecA249cD1646C7fD1469319'
+ const routing_contract = "secret1zash9uk88y3sr8sjf0jdrlfsdsyuk6szvj99k6"
+ const routing_code_hash = "d94d2cd7d22f0509c7ca0b80d6576ecfebf2618c6026204c30a35f6624cb3230"
+
+ // @ts-ignore
+ const provider = new ethers.providers.Web3Provider(window.ethereum);
+
+ element.addEventListener("click", async function(event: Event){
+ event.preventDefault()
+ const [myAddress] = await provider.send("eth_requestAccounts", []);
+
+ const data = JSON.stringify({
+ numWords:20
+ })
+
+
+ // create the abi interface and encode the function data
+ const abi = [{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"callback","inputs":[{"name":"_taskId","type":"uint256","internalType":"uint256"},{"name":"_result","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"postExecution","inputs":[{"name":"_taskId","type":"uint256","internalType":"uint256"},{"name":"_sourceNetwork","type":"string","internalType":"string"},{"name":"_info","type":"tuple","internalType":"struct Gateway.PostExecutionInfo","components":[{"name":"payload_hash","type":"bytes32","internalType":"bytes32"},{"name":"result_hash","type":"bytes32","internalType":"bytes32"},{"name":"packet_hash","type":"bytes32","internalType":"bytes32"},{"name":"callback_address","type":"bytes20","internalType":"bytes20"},{"name":"callback_selector","type":"bytes4","internalType":"bytes4"},{"name":"callback_gas_limit","type":"bytes4","internalType":"bytes4"},{"name":"packet_signature","type":"bytes","internalType":"bytes"},{"name":"result_signature","type":"bytes","internalType":"bytes"},{"name":"result","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"requestRandomWords","inputs":[{"name":"_numWords","type":"uint32","internalType":"uint32"},{"name":"_callbackGasLimit","type":"uint32","internalType":"uint32"}],"outputs":[{"name":"requestId","type":"uint256","internalType":"uint256"}],"stateMutability":"payable"},{"type":"function","name":"send","inputs":[{"name":"_payloadHash","type":"bytes32","internalType":"bytes32"},{"name":"_userAddress","type":"address","internalType":"address"},{"name":"_routingInfo","type":"string","internalType":"string"},{"name":"_info","type":"tuple","internalType":"struct Gateway.ExecutionInfo","components":[{"name":"user_key","type":"bytes","internalType":"bytes"},{"name":"user_pubkey","type":"bytes","internalType":"bytes"},{"name":"routing_code_hash","type":"string","internalType":"string"},{"name":"handle","type":"string","internalType":"string"},{"name":"nonce","type":"bytes12","internalType":"bytes12"},{"name":"payload","type":"bytes","internalType":"bytes"},{"name":"payload_signature","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setContractAddressAndCodeHash","inputs":[{"name":"_contractAddress","type":"string","internalType":"string"},{"name":"_contractCodeHash","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setMasterVerificationAddress","inputs":[{"name":"_masterVerificationAddress","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateRoute","inputs":[{"name":"_route","type":"string","internalType":"string"},{"name":"_verificationAddress","type":"address","internalType":"address"},{"name":"_signature","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"ComputedResult","inputs":[{"name":"taskId","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"result","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"type":"event","name":"logCompletedTask","inputs":[{"name":"task_id","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"payload_hash","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"result_hash","type":"bytes32","indexed":false,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"logNewTask","inputs":[{"name":"task_id","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"source_network","type":"string","indexed":false,"internalType":"string"},{"name":"user_address","type":"address","indexed":false,"internalType":"address"},{"name":"routing_info","type":"string","indexed":false,"internalType":"string"},{"name":"payload_hash","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"info","type":"tuple","indexed":false,"internalType":"struct Gateway.ExecutionInfo","components":[{"name":"user_key","type":"bytes","internalType":"bytes"},{"name":"user_pubkey","type":"bytes","internalType":"bytes"},{"name":"routing_code_hash","type":"string","internalType":"string"},{"name":"handle","type":"string","internalType":"string"},{"name":"nonce","type":"bytes12","internalType":"bytes12"},{"name":"payload","type":"bytes","internalType":"bytes"},{"name":"payload_signature","type":"bytes","internalType":"bytes"}]}],"anonymous":false},{"type":"error","name":"CallbackError","inputs":[]},{"type":"error","name":"InvalidPacketSignature","inputs":[]},{"type":"error","name":"InvalidPayloadHash","inputs":[]},{"type":"error","name":"InvalidResultSignature","inputs":[]},{"type":"error","name":"InvalidSignature","inputs":[]},{"type":"error","name":"InvalidSignatureLength","inputs":[]},{"type":"error","name":"InvalidSignatureSValue","inputs":[]},{"type":"error","name":"TaskAlreadyCompleted","inputs":[]}]
+ const iface= new ethers.utils.Interface( abi )
+ const FormatTypes = ethers.utils.FormatTypes;
+ console.log(iface.format(FormatTypes.full))
+
+
+ const functionData = iface.encodeFunctionData("send",
+ [
+ _payloadHash,
+ _userAddress,
+ _routingInfo,
+ _info,
+ ]
+ )
+ console.log(functionData)
+
+ const tx_params = [
+ {
+ gas: '0x249F0', // 150000
+ to: publicClientAddress,
+ from: myAddress,
+ value: '0x00', // 0
+ data: functionData, // TODO figure out what this data is meant to be
+ },
+ ];
+
+ const txHash = await provider.send("eth_sendTransaction", tx_params);
+ console.log(txHash)
+
+ document.querySelector('#preview')!.innerHTML = `
+ Raw Payload
+ ${thePayload}
+
+ TNLS Payload
+ ${ciphertext.toString('base64')}
+
+ Payload Hash
+ ${payloadHash}
+
+
Payload Signature
+ ${payloadSignature}
+
+
Other Info
+
+
+ Public key used during encryption: ${userPublicKey}
+ Nonce used during encryption: ${nonce}
+
+
+
+ Transaction Parameters
+ Tx Hash: ${txHash}
+ Gateway Address (to check the postExecution callback) ${publicClientAddress}
+ ${JSON.stringify(tx_params)}
+ `
+ })
+}
+// Tx Hash: ${txHash}
+//Gateway Address (to check the postExecution callback) ${publicClientAddress}
+//${JSON.stringify(tx_params)}
\ No newline at end of file
diff --git a/TNLS-Clients/VRFDemo/src/vite-env.d.ts b/TNLS-Clients/VRFDemo/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/TNLS-Clients/VRFDemo/tsconfig.json b/TNLS-Clients/VRFDemo/tsconfig.json
new file mode 100644
index 0000000..c82b46b
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "useDefineForClassFields": true,
+ "module": "ESNext",
+ "lib": ["ESNext", "DOM"],
+ "moduleResolution": "Node",
+ "strict": true,
+ "sourceMap": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "esModuleInterop": true,
+ "noEmit": true,
+ "noUnusedLocals": false,
+ "noUnusedParameters": false,
+ "noImplicitReturns": true,
+ "skipLibCheck": true
+ },
+ "include": ["src"]
+}
diff --git a/TNLS-Clients/VRFDemo/vite.config.ts b/TNLS-Clients/VRFDemo/vite.config.ts
new file mode 100644
index 0000000..13298e7
--- /dev/null
+++ b/TNLS-Clients/VRFDemo/vite.config.ts
@@ -0,0 +1,13 @@
+import { fileURLToPath, URL } from "node:url";
+
+import { defineConfig } from "vite";
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [],
+ resolve: {
+ alias: {
+ "@": fileURLToPath(new URL("./src", import.meta.url)),
+ },
+ },
+});
diff --git a/TNLS-Clients/payload-encryption/package-lock.json b/TNLS-Clients/payload-encryption/package-lock.json
index baf7d57..fb09a65 100644
--- a/TNLS-Clients/payload-encryption/package-lock.json
+++ b/TNLS-Clients/payload-encryption/package-lock.json
@@ -1059,7 +1059,8 @@
},
"node_modules/elliptic": {
"version": "6.5.4",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
+ "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
"dependencies": {
"bn.js": "^4.11.9",
"brorand": "^1.1.0",
@@ -2034,7 +2035,8 @@
},
"node_modules/secure-random": {
"version": "1.1.2",
- "license": "MIT"
+ "resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.2.tgz",
+ "integrity": "sha512-H2bdSKERKdBV1SwoqYm6C0y+9EA94v6SUBOWO8kDndc4NoUih7Dv6Tsgma7zO1lv27wIvjlD0ZpMQk7um5dheQ=="
},
"node_modules/semver": {
"version": "7.5.4",
diff --git a/TNLS-Clients/payload-encryption/src/wasm/encrypt_payload_bg.wasm.gz b/TNLS-Clients/payload-encryption/src/wasm/encrypt_payload_bg.wasm.gz
deleted file mode 100644
index 1b5e9f4..0000000
Binary files a/TNLS-Clients/payload-encryption/src/wasm/encrypt_payload_bg.wasm.gz and /dev/null differ
diff --git a/TNLS-Gateways/public-gateway/lib/openzeppelin-contracts b/TNLS-Gateways/public-gateway/lib/openzeppelin-contracts
new file mode 160000
index 0000000..01ef448
--- /dev/null
+++ b/TNLS-Gateways/public-gateway/lib/openzeppelin-contracts
@@ -0,0 +1 @@
+Subproject commit 01ef448981be9d20ca85f2faf6ebdf591ce409f3
diff --git a/TNLS-Gateways/public-gateway/script/DeployScript.s.sol b/TNLS-Gateways/public-gateway/script/DeployScript.s.sol
index 939ce9a..02904f2 100644
--- a/TNLS-Gateways/public-gateway/script/DeployScript.s.sol
+++ b/TNLS-Gateways/public-gateway/script/DeployScript.s.sol
@@ -7,17 +7,23 @@ import "forge-std/console2.sol";
import "forge-std/Script.sol";
import {Gateway} from "../src/Gateway.sol";
import {RandomnessReciever} from "../src/RandomnessReciever.sol";
+import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
+import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
+
contract DeployScript is Script {
function setUp() public {}
- Gateway gatewayAddress;
+ address deployer;
+ ProxyAdmin proxyAdmin;
+ Gateway gatewayLogic;
+ TransparentUpgradeableProxy gatewayProxy;
RandomnessReciever randomnessAddress;
-
+
uint256 privKey = vm.envUint("ETH_PRIVATE_KEY");
- address deployer = vm.rememberKey(privKey);
- /// @notice Get the encoded hash of the inputs for signing
+
+ /// @notice Get the encoded hash of the inputs for signing
/// @param _routeInput Route name
/// @param _verificationAddressInput Address corresponding to the route
function getRouteHash(string memory _routeInput, address _verificationAddressInput) public pure returns (bytes32) {
@@ -35,24 +41,43 @@ contract DeployScript is Script {
}
function run() public {
+ deployer = vm.rememberKey(privKey);
vm.startBroadcast();
- gatewayAddress = new Gateway();
- randomnessAddress = new RandomnessReciever();
+ // Deploy ProxyAdmin
+ proxyAdmin = new ProxyAdmin(msg.sender);
+
+ // Deploy Gateway Logic Contract
+ gatewayLogic = new Gateway();
- console2.logAddress(address(gatewayAddress));
+ // Prepare initializer data for Gateway
+ bytes memory initializerData = abi.encodeWithSelector(
+ Gateway.initialize.selector
+ );
+
+ // Deploy TransparentUpgradeableProxy
+ gatewayProxy = new TransparentUpgradeableProxy(
+ address(gatewayLogic),
+ address(proxyAdmin),
+ initializerData
+ );
+
+ // Cast the proxy address to the Gateway interface
+ Gateway gateway = Gateway(address(gatewayProxy));
+
+ // Continue with your existing setup, but replace `gatewayAddress` with `gateway`
+ randomnessAddress = new RandomnessReciever();
+ console2.logAddress(address(gateway));
console2.logAddress(deployer);
- randomnessAddress.setGatewayAddress(address(gatewayAddress));
+ randomnessAddress.setGatewayAddress(address(gateway));
+
// Initialize master verification Address
- gatewayAddress.setMasterVerificationAddress(deployer);
- gatewayAddress.setContractAddressAndCodeHash("secret1u3zsgg680f0fmjv7w6qkhpe6sh78wngzevvlvd",
- "866d57146b2d9cccde295b57d84f22995568ffb5dc31a795e73f351bbfb19dfb");
- address verificationAddress = 0xBC0951b2f849020027921e7286aE134C8e159203;
- gatewayAddress.setChainidentifier("ethereum");
+ gateway.setMasterVerificationAddress(deployer); // Replace gatewayAddress with gateway
+ address verificationAddress = 0x09362bF5bbA88948f8B9fCDbB5B56C8CdD2403ad;
/// ------ Update Routes Param Setup ------- ///
- string memory route = "secret";
+ string memory route = "secret-4";
//address verificationAddress = vm.envAddress("SECRET_GATEWAY_ETH_ADDRESS");
// Update the route with with masterVerificationKey signature
@@ -62,8 +87,8 @@ contract DeployScript is Script {
(uint8 v, bytes32 r, bytes32 s) = vm.sign(privKey, ethSignedMessageHash);
bytes memory sig = abi.encodePacked(r, s, v);
- gatewayAddress.updateRoute(route, verificationAddress, sig);
+ gateway.updateRoute(route, verificationAddress, sig);
vm.stopBroadcast();
}
-}
+}
\ No newline at end of file
diff --git a/TNLS-Gateways/public-gateway/src/Gateway.sol b/TNLS-Gateways/public-gateway/src/Gateway.sol
index 8da7ed3..ed03b11 100644
--- a/TNLS-Gateways/public-gateway/src/Gateway.sol
+++ b/TNLS-Gateways/public-gateway/src/Gateway.sol
@@ -1,8 +1,26 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;
-contract Gateway {
+import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
+import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
+import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
+
+ /*//////////////////////////////////////////////////////////////
+ Gateway Proxy
+ //////////////////////////////////////////////////////////////*/
+contract GatewayProxy is TransparentUpgradeableProxy {
+ constructor(address _logic, address admin_, bytes memory _data) TransparentUpgradeableProxy(_logic, admin_, _data) {}
+}
+
+ /*//////////////////////////////////////////////////////////////
+ Secret VRF Interface
+ //////////////////////////////////////////////////////////////*/
+interface IRandomness {
+ function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) external;
+}
+
+contract Gateway is Initializable {
/*//////////////////////////////////////////////////////////////
Structs
//////////////////////////////////////////////////////////////*/
@@ -22,6 +40,13 @@ contract Gateway {
bytes payload_signature;
}
+ struct VRFSecretContract {
+ bytes32 contract_address_1;
+ bytes13 contract_address_2;
+ bytes32 contract_code_hash_1;
+ bytes32 contract_code_hash_2;
+ }
+
struct PostExecutionInfo {
bytes32 payload_hash;
bytes32 result_hash;
@@ -34,6 +59,21 @@ contract Gateway {
bytes result;
}
+ /*//////////////////////////////////////////////////////////////
+ State Variables
+ //////////////////////////////////////////////////////////////*/
+
+ address public owner;
+ address public masterVerificationAddress;
+ uint256 public taskId;
+
+ /// @dev Task ID ====> ReducedTask
+ mapping(uint256 => ReducedTask) public tasks;
+
+ /// @dev mapping of chain name string to the verification address
+ mapping(string => address) public route;
+
+
/*//////////////////////////////////////////////////////////////
Errors
//////////////////////////////////////////////////////////////*/
@@ -66,8 +106,11 @@ contract Gateway {
Helpers
//////////////////////////////////////////////////////////////*/
- /// @notice Splitting signature util for recovery
- /// @param _sig The signature
+ /// @notice Splits a signature into its r, s, and v components
+ /// @param _sig The signature to split
+ /// @return r The r component of the signature
+ /// @return s The s component of the signature
+ /// @return v The recovery byte of the signature
function splitSignature(bytes memory _sig) private pure returns (bytes32 r, bytes32 s, uint8 v) {
require(_sig.length == 65, "invalid signature length");
@@ -81,19 +124,20 @@ contract Gateway {
}
}
- /// @notice Recover the signer from message hash with a valid recovery ID
- /// @param _signedMessageHash the signed message hash
- /// @param _signature The signature that needs to be verified
+ /// @notice Recovers the signer address from a message hash and a signature
+ /// @param _signedMessageHash The hash of the signed message
+ /// @param _signature The signature
+ /// @return The address of the signer
function recoverSigner(bytes32 _signedMessageHash, bytes memory _signature) private pure returns (address) {
(bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature);
-
return ecrecover(_signedMessageHash, v, r, s);
}
- /// @notice Get the encoded hash of the inputs for signing
- /// @param _routeInput Route name
- /// @param _verificationAddressInput Address corresponding to the route
+ /// @notice Calculates the keccak256 hash of the route name and verification address
+ /// @param _routeInput The route name
+ /// @param _verificationAddressInput The verification address
+ /// @return The calculated hash
function getRouteHash(string calldata _routeInput, address _verificationAddressInput) private pure returns (bytes32) {
return keccak256(abi.encode(_routeInput, _verificationAddressInput));
}
@@ -102,6 +146,77 @@ contract Gateway {
return bytes31(data & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00);
}
+ function encodeBase64(bytes memory data) private pure returns (string memory) {
+ if (data.length == 0) return "";
+ string memory table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ string memory result = new string(4 * ((data.length + 2) / 3));
+ /// @solidity memory-safe-assembly
+ assembly {
+ let tablePtr := add(table, 1)
+ let resultPtr := add(result, 32)
+ for {
+ let dataPtr := data
+ let endPtr := add(data, mload(data))
+ } lt(dataPtr, endPtr) {
+ } {
+ dataPtr := add(dataPtr, 3)
+ let input := mload(dataPtr)
+ mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
+ resultPtr := add(resultPtr, 1)
+ mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
+ resultPtr := add(resultPtr, 1)
+ mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
+ resultPtr := add(resultPtr, 1)
+ mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
+ resultPtr := add(resultPtr, 1)
+ }
+ switch mod(mload(data), 3)
+ case 1 {
+ mstore8(sub(resultPtr, 1), 0x3d)
+ mstore8(sub(resultPtr, 2), 0x3d)
+ }
+ case 2 {
+ mstore8(sub(resultPtr, 1), 0x3d)
+ }
+ }
+ return result;
+ }
+
+ function uint256toString(uint256 value) private pure returns (string memory ptr) {
+ assembly {
+ ptr := add(mload(0x40), 128)
+ mstore(0x40, ptr)
+ let end := ptr
+ for {
+ let temp := value
+ ptr := sub(ptr, 1)
+ mstore8(ptr, add(48, mod(temp, 10)))
+ temp := div(temp, 10)
+ } temp {
+ temp := div(temp, 10)
+ } {
+ ptr := sub(ptr, 1)
+ mstore8(ptr, add(48, mod(temp, 10)))
+ }
+ let length := sub(end, ptr)
+ ptr := sub(ptr, 32)
+ mstore(ptr, length)
+ }
+ }
+
+ function bytesToUint256Array(bytes memory data) public pure returns (uint256[] memory) {
+ require(data.length % 32 == 0, "Data length must be a multiple of 32 bytes");
+
+ uint256[] memory uintArray;
+ assembly {
+ // Cast the bytes array to a uint256[] array by setting the appropriate length
+ uintArray := data
+ mstore(uintArray, div(mload(data), 32))
+ }
+ return uintArray;
+ }
+
+
/*//////////////////////////////////////////////////////////////
Events
//////////////////////////////////////////////////////////////*/
@@ -121,58 +236,46 @@ contract Gateway {
event ComputedResult(uint256 taskId, bytes result);
/*//////////////////////////////////////////////////////////////
- Constructor
+ Modifiers
//////////////////////////////////////////////////////////////*/
- address private immutable owner;
- string private chainIdentifier;
- string private routing_info;
- string private routing_code_hash;
-
- constructor() {
- owner = msg.sender;
- }
-
modifier onlyOwner() {
require(msg.sender == owner, "UNAUTHORIZED");
_;
}
+ /*//////////////////////////////////////////////////////////////
+ Initializer
+ //////////////////////////////////////////////////////////////*/
+
+ /// @notice Replaces the constructor for upgradeable contracts
+ function initialize() public initializer {
+ owner = msg.sender;
+ taskId = 1;
+ }
+
/*//////////////////////////////////////////////////////////////
Initialization
//////////////////////////////////////////////////////////////*/
- address private masterVerificationAddress;
-
/// @notice Initialize the verification address
/// @param _masterVerificationAddress The input address
function setMasterVerificationAddress(address _masterVerificationAddress) external onlyOwner {
masterVerificationAddress = _masterVerificationAddress;
}
- function setContractAddressAndCodeHash(string calldata _contractAddress, string calldata _codeHash) external onlyOwner {
- routing_info = _contractAddress;
- routing_code_hash = _codeHash;
- }
-
- function setChainidentifier(string calldata _chainIdentifier) external onlyOwner {
- chainIdentifier = _chainIdentifier;
- }
-
/*//////////////////////////////////////////////////////////////
Update Routes
//////////////////////////////////////////////////////////////*/
- /// @dev mapping of chain name string to the verification address
- mapping(string => address) private route;
-
/// @notice Updating the route
/// @param _route Route name
/// @param _verificationAddress Address corresponding to the route
/// @param _signature Signed hashed inputs(_route + _verificationAddress)
+
function updateRoute(string calldata _route, address _verificationAddress, bytes calldata _signature) external onlyOwner {
bytes32 routeHash = getRouteHash(_route, _verificationAddress);
- bytes32 ethSignedMessageHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", routeHash));
+ bytes32 ethSignedMessageHash = keccak256(bytes.concat("\x19Ethereum Signed Message:\n32", routeHash));
if (recoverSigner(ethSignedMessageHash, _signature) != masterVerificationAddress) {
revert InvalidSignature();
@@ -185,27 +288,26 @@ contract Gateway {
Pre Execution
//////////////////////////////////////////////////////////////*/
- uint256 private taskId = 1;
-
- /// @dev Task ID ====> Task
- mapping(uint256 => ReducedTask) private tasks;
-
- /// @notice Send
- /// @param _userAddress User address
- /// @param _sourceNetwork Source network of msg
- /// @param _routingInfo Routing info for computation
- /// @param _payloadHash Payload hash
- /// @param _info ExecutionInfo struct
+ /// @notice Creates a new task with provided execution info
+ /// @param _payloadHash Hash of the payload
+ /// @param _userAddress Address of the user
+ /// @param _routingInfo Routing information
+ /// @param _info Execution information
function send(
bytes32 _payloadHash,
address _userAddress,
- string calldata _sourceNetwork,
string calldata _routingInfo,
ExecutionInfo calldata _info)
- external {
+ external payable {
- // Payload hash signature verification
+ // Payload hash verification
+
+ if (keccak256(bytes.concat("\x19Ethereum Signed Message:\n32", keccak256(_info.payload))) != _payloadHash) {
+ revert InvalidPayloadHash();
+ }
+
+ // Payload signature verification
if (recoverSigner(_payloadHash, _info.payload_signature) != _userAddress) {
revert InvalidSignature();
@@ -216,7 +318,7 @@ contract Gateway {
emit logNewTask(
taskId,
- _sourceNetwork,
+ uint256toString(block.chainid),
_userAddress,
_routingInfo,
_payloadHash,
@@ -226,52 +328,62 @@ contract Gateway {
taskId++;
}
- function requestRandomWords(
+ /// @notice Requests random words for VRF
+ /// @param _numWords The number of random words requested
+ /// @param _callbackGasLimit The gas limit for the callback
+ /// @return requestId The request ID for the random words
+
+ function requestRandomness(
uint32 _numWords,
uint32 _callbackGasLimit
) external payable returns (uint256 requestId) {
- require(_numWords <= 50, "Too many words requested");
+ require(_numWords <= 2000, "Too many words requested");
- string memory callback_address = Encoders.encodeBase64(abi.encodePacked(msg.sender));
+ string memory callback_address = encodeBase64(bytes.concat(bytes20(msg.sender)));
- bytes memory payload = abi.encodePacked(
+ //use hard coded contract values instead of storage variables, saves around 8,500 in gas per TX.
+ //Since contract is upgradeable, we can update these values as well with it.
+ bytes memory _routing_info = "secret10hwq375veu49khx9dkcl6249n6fc2u5tft50jp";
+ bytes memory _routing_code_hash = "d94d2cd7d22f0509c7ca0b80d6576ecfebf2618c6026204c30a35f6624cb3230";
+
+ bytes memory payload = bytes.concat(
bytes23(0x7b2264617461223a227b5c226e756d576f7264735c223a), //bytes representation of '{"data":"{\"numWords\":' because solidity has problems with correct string escaping of numWords
- Encoders.uint256toString(_numWords),
- '}","routing_info": "',routing_info,
- '","routing_code_hash": "',routing_code_hash,
- '","user_address": "0x0000000000000000000000000000000000000000",', //unused user_address here
- '"user_key": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",', // 33 bytes of zeros in base64
- '"callback_address": "', callback_address,
+ bytes(uint256toString(_numWords)),
+ '}","routing_info": "',_routing_info,
+ '","routing_code_hash": "',_routing_code_hash,
+ '","user_address": "0x0000000000000000000000000000000000000000","user_key": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",', //unused user_address here + + 33 bytes of zeros in base64 for user_key
+ '"callback_address": "', bytes(callback_address),
'","callback_selector": "OLpGFA==",', // 0x38ba4614 hex value already converted into base64, callback_selector of the fullfillRandomWords function
- '"callback_gas_limit": ', Encoders.uint256toString(_callbackGasLimit),'}' // Corrected function call
+ '"callback_gas_limit": ', bytes(uint256toString(_callbackGasLimit)),'}'
);
- bytes32 payloadHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32",keccak256(payload)));
+ bytes32 payloadHash = keccak256(bytes.concat("\x19Ethereum Signed Message:\n32", keccak256(payload)));
// ExecutionInfo struct
ExecutionInfo memory executionInfo = ExecutionInfo({
user_key: new bytes(33), // equals AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA in base64
user_pubkey: new bytes(64), // Fill with 0 bytes
- routing_code_hash: routing_code_hash,
+ routing_code_hash: string(_routing_code_hash),
handle: "request_random",
nonce: bytes12(0),
- payload: payload, // Make sure payload is correctly formatted
+ payload: payload,
payload_signature: new bytes(64) // empty signature, fill with 0 bytes
});
+ uint256 oldTaskId = taskId;
// persisting the task
- tasks[taskId] = ReducedTask(sliceLastByte(payloadHash), false);
+ tasks[oldTaskId] = ReducedTask(sliceLastByte(payloadHash), false);
emit logNewTask(
taskId,
- chainIdentifier,
+ uint256toString(block.chainid),
msg.sender,
- routing_info,
+ string(_routing_info),
payloadHash,
executionInfo
);
- uint256 oldTaskId = taskId;
+
taskId++;
return oldTaskId;
}
@@ -280,158 +392,86 @@ contract Gateway {
Post Execution
//////////////////////////////////////////////////////////////*/
- /// @notice Post-Execution
- /// @param _taskId Task Id of the executed message
- /// @param _sourceNetwork Source network of the message
- /// @param _info PostExecutionInfo struct
+ /// @notice Handles the post-execution logic of a task
+ /// @param _taskId The ID of the task
+ /// @param _sourceNetwork The source network of the task
+ /// @param _info Post execution information
function postExecution(uint256 _taskId, string calldata _sourceNetwork, PostExecutionInfo calldata _info) external {
-
- ReducedTask storage task = tasks[_taskId];
+
+ ReducedTask storage task = tasks[_taskId];
- // Check if the task is already completed
- if (task.completed) {
- revert TaskAlreadyCompleted();
- }
-
- if (sliceLastByte(_info.payload_hash) != task.payload_hash_reduced) {
- revert InvalidPayloadHash();
- }
-
- address checkerAddress = route[_sourceNetwork];
-
- // Result signature verification
- if (recoverSigner(_info.result_hash, _info.result_signature) != checkerAddress) {
- revert InvalidResultSignature();
- }
+ // Check if the task is already completed
+ if (task.completed) {
+ revert TaskAlreadyCompleted();
+ }
- // Concatenate data elements
- bytes memory data = bytes.concat(
- bytes(_sourceNetwork),
- bytes(chainIdentifier),
- bytes32(_taskId),
- bytes32(_info.payload_hash),
- bytes(_info.result),
- bytes32(_info.result_hash),
- bytes20(_info.callback_address),
- bytes4(_info.callback_selector));
-
- // Perform Keccak256 + sha256 hash
- bytes32 packetHash = sha256(abi.encodePacked(keccak256(data)));
+ if (sliceLastByte(_info.payload_hash) != task.payload_hash_reduced) {
+ revert InvalidPayloadHash();
+ }
- // Packet signature verification
- if ((_info.packet_hash != packetHash) || recoverSigner(_info.packet_hash, _info.packet_signature) != checkerAddress) {
- revert InvalidPacketSignature();
- }
-
- task.completed = true;
+ address checkerAddress = route[_sourceNetwork];
- emit logCompletedTask(_taskId, _info.payload_hash, _info.result_hash);
+ // Result signature verification
+ if (recoverSigner(_info.result_hash, _info.result_signature) != checkerAddress) {
+ revert InvalidResultSignature();
+ }
- // Continue with the function execution
+ // Concatenate data elements
+ bytes memory data = bytes.concat(
+ bytes(_sourceNetwork),
+ bytes(uint256toString(block.chainid)),
+ bytes32(_taskId),
+ _info.payload_hash,
+ _info.result,
+ _info.result_hash,
+ _info.callback_address,
+ _info.callback_selector);
+
+ // Perform Keccak256 + sha256 hash
+ bytes32 packetHash = sha256(abi.encodePacked(keccak256(data)));
+
+ // Packet signature verification
+ if ((_info.packet_hash != packetHash) || recoverSigner(_info.packet_hash, _info.packet_signature) != checkerAddress) {
+ revert InvalidPacketSignature();
+ }
+
+ task.completed = true;
- // Additional conversion for Secret VRF into uint256[] if callback_selector matches the fullfillRandomWords selector.
+ emit logCompletedTask(_taskId, _info.payload_hash, _info.result_hash);
- bool val;
+ // Continue with the function execution
+ // Additional conversion for Secret VRF into uint256[] if callback_selector matches the fullfillRandomWords selector.
- if (_info.callback_selector == bytes4(0x38ba4614)) {
- uint256[] memory randomWords = Encoders.bytesToUint256Array(_info.result);
- (val, ) = address(_info.callback_address).call{gas: uint32(_info.callback_gas_limit)}(
- abi.encodeWithSelector(_info.callback_selector, _taskId, randomWords)
- );
- }
- else {
- (val, ) = address(_info.callback_address).call{gas: uint32(_info.callback_gas_limit)}(
- abi.encodeWithSelector(_info.callback_selector, _taskId, _info.result)
- );
- }
- if (!val) {
- revert CallbackError();
+ if (_info.callback_selector == bytes4(0x38ba4614)) {
+ uint256[] memory randomWords = bytesToUint256Array(_info.result);
+ IRandomness randomness = IRandomness(address(_info.callback_address));
+ randomness.fulfillRandomWords(_taskId, randomWords);
+ }
+ else {
+ bool val;
+ (val, ) = address(_info.callback_address).call{gas: uint32(_info.callback_gas_limit)}(
+ abi.encodeWithSelector(_info.callback_selector, _taskId, _info.result)
+ );
+ if (!val) {
+ revert CallbackError();
+ }
+ }
}
-}
/*//////////////////////////////////////////////////////////////
Callback
//////////////////////////////////////////////////////////////*/
- /// @param _taskId Task Id of the computation
- /// @param _result Privately computed result
+ /// @notice Emits an event with the result of a computation
+ /// @param _taskId The ID of the task
+ /// @param _result The result of the computation
+
function callback(uint256 _taskId, bytes calldata _result) external {
emit ComputedResult(_taskId, _result);
}
-}
-library Encoders {
-
- function encodeBase64(bytes memory data) internal pure returns (string memory) {
- if (data.length == 0) return "";
- string memory table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- string memory result = new string(4 * ((data.length + 2) / 3));
- /// @solidity memory-safe-assembly
- assembly {
- let tablePtr := add(table, 1)
- let resultPtr := add(result, 32)
- for {
- let dataPtr := data
- let endPtr := add(data, mload(data))
- } lt(dataPtr, endPtr) {
- } {
- dataPtr := add(dataPtr, 3)
- let input := mload(dataPtr)
- mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
- resultPtr := add(resultPtr, 1)
- mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
- resultPtr := add(resultPtr, 1)
- mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
- resultPtr := add(resultPtr, 1)
- mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
- resultPtr := add(resultPtr, 1)
- }
- switch mod(mload(data), 3)
- case 1 {
- mstore8(sub(resultPtr, 1), 0x3d)
- mstore8(sub(resultPtr, 2), 0x3d)
- }
- case 2 {
- mstore8(sub(resultPtr, 1), 0x3d)
- }
- }
- return result;
- }
-
- function uint256toString(uint256 value) external pure returns (string memory ptr) {
- assembly {
- ptr := add(mload(0x40), 128)
- mstore(0x40, ptr)
- let end := ptr
- for {
- let temp := value
- ptr := sub(ptr, 1)
- mstore8(ptr, add(48, mod(temp, 10)))
- temp := div(temp, 10)
- } temp {
- temp := div(temp, 10)
- } {
- ptr := sub(ptr, 1)
- mstore8(ptr, add(48, mod(temp, 10)))
- }
- let length := sub(end, ptr)
- ptr := sub(ptr, 32)
- mstore(ptr, length)
- }
- }
-
- function bytesToUint256Array(bytes memory data) internal pure returns (uint256[] memory) {
- require(data.length % 32 == 0, "Data length must be a multiple of 32 bytes");
- uint256[] memory uintArray = new uint256[](data.length / 32);
- uint256 dataLength = data.length;
- assembly {
- let dataPtr := add(data, 0x20)
- let uintArrayPtr := add(uintArray, 0x20)
- for { let i := 0 } lt(i, dataLength) { i := add(i, 32) } {
- mstore(add(uintArrayPtr, i), mload(add(dataPtr, i)))
- }
- }
- return uintArray;
- }
+ /*//////////////////////////////////////////////////////////////
+ New Functions for Upgradeability
+ //////////////////////////////////////////////////////////////*/
}
\ No newline at end of file
diff --git a/TNLS-Gateways/public-gateway/src/RandomnessReciever.sol b/TNLS-Gateways/public-gateway/src/RandomnessReciever.sol
index aa3f435..079831e 100644
--- a/TNLS-Gateways/public-gateway/src/RandomnessReciever.sol
+++ b/TNLS-Gateways/public-gateway/src/RandomnessReciever.sol
@@ -1,10 +1,14 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;
+interface ISecretVRF {
+ function requestRandomness(uint32 _numWords, uint32 _callbackGasLimit) external payable returns (uint256 requestId);
+}
+
contract RandomnessReciever {
- address private RNGGateway;
- address private immutable owner;
+ address public VRFGateway;
+ address public immutable owner;
constructor() {
owner = msg.sender;
@@ -15,34 +19,26 @@ contract RandomnessReciever {
_;
}
- function setGatewayAddress(address _RNGGateway) external onlyOwner {
- RNGGateway = _RNGGateway;
+ function setGatewayAddress(address _VRFGateway) external onlyOwner {
+ VRFGateway = _VRFGateway;
}
- function requestRandomWordsTest() external {
- bool success;
- bytes memory data;
- uint256 requestId;
- uint32 numWords = 50; // can be up to 50 words
- uint32 callbackGasLimit = 1000000;
- (success, data) = RNGGateway.call(abi.encodeWithSelector(bytes4(0x967b2017), numWords, callbackGasLimit));
- require(success, "External call failed");
- if (data.length == 32) {
- assembly {requestId := mload(add(data, 32))}
- } else {
- revert("Data returned is too short");
- }
+ function requestRandomnessTest() external {
+ uint32 numWords = 2000; // can be up to 2000 words
+ uint32 callbackGasLimit = 2000000;
+ ISecretVRF vrfContract = ISecretVRF(VRFGateway);
+ uint256 requestId = vrfContract.requestRandomness(numWords, callbackGasLimit);
}
event fulfilledRandomWords(uint256 requestId, uint256[] randomWords);
/*//////////////////////////////////////////////////////////////
- Callback
+ fulfillRandomWords Callback
//////////////////////////////////////////////////////////////*/
- function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external {
- require(msg.sender == address(RNGGateway), "only Secret Gateway can fulfill");
+ function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) external {
+ require(msg.sender == address(VRFGateway), "only Secret Gateway can fulfill");
//do your custom stuff here.
emit fulfilledRandomWords(requestId, randomWords);
}
diff --git a/TNLS-Gateways/public-gateway/test/Contract.t.sol b/TNLS-Gateways/public-gateway/test/Contract.t.sol
index 8222191..26607c6 100644
--- a/TNLS-Gateways/public-gateway/test/Contract.t.sol
+++ b/TNLS-Gateways/public-gateway/test/Contract.t.sol
@@ -51,7 +51,6 @@ contract ContractTest is Test {
require(_sig.length == 65, "invalid signature length");
assembly {
-
// first 32 bytes, after the length prefix
r := mload(add(_sig, 32))
// second 32 bytes
@@ -135,16 +134,12 @@ contract ContractTest is Test {
Test Cases
//////////////////////////////////////////////////////////////*/
- function test_CheckTheOwnerOfTheContract() public {
- address owner = gateway.owner();
- assertEq(deployer, owner);
- }
function test_OwnerCanInitialize() public {
vm.prank(deployer);
address tempAddress = vm.addr(5);
- gateway.initialize(tempAddress);
+ gateway.setMasterVerificationAddress(tempAddress);
assertEq(tempAddress, gateway.masterVerificationAddress());
}
@@ -152,7 +147,7 @@ contract ContractTest is Test {
function testFail_NonOwnerCannotInitialize() public {
vm.startPrank(notOwner);
address tempAddress = vm.addr(5);
- gateway.initialize(tempAddress);
+ gateway.setMasterVerificationAddress(tempAddress);
vm.stopPrank();
}
@@ -161,10 +156,10 @@ contract ContractTest is Test {
vm.prank(deployer);
address masterVerificationKey = vm.addr(2);
- gateway.initialize(masterVerificationKey);
+ gateway.setMasterVerificationAddress(masterVerificationKey);
address SampleVerificationAddress = vm.addr(6);
- string memory sampleRoute = "secret";
+ string memory sampleRoute = "secret-4";
// Update the route with with masterVerificationKey signature
bytes32 routeHash = getRouteHash(sampleRoute, SampleVerificationAddress);
@@ -176,7 +171,7 @@ contract ContractTest is Test {
vm.prank(deployer);
gateway.updateRoute(sampleRoute, SampleVerificationAddress, sig);
- assertEq(gateway.route("secret"), SampleVerificationAddress);
+ assertEq(gateway.route("secret-4"), SampleVerificationAddress);
}
function testFail_OwnerCannotUpdateRouteWithoutValidSignature() public {
@@ -184,7 +179,7 @@ contract ContractTest is Test {
vm.prank(deployer);
address masterVerificationKey = vm.addr(5);
- gateway.initialize(masterVerificationKey);
+ gateway.setMasterVerificationAddress(masterVerificationKey);
address SampleVerificationAddress = vm.addr(6);
string memory sampleRoute = "secret";
@@ -207,7 +202,7 @@ contract ContractTest is Test {
vm.prank(deployer);
address masterVerificationKey = vm.addr(5);
- gateway.initialize(masterVerificationKey);
+ gateway.setMasterVerificationAddress(masterVerificationKey);
address SampleVerificationAddress = vm.addr(6);
string memory sampleRoute = "secret";
@@ -227,7 +222,7 @@ contract ContractTest is Test {
vm.prank(deployer);
address masterVerificationKey = vm.addr(5);
- gateway.initialize(masterVerificationKey);
+ gateway.setMasterVerificationAddress(masterVerificationKey);
address SampleVerificationAddress = vm.addr(6);
string memory sampleRoute = "secret";
@@ -272,16 +267,10 @@ contract ContractTest is Test {
gateway.send(vm.addr(5), sourceNetwork,routingInfo, payloadHash, assembledInfo, vm.addr(7), callbackSelector, 300000 );
- (bytes32 tempPayloadHash,,,,) = gateway.tasks(1);
+ (bytes31 tempPayloadHash,,,,) = gateway.tasks(1);
assertEq(tempPayloadHash, payloadHash, "payloadHash failed");
- (,address tempCallbackAddress,,,) = gateway.tasks(1);
- assertEq(tempCallbackAddress, vm.addr(7), "tempCallbackAddress failed");
-
- (,,bytes4 tempCallbackSelector,,) = gateway.tasks(1);
- assertEq(tempCallbackSelector, callbackSelector, "callbackSelector failed");
-
- (,,,, bool tempCompleted) = gateway.tasks(1);
+ (,bool tempCompleted) = gateway.tasks(1);
assertEq(tempCompleted, false, "tempCompleted failed");
}
@@ -435,7 +424,7 @@ contract ContractTest is Test {
vm.prank(deployer);
address masterVerificationKey = vm.addr(2);
- gateway.initialize(masterVerificationKey);
+ gateway.setMasterVerificationAddress(masterVerificationKey);
address SampleVerificationAddress = 0x49F7552065228e5abF44e144cc750aEA4F711Dc3;
string memory sampleRoute = "secret";
diff --git a/TNLS-Gateways/secret/contract.wasm.gz b/TNLS-Gateways/secret/contract.wasm.gz
index d8161bc..e746e6b 100644
Binary files a/TNLS-Gateways/secret/contract.wasm.gz and b/TNLS-Gateways/secret/contract.wasm.gz differ
diff --git a/TNLS-Gateways/secret/src/contract.rs b/TNLS-Gateways/secret/src/contract.rs
index 9b7cbbe..ba4e735 100644
--- a/TNLS-Gateways/secret/src/contract.rs
+++ b/TNLS-Gateways/secret/src/contract.rs
@@ -23,6 +23,7 @@ use sha3::{Digest, Keccak256};
/// pad handle responses and log attributes to blocks of 256 bytes to prevent leaking info based on
/// response size
pub const BLOCK_SIZE: usize = 256;
+pub const CHAIN_ID: &str = "secret-4";
#[cfg(feature = "contract")]
////////////////////////////////////// Init ///////////////////////////////////////
@@ -92,7 +93,7 @@ pub fn execute(
match msg {
ExecuteMsg::Input { inputs } => {
pad_handle_result(pre_execution(deps, env, inputs), BLOCK_SIZE)
- }
+ },
ExecuteMsg::Output { outputs } => post_execution(deps, env, outputs),
}
}
@@ -320,7 +321,7 @@ fn post_execution(deps: DepsMut, _env: Env, msg: PostExecutionMsg) -> StdResult<
// create hash of entire packet (used to verify the message wasn't modified in transit)
let data = [
- "secret".as_bytes(), // source network
+ CHAIN_ID.as_bytes(), // source network
routing_info.as_bytes(), // task_destination_network
task_id_padded.as_slice(), //msg.task_id.to_be_bytes().as_slice(), // task ID
// task_info.payload.as_slice(), // payload (original encrypted or unencrypted payload)
@@ -422,7 +423,7 @@ fn post_execution(deps: DepsMut, _env: Env, msg: PostExecutionMsg) -> StdResult<
let callback_gas_limit = format!("0x{}", task_info.callback_gas_limit.to_be_bytes().encode_hex::());
Ok(Response::new()
- .add_attribute_plaintext("source_network", "secret")
+ .add_attribute_plaintext("source_network", CHAIN_ID)
.add_attribute_plaintext("task_destination_network", routing_info)
.add_attribute_plaintext("task_id", msg.task_id.to_string())
.add_attribute_plaintext("payload_hash", payload_hash)
diff --git a/TNLS-Relayers/base_interface.py b/TNLS-Relayers/base_interface.py
index da1677d..761f73e 100644
--- a/TNLS-Relayers/base_interface.py
+++ b/TNLS-Relayers/base_interface.py
@@ -16,8 +16,8 @@
}
-task_keys_to_msg = {'ethereum': eth_task_keys_to_msg}
-task_keys_in_order = {'ethereum': ['_taskId', '_sourceNetwork', '_info']}
+task_keys_to_msg = {'11155111': eth_task_keys_to_msg}
+task_keys_in_order = {'11155111': ['_taskId', '_sourceNetwork', '_info']}
def to_dict(dict_to_parse, key_type=""):
@@ -96,7 +96,7 @@ def __init__(self, task_dict):
task_dict['routing_info'] = task_dict['routing_info'].split(':')[1]
task_dict['task_destination_network'] = self.task_destination_network
elif 'routing_info' in task_dict and 'secret' in task_dict['routing_info']:
- self.task_destination_network = 'secret'
+ self.task_destination_network = 'secret-4'
task_dict['task_destination_network'] = self.task_destination_network
elif 'routing_info' in task_dict:
self.task_destination_network = task_dict['routing_info']
@@ -117,7 +117,7 @@ def __str__(self):
return json.dumps(new_task_list)
return json.dumps(to_dict(new_task_dict, key_type=self.task_destination_network))
else:
- if 'task_id' in self.task_data and self.task_destination_network == 'secret':
+ if 'task_id' in self.task_data and self.task_destination_network == 'secret-4':
self.task_data['task_id'] = int(self.task_data['task_id'])
return json.dumps(to_dict(self.task_data))
diff --git a/TNLS-Relayers/eth_interface.py b/TNLS-Relayers/eth_interface.py
index 3546d74..c037b78 100644
--- a/TNLS-Relayers/eth_interface.py
+++ b/TNLS-Relayers/eth_interface.py
@@ -56,7 +56,7 @@ def create_transaction(self, contract_function, *args, **kwargs):
if kwargs is {}:
tx = contract_function(*args).build_transaction({
'from': self.address,
- 'gas': 1000000,
+ 'gas': 3000000,
'nonce': nonce,
#'maxFeePerGas': self.provider.eth.max_priority_fee
#'maxPriorityFeePerGas': self.provider.eth.max_priority_fee,
@@ -64,14 +64,14 @@ def create_transaction(self, contract_function, *args, **kwargs):
elif len(args) == 0:
tx = contract_function(**kwargs).build_transaction({
'from': self.address,
- 'gas': 1000000,
+ 'gas': 3000000,
'nonce': nonce,
#'maxPriorityFeePerGas': self.provider.eth.max_priority_fee,
})
else:
tx = contract_function(*args, **kwargs).build_transaction({
'from': self.address,
- 'gas': 1000000,
+ 'gas': 3000000,
'nonce': nonce,
#'maxPriorityFeePerGas': self.provider.eth.max_priority_fee,
})
diff --git a/TNLS-Relayers/relayer.py b/TNLS-Relayers/relayer.py
index c916303..d066452 100644
--- a/TNLS-Relayers/relayer.py
+++ b/TNLS-Relayers/relayer.py
@@ -71,7 +71,7 @@ def __init__(self,
# Setup keys dictionary
keys_dict = {
- 'secret': {
+ 'secret-4': {
'verification': verification_key,
'encryption': encryption_key
}
@@ -90,7 +90,7 @@ def __init__(self,
scrt_tuple = (scrt_base_interface, scrt_contract_interface, 'wasm', 'inputs')
# Create the dictionary and add the tuple
- self.dict_of_names_to_interfaces = {'ethereum': eth_tuple,'secret': scrt_tuple}
+ self.dict_of_names_to_interfaces = {'11155111': eth_tuple,'secret-4': scrt_tuple}
"""
Args:
@@ -136,11 +136,11 @@ def process_transaction(self, transaction, name, contract_interface, evt_name):
def poll_for_transactions(self):
for name, (chain_interface, contract_interface, evt_name, _) in self.dict_of_names_to_interfaces.items():
- if name == 'secret':
+ if name == 'secret-4' or name == 'pulsar-3':
continue
prev_height = self.dict_of_names_to_blocks[name]
curr_height = chain_interface.get_last_block()
- #curr_height = 5021399
+ #curr_height = 5029638
if prev_height is None:
prev_height = curr_height - 1
@@ -176,7 +176,7 @@ def route_transaction(self, task: Task):
return
contract_for_txn = self.dict_of_names_to_interfaces[task.task_destination_network][1]
function_name = self.dict_of_names_to_interfaces[task.task_destination_network][3]
- if task.task_destination_network == 'secret':
+ if task.task_destination_network == 'secret-4':
ntasks, _ = contract_for_txn.call_function(function_name, str(task))
self.task_list.extend(ntasks)
else:
diff --git a/TNLS-Samples/RNG/contract.wasm.gz b/TNLS-Samples/RNG/contract.wasm.gz
index 71db02e..bcdd186 100644
Binary files a/TNLS-Samples/RNG/contract.wasm.gz and b/TNLS-Samples/RNG/contract.wasm.gz differ
diff --git a/TNLS-Samples/RNG/src/contract.rs b/TNLS-Samples/RNG/src/contract.rs
index b5efd81..41f1895 100644
--- a/TNLS-Samples/RNG/src/contract.rs
+++ b/TNLS-Samples/RNG/src/contract.rs
@@ -37,8 +37,7 @@ pub fn instantiate(
#[entry_point]
pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult {
let response = match msg {
- ExecuteMsg::Input { message } => try_handle(deps, env, info, message),
- ExecuteMsg::ReturnRandom {} => return_random(deps, env, info),
+ ExecuteMsg::Input { message } => try_handle(deps, env, info, message)
};
pad_handle_result(response, BLOCK_SIZE)
}
@@ -46,7 +45,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S
#[entry_point]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult {
let response = match msg {
- QueryMsg::Query {} => try_query(deps),
+ QueryMsg::Query {} => try_query(deps)
};
pad_query_result(response, BLOCK_SIZE)
}
@@ -78,20 +77,6 @@ fn try_handle(
}
}
-fn return_random(
- _deps: DepsMut,
- env: Env,
- _info: MessageInfo,
-) -> StdResult {
-
- let result = match env.block.random {
- Some(random_value) => random_value.to_base64(),
- None => return Err(StdError::generic_err("No random value available")),
- };
-
- Ok(Response::new().add_attribute("random", result))
-}
-
fn try_random(
deps: DepsMut,
env: Env,
diff --git a/TNLS-Samples/RNG/src/msg.rs b/TNLS-Samples/RNG/src/msg.rs
index 0143d22..112069a 100644
--- a/TNLS-Samples/RNG/src/msg.rs
+++ b/TNLS-Samples/RNG/src/msg.rs
@@ -15,14 +15,13 @@ pub struct InstantiateMsg {
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
- Input { message: PrivContractHandleMsg },
- ReturnRandom {},
+ Input { message: PrivContractHandleMsg }
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum QueryMsg {
- Query {},
+ Query {}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
diff --git a/TNLS-Samples/RNG/tests/integration.ts b/TNLS-Samples/RNG/tests/integration.ts
index 641072d..a1d1d1d 100644
--- a/TNLS-Samples/RNG/tests/integration.ts
+++ b/TNLS-Samples/RNG/tests/integration.ts
@@ -46,8 +46,6 @@ const initializeClient = async (endpoint: string, chainId: string) => {
const initializeGateway = async (
client: SecretNetworkClient,
contractPath: string,
- scrtRngHash: string,
- scrtRngAddress: string,
) => {
const wasmCode = fs.readFileSync(contractPath);
console.log("Uploading gateway contract...");
@@ -91,11 +89,7 @@ const initializeGateway = async (
{
sender: client.address,
code_id: codeId,
- init_msg: {
- entropy: "secret",
- rng_hash: scrtRngHash,
- rng_addr: scrtRngAddress,
- },
+ init_msg: {},
code_hash: contractCodeHash.code_hash,
label: "My contract" + Math.ceil(Math.random() * 10000), // The label should be unique for every contract, add random string in order to maintain uniqueness
},
@@ -170,7 +164,7 @@ const initializeScrtRng = async (
{
sender: client.address,
code_id: codeId,
- init_msg: { initseed: "secret", prng_seed: "secret" },
+ init_msg: {},
code_hash: contractCodeHash.code_hash,
label: "My contract" + Math.ceil(Math.random() * 10000), // The label should be unique for every contract, add random string in order to maintain uniqueness
},