diff --git a/package.json b/package.json index 24f12329..dbccfbb2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "filecoin-verifier-frontend", - "version": "1.2.7", + "version": "1.3.3", "private": true, "dependencies": { "@emotion/react": "^11.0.0-next.13", diff --git a/src/App.scss b/src/App.scss index 6d2ba84a..20b4b833 100644 --- a/src/App.scss +++ b/src/App.scss @@ -1604,6 +1604,30 @@ } } + .tabs { + position: absolute; + height: 25px; + left: 1px; + top: 440px; + background: #ffffff; + width: 100%; + text-align: center; + border-bottom: 1px solid #ccc; + display: flex; + justify-content: space-evenly; + color: #33a7ff; + + .tab { + cursor: pointer; + } + } + + .multisiginput { + width: 200px; + margin-top: 5px; + padding: 5px; + } + .buttons { position: absolute; height: 96px; diff --git a/src/App.tsx b/src/App.tsx index 4ceb549c..5f34613c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -111,8 +111,8 @@ class App extends Component<{}, States> { } } return '0' - } - + } + updateSearch = () => { this.context.search(this.state.search) } @@ -200,6 +200,25 @@ class App extends Component<{}, States> { /> + {this.context.wallet.multisig && this.context.viewroot === false ? + +
Multisig address
+
+
+
+ Datacap: {bytesToiB(this.getVerifierAmount(this.context.wallet.multisigAddress))} + {this.context.wallet.multisig ? + network + : null} +
+
+ {this.context.wallet.multisigAddress.length > 20 ? addressFilter(this.context.wallet.multisigAddress): this.context.wallet.multisigAddress} + +
+
+
+
+ : null}
Account addresses
{this.context.wallet.accounts.map((account: any, index: number) => { return
@@ -224,7 +243,7 @@ class App extends Component<{}, States> {
: null}
{this.context.viewroot ? 'Rootkey Holder ID' : 'Approved Notary ID'}
-
{addressFilter(this.context.wallet.activeAccount)}
+
{addressFilter(this.context.wallet.activeAccount)}, {this.context.wallet.multisig && this.context.viewroot === false ? this.context.wallet.multisigAddress.length > 20 ? addressFilter(this.context.wallet.multisigAddress): this.context.wallet.multisigAddress : null}
diff --git a/src/components/Pagination.tsx b/src/components/Pagination.tsx index 87d13122..b49de94d 100644 --- a/src/components/Pagination.tsx +++ b/src/components/Pagination.tsx @@ -19,7 +19,8 @@ class Pagination extends Component { state = { initialIndex: 0, actualPage: 1, - pages: [] + pages: [], + } componentDidMount() { diff --git a/src/components/overview/Notary.tsx b/src/components/overview/Notary.tsx index ef6c55e5..f4360ac7 100644 --- a/src/components/overview/Notary.tsx +++ b/src/components/overview/Notary.tsx @@ -142,7 +142,12 @@ export default class Notary extends Component { if (address.length < 12) { address = await this.context.wallet.api.actorKey(address) } - let messageID = await this.context.wallet.api.verifyClient(address, BigInt(datacap), this.context.wallet.walletIndex) + let messageID + if(this.context.wallet.multisig){ + messageID = await this.context.wallet.api.multisigVerifyClient(this.context.wallet.multisigID, address, BigInt(datacap), this.context.wallet.walletIndex) + } else { + messageID = await this.context.wallet.api.verifyClient(address, BigInt(datacap), this.context.wallet.walletIndex) + } // github update this.context.updateGithubVerified(request.number, messageID, address, request.data.datacap) diff --git a/src/context/Wallet/WalletProvider.tsx b/src/context/Wallet/WalletProvider.tsx index 900771c2..898be9d8 100644 --- a/src/context/Wallet/WalletProvider.tsx +++ b/src/context/Wallet/WalletProvider.tsx @@ -27,6 +27,10 @@ interface WalletProviderStates { message: string loadWallet: any dispatchNotification: any + multisig: boolean + multisigAddress: string + multisigActor: string + multisigID: string } type Props = { @@ -52,7 +56,7 @@ class WalletProvider extends React.Component { this.setState(state, resolve) }); } - loadLedger = async () => { + loadLedger = async (options: any = {}) => { try { const wallet = new LedgerWallet() await wallet.loadWallet(this.state.networkIndex) @@ -71,6 +75,23 @@ class WalletProvider extends React.Component { } } } + let multisigInfo: any = {} + let multisigActor: string = '' + let multisigID: string = '' + if (options.multisig) { + try { + if (options.multisigAddress.length > 20) { + multisigID = await wallet.api.actorAddress(options.multisigAddress) + } else { + multisigID = options.multisigAddress + } + multisigInfo = await wallet.api.multisigInfo(multisigID) + multisigActor = await wallet.api.actorKey(multisigInfo.signers[0]) + } catch (e) { + this.state.dispatchNotification('Multisig not found') + return false + } + } await this.setStateAsync({ isLogged: true, isLoading: false, @@ -95,7 +116,11 @@ class WalletProvider extends React.Component { }, activeAccount: lastWallet ? lastWallet : accounts[0], accounts, - accountsActive + accountsActive, + multisig: options.multisig ? true : false, + multisigAddress: options.multisig ? options.multisigAddress : '', + multisigActor: options.multisig ? multisigActor : '', + multisigID: multisigID }) // this.loadGithub() return true @@ -109,7 +134,7 @@ class WalletProvider extends React.Component { } } - loadBurner = async () => { + loadBurner = async (options: any = {}) => { try { const wallet = new BurnerWallet() await wallet.loadWallet(this.state.networkIndex) @@ -128,6 +153,23 @@ class WalletProvider extends React.Component { } } } + let multisigInfo: any = {} + let multisigActor: string = '' + let multisigID: string = '' + if (options.multisig) { + try { + if (options.multisigAddress.length > 20) { + multisigID = await wallet.api.actorAddress(options.multisigAddress) + } else { + multisigID = options.multisigAddress + } + multisigInfo = await wallet.api.multisigInfo(multisigID) + multisigActor = await wallet.api.actorKey(multisigInfo.signers[0]) + } catch (e) { + this.state.dispatchNotification('Multisig not found') + return false + } + } this.setStateAsync({ isLogged: true, isLoading: false, @@ -138,7 +180,11 @@ class WalletProvider extends React.Component { walletIndex: walletCookieIndex !== -1 ? walletCookieIndex : 0, activeAccount: lastWallet ? lastWallet : accounts[0], accounts, - accountsActive + accountsActive, + multisig: options.multisig ? true : false, + multisigAddress: options.multisig ? options.multisigAddress : '', + multisigActor: options.multisig ? multisigActor : '', + multisigID: multisigID }) return true // this.loadGithub() @@ -213,14 +259,14 @@ class WalletProvider extends React.Component { }, balance: 0, message: '', - loadWallet: async (type: string) => { + loadWallet: async (type: string, options: any = {}) => { this.setState({ isLoading: true }) switch (type) { case 'Ledger': - const resLedger = await this.loadLedger() + const resLedger = await this.loadLedger(options) return resLedger case 'Burner': - const resBurner = await this.loadBurner() + const resBurner = await this.loadBurner(options) return resBurner default: return false @@ -235,7 +281,11 @@ class WalletProvider extends React.Component { timeout: 5000 } }); - } + }, + multisig: false, + multisigAddress: '', + multisigActor: '', + multisigID: '' } render() { diff --git a/src/modals/AddClientModal.tsx b/src/modals/AddClientModal.tsx index 768d0136..ae58aada 100644 --- a/src/modals/AddClientModal.tsx +++ b/src/modals/AddClientModal.tsx @@ -58,7 +58,14 @@ class AddClientModal extends Component { console.log("datacap: " + this.state.datacap) console.log("fullDatacap: " + fullDatacap) - let messageID = await this.context.wallet.api.verifyClient(this.state.address, BigInt(fullDatacap), this.context.wallet.walletIndex); + + let messageID + if(this.context.wallet.multisig){ + messageID =await this.context.wallet.api.multisigVerifyClient(this.context.wallet.multisigID, this.state.address, BigInt(fullDatacap), this.context.wallet.walletIndex) + } else { + messageID = await this.context.wallet.api.verifyClient(this.state.address, BigInt(fullDatacap), this.context.wallet.walletIndex) + } + if (this.props.newDatacap) { this.context.updateGithubVerified(this.state.issueNumber, messageID, this.state.address, dataCapIssue) } diff --git a/src/modals/LogInModal.tsx b/src/modals/LogInModal.tsx index 8ff39453..bab283c1 100644 --- a/src/modals/LogInModal.tsx +++ b/src/modals/LogInModal.tsx @@ -10,25 +10,40 @@ import { Data } from '../context/Data/Index' import { ButtonPrimary, dispatchCustomEvent } from "slate-react-system"; import { config } from '../config'; +type ModalStates = { + address: string, + multisig: boolean +} type ModalProps = { type: string, } -class LogInModal extends Component { +class LogInModal extends Component { public static contextType = Data constructor(props: ModalProps) { super(props); + this.state = { + multisig: false, + address: '' + } } componentDidMount() { } + handleChange = (e:any) => { + this.setState({ [e.target.name]: e.target.value } as any) + } + loadLedgerWallet = async () => { - const logged = await this.context.wallet.loadWallet('Ledger') + const logged = await this.context.wallet.loadWallet('Ledger', { + multisig: this.state.multisig, + multisigAddress: this.state.address + }) if (logged) { if (this.context.viewroot === false && this.props.type == '0') { this.context.switchview() @@ -43,7 +58,10 @@ class LogInModal extends Component { } loadBurnerWallet = async () => { - const logged = await this.context.wallet.loadWallet('Burner') + const logged = await this.context.wallet.loadWallet('Burner', { + multisig: this.state.multisig, + multisigAddress: this.state.address + }) if (logged) { if (this.context.viewroot === false && this.props.type == '0') { this.context.switchview() @@ -57,49 +75,96 @@ class LogInModal extends Component { } } + loadPrivate = () => { + this.setState({ + multisig: false + }) + } + + loadMultisig = () => { + this.setState({ + multisig: true + }) + } + render() { return (
-
- {this.props.type === '0' ? - {'RootKey'} - : - {'Verifiers'} - } -
-
-
- {this.props.type === '0' ? - "Log in as a Root Key Holder" - : - "Log in as a Notary" - } -
-
- {this.props.type === '0' ? - "Here is where you can action pending Notary allocation decisions.To become a rootkey holder, you’ll need to have been selected by the network originally." - : - "Here is where you can manage pending public requests and action DataCap allocation decisions. To become a rootkey holder, you’ll need to have been preselected." - } -
-
-
- {!config.networks.includes('Mainnet') ? -
- - {'Logo'} - Load Browser Wallet - + {this.props.type === '0' ? + +
+ {'RootKey'} +
+
+
+ Log in as a Root Key Holder +
+
+ Here is where you can action pending Notary allocation decisions.To become a rootkey holder, you’ll need to have been selected by the network originally. +
+
+
+ {!config.networks.includes('Mainnet') ? +
+ + {'Logo'} + Load Browser Wallet + +
+ : null} +
+ + {'Ledger'} + Load Ledger Wallet + +

Please ensure you have “expert mode” enabled

+
+
+
+ : + +
+ {'Verifiers'} +
+
+
+ Log in as a Notary +
+
+ Here is where you can manage pending public requests and action DataCap allocation decisions. To become a rootkey holder, you’ll need to have been preselected. +
+
+
+
this.loadPrivate()}>Individual
+
this.loadMultisig()}>Organization
+
+
+ {!config.networks.includes('Mainnet') ? +
+ + {'Logo'} + Load Browser Wallet + + { this.state.multisig ? + + : null + } +
+ : null} +
+ + {'Ledger'} + Load Ledger Wallet + + { this.state.multisig ? + + : null + } +

Please ensure you have “expert mode” enabled

+
- : null} -
- - {'Ledger'} - Load Ledger Wallet - -

Please ensure you have “expert mode” enabled

-
-
+ + }
) }