From 1c1a9d166d643b377eb96e7aa27cef63bb53ea6b Mon Sep 17 00:00:00 2001 From: nabarun Date: Tue, 4 Apr 2023 18:29:53 +0530 Subject: [PATCH] Only deploy contract and generate invite in mobymask container --- .../docker-compose-watcher-mobymask-v2.yml | 12 +- .../deploy-and-generate-invite.sh | 2 +- .../scripts/deploy-and-generate-invite.ts | 133 ++++++++++++++++++ 3 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 app/data/container-build/cerc-mobymask/scripts/deploy-and-generate-invite.ts diff --git a/app/data/compose/docker-compose-watcher-mobymask-v2.yml b/app/data/compose/docker-compose-watcher-mobymask-v2.yml index a3ba4eb6..e8597aa7 100644 --- a/app/data/compose/docker-compose-watcher-mobymask-v2.yml +++ b/app/data/compose/docker-compose-watcher-mobymask-v2.yml @@ -22,7 +22,6 @@ services: start_period: 10s mobymask: - restart: unless-stopped image: cerc/mobymask:local working_dir: /app/packages/server env_file: @@ -40,14 +39,9 @@ services: - ../config/wait-for-it.sh:/app/packages/server/wait-for-it.sh - ../config/watcher-mobymask-v2/secrets-template.json:/app/packages/server/secrets-template.json - ../config/watcher-mobymask-v2/deploy-and-generate-invite.sh:/app/packages/server/deploy-and-generate-invite.sh + - ../container-build/cerc-mobymask/scripts/deploy-and-generate-invite.ts:/app/packages/server/deploy-and-generate-invite.ts - moby_data_server:/app/packages/server - fixturenet_geth_accounts:/geth-accounts:ro - healthcheck: - test: ["CMD", "nc", "-v", "localhost", "3330"] - interval: 20s - timeout: 5s - retries: 15 - start_period: 10s extra_hosts: - "host.docker.internal:host-gateway" @@ -57,7 +51,7 @@ services: mobymask-watcher-db: condition: service_healthy mobymask: - condition: service_healthy + condition: service_completed_successfully image: cerc/watcher-mobymask-v2:local env_file: - ../config/watcher-mobymask-v2/optimism-params.env @@ -87,7 +81,7 @@ services: mobymask-watcher-server: condition: service_healthy mobymask: - condition: service_healthy + condition: service_completed_successfully image: cerc/mobymask-ui:local command: ["sh", "mobymask-app-start.sh"] volumes: diff --git a/app/data/config/watcher-mobymask-v2/deploy-and-generate-invite.sh b/app/data/config/watcher-mobymask-v2/deploy-and-generate-invite.sh index c0e16b28..6d53aeb4 100755 --- a/app/data/config/watcher-mobymask-v2/deploy-and-generate-invite.sh +++ b/app/data/config/watcher-mobymask-v2/deploy-and-generate-invite.sh @@ -19,4 +19,4 @@ jq --arg privateKey "$PRIVATE_KEY_DEPLOYER" '.privateKey = $privateKey' secrets- export L2_GETH_URL="http://${L2_GETH_HOST}:${L2_GETH_PORT}" jq --arg rpcUrl "$L2_GETH_URL" '.rpcUrl = $rpcUrl' secrets.json > secrets_updated.json && mv secrets_updated.json secrets.json -npm start +npx ts-node deploy-and-generate-invite.ts diff --git a/app/data/container-build/cerc-mobymask/scripts/deploy-and-generate-invite.ts b/app/data/container-build/cerc-mobymask/scripts/deploy-and-generate-invite.ts new file mode 100644 index 00000000..6895ac51 --- /dev/null +++ b/app/data/container-build/cerc-mobymask/scripts/deploy-and-generate-invite.ts @@ -0,0 +1,133 @@ +import { ethers } from "ethers"; +import fs from 'fs'; +import path from 'path'; + +// Workaround for missing types +const { generateUtil } = require('eth-delegatable-utils'); + +const phisherRegistryArtifacts = require('../hardhat/artifacts/contracts/PhisherRegistry.sol/PhisherRegistry.json'); +const { privateKey, rpcUrl, baseURI } = require('./secrets.json'); + + +const DEFAULT_BASE_URI = 'https://mobymask.com/#'; + +const configPath = path.join(__dirname, './config.json'); +const { abi } = phisherRegistryArtifacts; + +let provider = new ethers.providers.JsonRpcProvider(rpcUrl); +let signer: ethers.Wallet; +let _chainId: string; +let _name: string = 'MobyMask'; + +setupSigner() + .then(setupContract) + .then(signDelegation) + .catch(console.error); + +async function setupSigner () { + if (privateKey) { + signer = new ethers.Wallet(privateKey, provider) + } +} + +async function setupContract (): Promise { + try { + const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); + const { address, chainId, name } = config; + _name = name; + _chainId = chainId; + return attachToContract(address) + } catch (err) { + console.log('No config detected, deploying contract and creating one.'); + return deployContract() + } +} + +async function deployContract () { + const Registry = new ethers.ContractFactory(abi, phisherRegistryArtifacts.bytecode, signer); + const _name = 'MobyMask'; + const registry = await Registry.deploy(_name); + + const address = registry.address; + fs.writeFileSync(configPath, JSON.stringify({ address, name: _name, chainId: registry.deployTransaction.chainId }, null, 2)); + try { + return await registry.deployed(); + } catch (err) { + console.log('Deployment failed, trying to attach to existing contract.', err); + throw err; + } +} + +async function attachToContract(address: string) { + const Registry = new ethers.Contract(address, abi, signer); + const registry = await Registry.attach(address); + console.log('Attaching to existing contract'); + const deployed = await registry.deployed(); + return deployed; +} + +type Invocation = { + transaction: Transaction, + authority: SignedDelegation[], +}; + +type Transaction = { + to: string, + gasLimit: string, + data: string, +}; + +type SignedDelegation = { + delegation: Delegation, + signature: string, +} + +type Delegation = { + delegate: string, + authority: string, + caveats: Caveat[], +}; + +type Caveat = { + enforcer: string, + terms: string, +} + +type SignedInvocation = { + invocation: Invocation, + signature: string, +} + +async function signDelegation (registry: ethers.Contract) { + const { chainId } = await provider.getNetwork(); + const utilOpts = { + chainId, + verifyingContract: registry.address, + name: _name, + }; + console.log('util opts', utilOpts); + const util = generateUtil(utilOpts) + const delegate = ethers.Wallet.createRandom(); + + // Prepare the delegation message. + // This contract is also a revocation enforcer, so it can be used for caveats: + const delegation = { + delegate: delegate.address, + authority: '0x0000000000000000000000000000000000000000000000000000000000000000', + caveats: [{ + enforcer: registry.address, + terms: '0x0000000000000000000000000000000000000000000000000000000000000000', + }], + }; + + // Owner signs the delegation: + const signedDelegation = util.signDelegation(delegation, signer.privateKey); + const invitation = { + v:1, + signedDelegations: [signedDelegation], + key: delegate.privateKey, + } + console.log('A SIGNED DELEGATION/INVITE LINK:'); + console.log(JSON.stringify(invitation, null, 2)); + console.log((baseURI ?? DEFAULT_BASE_URI) + '/members?invitation=' + encodeURIComponent(JSON.stringify(invitation))); +}