From 4a727dc15954532a9689017b1be2279b8470f537 Mon Sep 17 00:00:00 2001 From: Gerardo Nardelli Date: Fri, 26 Jun 2020 12:47:45 -0300 Subject: [PATCH] Add ALM new styles (#373) --- .eslintignore | 1 + alm/public/index.html | 1 + alm/src/App.tsx | 5 +- alm/src/abis/BridgeValidators.ts | 319 +++++++ alm/src/abis/ForeignAMB.ts | 589 +++++++++++++ alm/src/abis/HomeAMB.ts | 777 ++++++++++++++++++ alm/src/abis/index.ts | 3 + alm/src/components/ConfirmationsContainer.tsx | 2 +- alm/src/components/Form.tsx | 24 +- alm/src/components/MainPage.tsx | 78 +- alm/src/components/MessageSelector.tsx | 2 +- alm/src/components/StatusContainer.tsx | 40 +- alm/src/components/commons/Button.tsx | 5 + alm/src/components/commons/ExplorerTxLink.tsx | 1 + alm/src/components/commons/LeftArrow.tsx | 2 +- alm/src/components/commons/Loading.tsx | 308 +++---- alm/src/hooks/useBridgeContracts.ts | 2 +- alm/src/hooks/useMessageConfirmations.ts | 2 +- alm/src/hooks/useValidatorContract.ts | 2 +- alm/src/index.tsx | 4 +- alm/src/themes/Dark.tsx | 1 + alm/src/themes/GlobalStyle.tsx | 3 +- alm/src/themes/Light.ts | 22 + alm/src/utils/getConfirmationsForTx.ts | 3 +- alm/src/utils/web3.ts | 2 +- 25 files changed, 1991 insertions(+), 207 deletions(-) create mode 100644 alm/src/abis/BridgeValidators.ts create mode 100644 alm/src/abis/ForeignAMB.ts create mode 100644 alm/src/abis/HomeAMB.ts create mode 100644 alm/src/abis/index.ts create mode 100644 alm/src/themes/Light.ts diff --git a/.eslintignore b/.eslintignore index 08d0d3d4..2fc7af03 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,3 +3,4 @@ submodules coverage lib dist +build diff --git a/alm/public/index.html b/alm/public/index.html index 89efacd5..36f04479 100644 --- a/alm/public/index.html +++ b/alm/public/index.html @@ -25,6 +25,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> + AMB Live Monitoring diff --git a/alm/src/App.tsx b/alm/src/App.tsx index 524c6e65..3ab3eaf6 100644 --- a/alm/src/App.tsx +++ b/alm/src/App.tsx @@ -1,11 +1,14 @@ import React from 'react' import { BrowserRouter } from 'react-router-dom' import { MainPage } from './components/MainPage' +import { StateProvider } from './state/StateProvider' function App() { return ( - + + + ) } diff --git a/alm/src/abis/BridgeValidators.ts b/alm/src/abis/BridgeValidators.ts new file mode 100644 index 00000000..10fa0b52 --- /dev/null +++ b/alm/src/abis/BridgeValidators.ts @@ -0,0 +1,319 @@ +import { AbiItem } from 'web3-utils' + +const abi: AbiItem[] = [ + { + constant: true, + inputs: [], + name: 'validatorCount', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getBridgeValidatorsInterfacesVersion', + outputs: [ + { + name: 'major', + type: 'uint64' + }, + { + name: 'minor', + type: 'uint64' + }, + { + name: 'patch', + type: 'uint64' + } + ], + payable: false, + stateMutability: 'pure', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'isInitialized', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'validatorList', + outputs: [ + { + name: '', + type: 'address[]' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_requiredSignatures', + type: 'uint256' + } + ], + name: 'setRequiredSignatures', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'requiredSignatures', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_address', + type: 'address' + } + ], + name: 'getNextValidator', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'owner', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_validator', + type: 'address' + } + ], + name: 'isValidatorDuty', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'deployedAtBlock', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'F_ADDR', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: 'newOwner', + type: 'address' + } + ], + name: 'transferOwnership', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_validator', + type: 'address' + } + ], + name: 'isValidator', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'validator', + type: 'address' + } + ], + name: 'ValidatorAdded', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'validator', + type: 'address' + } + ], + name: 'ValidatorRemoved', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: 'requiredSignatures', + type: 'uint256' + } + ], + name: 'RequiredSignaturesChanged', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: 'previousOwner', + type: 'address' + }, + { + indexed: false, + name: 'newOwner', + type: 'address' + } + ], + name: 'OwnershipTransferred', + type: 'event' + }, + { + constant: false, + inputs: [ + { + name: '_requiredSignatures', + type: 'uint256' + }, + { + name: '_initialValidators', + type: 'address[]' + }, + { + name: '_owner', + type: 'address' + } + ], + name: 'initialize', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_validator', + type: 'address' + } + ], + name: 'addValidator', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_validator', + type: 'address' + } + ], + name: 'removeValidator', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + } +] + +export default abi diff --git a/alm/src/abis/ForeignAMB.ts b/alm/src/abis/ForeignAMB.ts new file mode 100644 index 00000000..d49572e6 --- /dev/null +++ b/alm/src/abis/ForeignAMB.ts @@ -0,0 +1,589 @@ +import { AbiItem } from 'web3-utils' + +const abi: AbiItem[] = [ + { + constant: true, + inputs: [], + name: 'transactionHash', + outputs: [ + { + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_txHash', + type: 'bytes32' + } + ], + name: 'relayedMessages', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_sourceChainId', + type: 'uint256' + }, + { + name: '_destinationChainId', + type: 'uint256' + }, + { + name: '_validatorContract', + type: 'address' + }, + { + name: '_maxGasPerTx', + type: 'uint256' + }, + { + name: '_gasPrice', + type: 'uint256' + }, + { + name: '_requiredBlockConfirmations', + type: 'uint256' + }, + { + name: '_owner', + type: 'address' + } + ], + name: 'initialize', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'isInitialized', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'requiredBlockConfirmations', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_data', + type: 'bytes' + }, + { + name: '_signatures', + type: 'bytes' + } + ], + name: 'executeSignatures', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_data', + type: 'bytes' + } + ], + name: 'getMinimumGasUsage', + outputs: [ + { + name: 'gas', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'pure', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_messageId', + type: 'bytes32' + } + ], + name: 'failedMessageReceiver', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getBridgeMode', + outputs: [ + { + name: '_data', + type: 'bytes4' + } + ], + payable: false, + stateMutability: 'pure', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_sourceChainId', + type: 'uint256' + }, + { + name: '_destinationChainId', + type: 'uint256' + } + ], + name: 'setChainIds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_messageId', + type: 'bytes32' + } + ], + name: 'failedMessageSender', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'messageId', + outputs: [ + { + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_token', + type: 'address' + }, + { + name: '_to', + type: 'address' + } + ], + name: 'claimTokens', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_maxGasPerTx', + type: 'uint256' + } + ], + name: 'setMaxGasPerTx', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'requiredSignatures', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'owner', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'validatorContract', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'deployedAtBlock', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getBridgeInterfacesVersion', + outputs: [ + { + name: 'major', + type: 'uint64' + }, + { + name: 'minor', + type: 'uint64' + }, + { + name: 'patch', + type: 'uint64' + } + ], + payable: false, + stateMutability: 'pure', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'messageSourceChainId', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_blockConfirmations', + type: 'uint256' + } + ], + name: 'setRequiredBlockConfirmations', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_gasPrice', + type: 'uint256' + } + ], + name: 'setGasPrice', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_messageId', + type: 'bytes32' + } + ], + name: 'messageCallStatus', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'messageSender', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_contract', + type: 'address' + }, + { + name: '_data', + type: 'bytes' + }, + { + name: '_gas', + type: 'uint256' + } + ], + name: 'requireToPassMessage', + outputs: [ + { + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_messageId', + type: 'bytes32' + } + ], + name: 'failedMessageDataHash', + outputs: [ + { + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'maxGasPerTx', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: 'newOwner', + type: 'address' + } + ], + name: 'transferOwnership', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'gasPrice', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'messageId', + type: 'bytes32' + }, + { + indexed: false, + name: 'encodedData', + type: 'bytes' + } + ], + name: 'UserRequestForAffirmation', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'sender', + type: 'address' + }, + { + indexed: true, + name: 'executor', + type: 'address' + }, + { + indexed: true, + name: 'messageId', + type: 'bytes32' + }, + { + indexed: false, + name: 'status', + type: 'bool' + } + ], + name: 'RelayedMessage', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: 'gasPrice', + type: 'uint256' + } + ], + name: 'GasPriceChanged', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: 'requiredBlockConfirmations', + type: 'uint256' + } + ], + name: 'RequiredBlockConfirmationChanged', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: 'previousOwner', + type: 'address' + }, + { + indexed: false, + name: 'newOwner', + type: 'address' + } + ], + name: 'OwnershipTransferred', + type: 'event' + } +] + +export default abi diff --git a/alm/src/abis/HomeAMB.ts b/alm/src/abis/HomeAMB.ts new file mode 100644 index 00000000..8236299c --- /dev/null +++ b/alm/src/abis/HomeAMB.ts @@ -0,0 +1,777 @@ +import { AbiItem } from 'web3-utils' + +const abi: AbiItem[] = [ + { + constant: true, + inputs: [], + name: 'transactionHash', + outputs: [ + { + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_message', + type: 'bytes32' + } + ], + name: 'numMessagesSigned', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_hash', + type: 'bytes32' + }, + { + name: '_index', + type: 'uint256' + } + ], + name: 'signature', + outputs: [ + { + name: '', + type: 'bytes' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_sourceChainId', + type: 'uint256' + }, + { + name: '_destinationChainId', + type: 'uint256' + }, + { + name: '_validatorContract', + type: 'address' + }, + { + name: '_maxGasPerTx', + type: 'uint256' + }, + { + name: '_gasPrice', + type: 'uint256' + }, + { + name: '_requiredBlockConfirmations', + type: 'uint256' + }, + { + name: '_owner', + type: 'address' + } + ], + name: 'initialize', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'isInitialized', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'requiredBlockConfirmations', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_data', + type: 'bytes' + } + ], + name: 'getMinimumGasUsage', + outputs: [ + { + name: 'gas', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'pure', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_messageId', + type: 'bytes32' + } + ], + name: 'failedMessageReceiver', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getBridgeMode', + outputs: [ + { + name: '_data', + type: 'bytes4' + } + ], + payable: false, + stateMutability: 'pure', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_sourceChainId', + type: 'uint256' + }, + { + name: '_destinationChainId', + type: 'uint256' + } + ], + name: 'setChainIds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_hash', + type: 'bytes32' + } + ], + name: 'message', + outputs: [ + { + name: '', + type: 'bytes' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_messageId', + type: 'bytes32' + } + ], + name: 'failedMessageSender', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: 'signature', + type: 'bytes' + }, + { + name: 'message', + type: 'bytes' + } + ], + name: 'submitSignature', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'messageId', + outputs: [ + { + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_token', + type: 'address' + }, + { + name: '_to', + type: 'address' + } + ], + name: 'claimTokens', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_hash', + type: 'bytes32' + } + ], + name: 'numAffirmationsSigned', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_hash', + type: 'bytes32' + } + ], + name: 'affirmationsSigned', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_maxGasPerTx', + type: 'uint256' + } + ], + name: 'setMaxGasPerTx', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'requiredSignatures', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'owner', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_message', + type: 'bytes32' + } + ], + name: 'messagesSigned', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'validatorContract', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'deployedAtBlock', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getBridgeInterfacesVersion', + outputs: [ + { + name: 'major', + type: 'uint64' + }, + { + name: 'minor', + type: 'uint64' + }, + { + name: 'patch', + type: 'uint64' + } + ], + payable: false, + stateMutability: 'pure', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'messageSourceChainId', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_blockConfirmations', + type: 'uint256' + } + ], + name: 'setRequiredBlockConfirmations', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_gasPrice', + type: 'uint256' + } + ], + name: 'setGasPrice', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_messageId', + type: 'bytes32' + } + ], + name: 'messageCallStatus', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'messageSender', + outputs: [ + { + name: '', + type: 'address' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_contract', + type: 'address' + }, + { + name: '_data', + type: 'bytes' + }, + { + name: '_gas', + type: 'uint256' + } + ], + name: 'requireToPassMessage', + outputs: [ + { + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_messageId', + type: 'bytes32' + } + ], + name: 'failedMessageDataHash', + outputs: [ + { + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'maxGasPerTx', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: 'message', + type: 'bytes' + } + ], + name: 'executeAffirmation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: 'newOwner', + type: 'address' + } + ], + name: 'transferOwnership', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'gasPrice', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_number', + type: 'uint256' + } + ], + name: 'isAlreadyProcessed', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'pure', + type: 'function' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'messageId', + type: 'bytes32' + }, + { + indexed: false, + name: 'encodedData', + type: 'bytes' + } + ], + name: 'UserRequestForSignature', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'sender', + type: 'address' + }, + { + indexed: true, + name: 'executor', + type: 'address' + }, + { + indexed: true, + name: 'messageId', + type: 'bytes32' + }, + { + indexed: false, + name: 'status', + type: 'bool' + } + ], + name: 'AffirmationCompleted', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'signer', + type: 'address' + }, + { + indexed: false, + name: 'messageHash', + type: 'bytes32' + } + ], + name: 'SignedForUserRequest', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'signer', + type: 'address' + }, + { + indexed: false, + name: 'messageHash', + type: 'bytes32' + } + ], + name: 'SignedForAffirmation', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: 'authorityResponsibleForRelay', + type: 'address' + }, + { + indexed: false, + name: 'messageHash', + type: 'bytes32' + }, + { + indexed: false, + name: 'NumberOfCollectedSignatures', + type: 'uint256' + } + ], + name: 'CollectedSignatures', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: 'gasPrice', + type: 'uint256' + } + ], + name: 'GasPriceChanged', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: 'requiredBlockConfirmations', + type: 'uint256' + } + ], + name: 'RequiredBlockConfirmationChanged', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: 'previousOwner', + type: 'address' + }, + { + indexed: false, + name: 'newOwner', + type: 'address' + } + ], + name: 'OwnershipTransferred', + type: 'event' + } +] + +export default abi diff --git a/alm/src/abis/index.ts b/alm/src/abis/index.ts new file mode 100644 index 00000000..b4935963 --- /dev/null +++ b/alm/src/abis/index.ts @@ -0,0 +1,3 @@ +export { default as HOME_AMB_ABI } from './HomeAMB' +export { default as FOREIGN_AMB_ABI } from './ForeignAMB' +export { default as BRIDGE_VALIDATORS_ABI } from './BridgeValidators' diff --git a/alm/src/components/ConfirmationsContainer.tsx b/alm/src/components/ConfirmationsContainer.tsx index 94272c2b..ead23412 100644 --- a/alm/src/components/ConfirmationsContainer.tsx +++ b/alm/src/components/ConfirmationsContainer.tsx @@ -23,7 +23,7 @@ const StatusResultLabel = styled.label` ` const StyledConfirmationContainer = styled.div` - background-color: var(--color-primary); + background-color: var(--bg-color); padding: 10px; border-radius: 4px; ` diff --git a/alm/src/components/Form.tsx b/alm/src/components/Form.tsx index 9576c1c3..222dd447 100644 --- a/alm/src/components/Form.tsx +++ b/alm/src/components/Form.tsx @@ -12,27 +12,39 @@ const LabelText = styled.label` ` const Input = styled.input` - background-color: var(--color-primary); + background-color: var(--bg-color); color: var(--font-color); max-width: 100%; + border-color: var(--color-primary) !important; + &:hover, + &:active, + &:focus { + border-color: var(--button-color) !important; + } ` -export const Form = ({ onSubmit }: { onSubmit: ({ chainId, txHash }: FormSubmitParams) => void }) => { +export const Form = ({ + onSubmit, + lastUsedChain +}: { + onSubmit: ({ chainId, txHash }: FormSubmitParams) => void + lastUsedChain: number +}) => { const { home, foreign, loading } = useStateProvider() const { chainId: paramChainId, txHash: paramTxHash } = useParams() - const [chainId, setChainId] = useState(0) + const [chainId, setChainId] = useState(lastUsedChain) const [txHash, setTxHash] = useState('') useEffect( () => { if (!paramChainId) { - setChainId(foreign.chainId) + setChainId(lastUsedChain > 0 ? lastUsedChain : foreign.chainId) } else { setChainId(parseInt(paramChainId)) setTxHash(paramTxHash) } }, - [foreign.chainId, paramChainId, paramTxHash] + [foreign.chainId, paramChainId, paramTxHash, lastUsedChain] ) const formSubmit = (e: FormEvent) => { @@ -55,7 +67,7 @@ export const Form = ({ onSubmit }: { onSubmit: ({ chainId, txHash }: FormSubmitP />
-
diff --git a/alm/src/components/MainPage.tsx b/alm/src/components/MainPage.tsx index 9eeec836..61867b6e 100644 --- a/alm/src/components/MainPage.tsx +++ b/alm/src/components/MainPage.tsx @@ -1,9 +1,9 @@ -import React from 'react' +import React, { useState } from 'react' import styled from 'styled-components' -import { Route, useHistory, Link } from 'react-router-dom' +import { Route, useHistory } from 'react-router-dom' import { Form } from './Form' import { StatusContainer } from './StatusContainer' -import { StateProvider } from '../state/StateProvider' +import { useStateProvider } from '../state/StateProvider' const StyledMainPage = styled.div` text-align: center; @@ -11,15 +11,24 @@ const StyledMainPage = styled.div` ` const Header = styled.header` - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); + background-color: #001529; + color: #ffffff; + margin-bottom: 50px; ` -const Title = styled.p` - color: var(--font-color); +const HeaderContainer = styled.header` + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + font-size: 16px; + height: 64px; + line-height: 64px; + padding: 0 50px; + + @media (max-width: 600px) { + padding: 0 20px; + } ` export interface FormSubmitParams { @@ -29,23 +38,46 @@ export interface FormSubmitParams { export const MainPage = () => { const history = useHistory() + const { home, foreign } = useStateProvider() + const [selectedChainId, setSelectedChainId] = useState(0) + const [networkName, setNetworkName] = useState('') + + const setNetworkData = (chainId: number) => { + const network = chainId === home.chainId ? home.name : foreign.name + + setNetworkName(network) + setSelectedChainId(chainId) + } + const onFormSubmit = ({ chainId, txHash }: FormSubmitParams) => { + setNetworkData(chainId) + history.push(`/${chainId}/${txHash}`) } + const resetNetworkHeader = () => { + setNetworkName('') + } + + const setNetworkFromParams = (chainId: number) => { + setNetworkData(chainId) + } + return ( - - -
- - AMB Live Monitoring - -
-
- } /> - } /> -
-
-
+ +
+ + AMB Live Monitoring + {networkName} + +
+
+ } /> + } + /> +
+
) } diff --git a/alm/src/components/MessageSelector.tsx b/alm/src/components/MessageSelector.tsx index 32aaa3ec..7332e2b2 100644 --- a/alm/src/components/MessageSelector.tsx +++ b/alm/src/components/MessageSelector.tsx @@ -38,7 +38,7 @@ export const MessageSelector = ({ messages, onMessageSelected }: MessageSelector ))}
-
diff --git a/alm/src/components/StatusContainer.tsx b/alm/src/components/StatusContainer.tsx index a8d0d000..99e1d8a2 100644 --- a/alm/src/components/StatusContainer.tsx +++ b/alm/src/components/StatusContainer.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect } from 'react' import { Link, useHistory, useParams } from 'react-router-dom' import { useTransactionStatus } from '../hooks/useTransactionStatus' import { formatTxHash, getExplorerTxUrl, getTransactionStatusDescription, validTxHash } from '../utils/networks' @@ -12,9 +12,12 @@ import { LeftArrow } from './commons/LeftArrow' import styled from 'styled-components' const BackButton = styled.button` - color: var(--font-color); + color: var(--button-color); border-color: var(--font-color); margin-top: 10px; + &:focus { + outline: var(--button-color); + } ` const BackLabel = styled.label` @@ -22,7 +25,12 @@ const BackLabel = styled.label` cursor: pointer; ` -export const StatusContainer = () => { +export interface StatusContainerParam { + onBackToMain: () => void + setNetworkFromParams: (chainId: number) => void +} + +export const StatusContainer = ({ onBackToMain, setNetworkFromParams }: StatusContainerParam) => { const { home, foreign } = useStateProvider() const history = useHistory() const { chainId, txHash, messageIdParam } = useParams() @@ -36,6 +44,15 @@ export const StatusContainer = () => { const selectedMessageId = messageIdParam === undefined || messages[messageIdParam] === undefined ? -1 : messageIdParam + useEffect( + () => { + if (validChainId) { + setNetworkFromParams(parseInt(chainId)) + } + }, + [validChainId, chainId, setNetworkFromParams] + ) + if (!validParameters && home.chainId && foreign.chainId) { return (
@@ -75,15 +92,12 @@ export const StatusContainer = () => { {status && (

The request{' '} - - {displayExplorerLink && ( - - {formattedMessageId} - - )} - {!displayExplorerLink && } - {' '} - {displayedDescription} + {displayExplorerLink && ( + + {formattedMessageId} + + )} + {!displayExplorerLink && } {displayedDescription}

)} {displayMessageSelector && } @@ -92,7 +106,7 @@ export const StatusContainer = () => { )}
- + Search another transaction diff --git a/alm/src/components/commons/Button.tsx b/alm/src/components/commons/Button.tsx index faeecbb6..248590e9 100644 --- a/alm/src/components/commons/Button.tsx +++ b/alm/src/components/commons/Button.tsx @@ -2,4 +2,9 @@ import styled from 'styled-components' export const Button = styled.button` height: 36px; + color: var(--button-color); + border-color: var(--button-color); + &:focus { + outline: var(--button-color); + } ` diff --git a/alm/src/components/commons/ExplorerTxLink.tsx b/alm/src/components/commons/ExplorerTxLink.tsx index fd23a405..6c69383d 100644 --- a/alm/src/components/commons/ExplorerTxLink.tsx +++ b/alm/src/components/commons/ExplorerTxLink.tsx @@ -3,4 +3,5 @@ import styled from 'styled-components' export const ExplorerTxLink = styled.a` color: var(--link-color); text-decoration: underline; + font-weight: bold; ` diff --git a/alm/src/components/commons/LeftArrow.tsx b/alm/src/components/commons/LeftArrow.tsx index 1700297a..abef676c 100644 --- a/alm/src/components/commons/LeftArrow.tsx +++ b/alm/src/components/commons/LeftArrow.tsx @@ -12,7 +12,7 @@ export const LeftArrow = () => { width="24" height="24" viewBox="0 0 24 24" - fill={themeContext.fontColor} + fill={themeContext.buttonColor} > diff --git a/alm/src/components/commons/Loading.tsx b/alm/src/components/commons/Loading.tsx index 8519ede2..7adfc6c9 100644 --- a/alm/src/components/commons/Loading.tsx +++ b/alm/src/components/commons/Loading.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import React, { useContext } from 'react' +import { ThemeContext } from 'styled-components' export interface LoadingParams { width?: string @@ -6,156 +7,159 @@ export interface LoadingParams { displayMessage?: boolean } -export const Loading = ({ width = '50px', height = '50px', displayMessage = true }: LoadingParams) => ( -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {displayMessage && } -
-) +export const Loading = ({ width = '50px', height = '50px', displayMessage = true }: LoadingParams) => { + const themeContext = useContext(ThemeContext) + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {displayMessage && } +
+ ) +} export const SimpleLoading = () => diff --git a/alm/src/hooks/useBridgeContracts.ts b/alm/src/hooks/useBridgeContracts.ts index e82edff1..02baeeea 100644 --- a/alm/src/hooks/useBridgeContracts.ts +++ b/alm/src/hooks/useBridgeContracts.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react' -import { HOME_AMB_ABI, FOREIGN_AMB_ABI } from '../../../commons' +import { HOME_AMB_ABI, FOREIGN_AMB_ABI } from '../abis' import { FOREIGN_BRIDGE_ADDRESS, HOME_BRIDGE_ADDRESS } from '../config/constants' import { Contract } from 'web3-eth-contract' import Web3 from 'web3' diff --git a/alm/src/hooks/useMessageConfirmations.ts b/alm/src/hooks/useMessageConfirmations.ts index b63457c6..299bb387 100644 --- a/alm/src/hooks/useMessageConfirmations.ts +++ b/alm/src/hooks/useMessageConfirmations.ts @@ -200,7 +200,7 @@ export const useMessageConfirmations = ({ // To avoid making extra requests, this is only executed when validators finished waiting for blocks confirmations useEffect( () => { - if (!waitingBlocksResolved || !timestamp) return + if (!waitingBlocksResolved || !timestamp || !requiredSignatures) return const subscriptions: Array = [] diff --git a/alm/src/hooks/useValidatorContract.ts b/alm/src/hooks/useValidatorContract.ts index c4863574..07ea7cfb 100644 --- a/alm/src/hooks/useValidatorContract.ts +++ b/alm/src/hooks/useValidatorContract.ts @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react' import { Contract } from 'web3-eth-contract' import Web3 from 'web3' import { getRequiredSignatures, getValidatorAddress, getValidatorList } from '../utils/contract' -import { BRIDGE_VALIDATORS_ABI } from '../../../commons' +import { BRIDGE_VALIDATORS_ABI } from '../abis' import { useStateProvider } from '../state/StateProvider' import { TransactionReceipt } from 'web3-eth' diff --git a/alm/src/index.tsx b/alm/src/index.tsx index fdfebe3f..11563b05 100644 --- a/alm/src/index.tsx +++ b/alm/src/index.tsx @@ -3,11 +3,11 @@ import ReactDOM from 'react-dom' import { ThemeProvider } from 'styled-components' import { GlobalStyle } from './themes/GlobalStyle' import App from './App' -import Dark from './themes/Dark' +import Light from './themes/Light' ReactDOM.render( - + diff --git a/alm/src/themes/Dark.tsx b/alm/src/themes/Dark.tsx index 4bb63531..425e2658 100644 --- a/alm/src/themes/Dark.tsx +++ b/alm/src/themes/Dark.tsx @@ -1,6 +1,7 @@ const theme = { backgroundColor: '#121212', fontColor: '#f5f5f5', + buttonColor: '#f5f5f5', colorPrimary: '#272727', colorGrey: '#272727', colorLightGrey: '#272727', diff --git a/alm/src/themes/GlobalStyle.tsx b/alm/src/themes/GlobalStyle.tsx index 04485df0..a8e62da9 100644 --- a/alm/src/themes/GlobalStyle.tsx +++ b/alm/src/themes/GlobalStyle.tsx @@ -1,6 +1,6 @@ import { createGlobalStyle } from 'styled-components' -import theme from './Dark' +import theme from './Light' type ThemeType = typeof theme @@ -17,6 +17,7 @@ export const GlobalStyle = createGlobalStyle<{ theme: ThemeType }>` :root { --bg-color: ${props => props.theme.backgroundColor}; --font-color: ${props => props.theme.fontColor}; + --button-color: ${props => props.theme.buttonColor}; --color-primary: ${props => props.theme.colorPrimary}; --color-grey: ${props => props.theme.colorGrey}; --color-lightGrey: ${props => props.theme.colorLightGrey}; diff --git a/alm/src/themes/Light.ts b/alm/src/themes/Light.ts new file mode 100644 index 00000000..0c972e84 --- /dev/null +++ b/alm/src/themes/Light.ts @@ -0,0 +1,22 @@ +const theme = { + backgroundColor: '#FFFFFF', + fontColor: 'rgba(0, 0, 0, 0.65)', + buttonColor: '#1890ff', + colorPrimary: '#BDBDBD', + colorGrey: '#1890ff', + colorLightGrey: '#1890ff', + linkColor: '#1890ff', + success: { + textColor: '#388E3C', + backgroundColor: 'rgba(0,201,167,.1)' + }, + notRequired: { + textColor: '#77838f', + backgroundColor: 'rgba(119,131,143,.1)' + }, + failed: { + textColor: '#de4437', + backgroundColor: 'rgba(222,68,55,.1)' + } +} +export default theme diff --git a/alm/src/utils/getConfirmationsForTx.ts b/alm/src/utils/getConfirmationsForTx.ts index 1fa2d7c2..58e1ce62 100644 --- a/alm/src/utils/getConfirmationsForTx.ts +++ b/alm/src/utils/getConfirmationsForTx.ts @@ -190,11 +190,10 @@ export const getConfirmationsForTx = async ( setPendingConfirmations: Function, getSuccessTransactions: (args: GetFailedTransactionParams) => Promise ) => { - if (!web3 || !validatorList || !bridgeContract || !waitingBlocksResolved) return + if (!web3 || !validatorList || !validatorList.length || !bridgeContract || !waitingBlocksResolved) return // If all the information was not collected, then it should retry let shouldRetry = false - const hashMsg = web3.utils.soliditySha3Raw(messageData) let validatorConfirmations = await Promise.all( validatorList.map(getValidatorConfirmation(web3, hashMsg, bridgeContract, confirmationContractMethod)) diff --git a/alm/src/utils/web3.ts b/alm/src/utils/web3.ts index db91d59e..0ed56a0a 100644 --- a/alm/src/utils/web3.ts +++ b/alm/src/utils/web3.ts @@ -4,7 +4,7 @@ import { TransactionReceipt } from 'web3-eth' import { AbiItem } from 'web3-utils' import memoize from 'fast-memoize' import promiseRetry from 'promise-retry' -import { HOME_AMB_ABI, FOREIGN_AMB_ABI } from '../../../commons' +import { HOME_AMB_ABI, FOREIGN_AMB_ABI } from '../abis' export interface MessageObject { id: string