Skip to content

Commit

Permalink
Merge #1473
Browse files Browse the repository at this point in the history
1473: Add zkscan link for alternative withdraw when appropriate r=Deniallugo a=StanislavBreadless



Co-authored-by: Stanislav Bezkorovainyi <[email protected]>
  • Loading branch information
2 parents 43e2036 + e6927fa commit 6fc1b6d
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 2 deletions.
36 changes: 34 additions & 2 deletions infrastructure/explorer/src/Account.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
<template v-slot:cell(value)="data"><span v-html="data.item.value" /></template>
</b-table>
</b-card>
<div class="alternativeWithdrawMsg" v-if="eligibleForForcedExit">
Funds from this account can be moved to L1 using the
<outter-link :to="alternativeWithdrawAddressLink" innerHTML="Alternative Withdraw"></outter-link>
</div>
<h5 class="mt-3 mb-2">Account transactions</h5>
<img src="./assets/loading.gif" width="100" height="100" v-if="loading" />
<div v-else-if="transactions.length == 0">No transactions yet.</div>
Expand Down Expand Up @@ -68,10 +72,12 @@
<script>
import timeConstants from './timeConstants';
import { clientPromise } from './Client';
import OutterLink from './links/OutterLink';
import SearchField from './SearchField.vue';
import CopyableAddress from './CopyableAddress.vue';
import { accountStateToBalances, makeEntry } from './utils';
import { accountStateToBalances, makeEntry, isEligibleForForcedExit } from './utils';
import Navbar from './Navbar.vue';
import store from './store';
import Entry from './links/Entry.vue';
Expand All @@ -81,7 +87,8 @@ const components = {
SearchField,
CopyableAddress,
Navbar,
Entry
Entry,
OutterLink
};
export default {
Expand All @@ -96,6 +103,7 @@ export default {
totalRows: 0,
loading: true,
eligibleForForcedExit: false,
intervalHandle: null,
client: null,
Expand All @@ -111,6 +119,7 @@ export default {
async nextAddress() {
this.loading = true;
this.totalRows = 0;
this.eligibleForForcedExit = false;
this.pagesOfTransactions = {};
this.client = await clientPromise;
Expand Down Expand Up @@ -151,6 +160,10 @@ export default {
clearInterval(this.intervalHandle);
},
methods: {
async checkForcedExitEligiblity() {
const isEligible = await isEligibleForForcedExit(this.address);
return isEligible;
},
onRowClicked(item) {
this.$parent.$router.push('/transactions/' + item.hash);
},
Expand Down Expand Up @@ -181,6 +194,8 @@ export default {
);
}
this.eligibleForForcedExit = await this.checkForcedExitEligiblity();
let nextPageLoaded = false;
let numNextPageTransactions;
Expand Down Expand Up @@ -219,6 +234,18 @@ export default {
}
},
computed: {
alternativeWithdrawUrl() {
if (store.network === 'rinkeby' || store.network === 'ropsten') {
return `https://withdraw-${store.network}.zksync.dev`;
} else {
return `https://withdraw.zksync.io`;
}
},
alternativeWithdrawAddressLink() {
let baseUrl = this.alternativeWithdrawUrl;
return `${baseUrl}?address=${this.address}`;
},
address() {
return this.$route.params.address;
},
Expand Down Expand Up @@ -305,4 +332,9 @@ export default {
.brown {
color: #aa935d;
}
.alternativeWithdrawMsg {
padding-top: 20px;
font-size: 15px;
}
</style>
42 changes: 42 additions & 0 deletions infrastructure/explorer/src/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import store from './store';
import config from './env-config';
import { Readiness } from './Readiness';
import { getDefaultProvider } from 'zksync';

export const sleep = async (ms) => await new Promise((resolve) => setTimeout(resolve, ms));

Expand Down Expand Up @@ -118,6 +120,46 @@ export function accountStateToBalances(account) {
return balances;
}

function getForcedExitEndpoint(str) {
const FORCED_EXIT_API = `${config.API_SERVER}/api/forced_exit_requests/v0.1`;
return FORCED_EXIT_API + str;
}

async function checkEligibilty(address) {
const endpoint = getForcedExitEndpoint(`/checks/eligibility/${address}`);

const response = await fetch(endpoint);

const responseObj = await response.json();

return responseObj.eligible;
}

export async function isEligibleForForcedExit(address) {
if (!window.provider) {
window.provider = await getDefaultProvider(config.ETH_NETWORK);
}

const state = await window.provider.getState(address);

if (!state.id || state.id === -1) {
// The account does not exist
return false;
}

if (state.committed.nonce) {
// The account has done some txs before
return false;
}

const existedForEnoughTime = await checkEligibilty(address);
if (!existedForEnoughTime) {
return false;
}

return true;
}

// Note that this class follows Builder pattern
// If you see any of it's methods not returning `this`
// it is a bug.
Expand Down

0 comments on commit 6fc1b6d

Please sign in to comment.