Skip to content

Commit

Permalink
Merge pull request #136 from eco-stake/swap-skip-go
Browse files Browse the repository at this point in the history
Swap section using Skip Go widget
  • Loading branch information
tombeynon authored Feb 2, 2025
2 parents 0d2fcf8 + f4852fd commit 014b9f4
Show file tree
Hide file tree
Showing 20 changed files with 22,253 additions and 7,892 deletions.
2 changes: 0 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: "3.3"

services:
app:
build: .
Expand Down
29,778 changes: 21,954 additions & 7,824 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
"@cosmjs/proto-signing": "^0.32.4",
"@cosmjs/stargate": "^0.32.4",
"@injectivelabs/sdk-ts": "^1.14.33",
"@skip-go/widget": "^3.2.0",
"@terra-money/terra.js": "^3.1.10",
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^15.0.7",
"@testing-library/user-event": "^13.5.0",
"@tharsis/address-converter": "^0.1.8",
"@walletconnect/browser-utils": "^1.8.0",
"axios": "^1.7.2",
"axios-retry": "^3.3.1",
"bootstrap": "^5.3.3",
Expand All @@ -24,6 +24,7 @@
"dotenv": "^16.4.5",
"fuzzy-search": "^3.2.1",
"lodash": "^4.17.21",
"long": "^5.2.4",
"mathjs": "^13.0.0",
"micromark": "^4.0.0",
"micromark-extension-gfm": "^3.0.0",
Expand All @@ -36,6 +37,7 @@
"react-bootstrap-icons": "^1.11.4",
"react-copy-to-clipboard": "^5.1.0",
"react-countdown": "^2.3.5",
"react-device-detect": "^2.2.3",
"react-dom": "^18.3.1",
"react-github-btn": "^1.4.0",
"react-moment": "^1.1.3",
Expand Down Expand Up @@ -84,5 +86,8 @@
"stream-http": "^3.2.0",
"url": "^0.11.4",
"vm-browserify": "^1.1.2"
},
"@parcel/resolver-default": {
"packageExports": true
}
}
2 changes: 1 addition & 1 deletion src/adapters/DefaultSigningAdapter.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export default class DefaultSigningAdapter {
pubkeyTypeUrl(pub_key){
if(pub_key && pub_key['@type']) return pub_key['@type']

if(this.network.slip44 === 60){
if(this.network.ethermint){
return '/ethermint.crypto.v1.ethsecp256k1.PubKey'
}
return '/cosmos.crypto.secp256k1.PubKey'
Expand Down
6 changes: 3 additions & 3 deletions src/components/About.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ function About(props) {
<p>You can also optionally add a total number of tokens the validator is allowed to delegate, or adjust the expiry date.</p>
<h5>How to use REStake</h5>
<ol>
<li>Choose a network. Some don't support Authz yet but many do.</li>
<li>Choose a network. Some don't support Authz yet but most do.</li>
<li>Delegate to any validators who offers the REStake service.</li>
<li>Enable REStake on the validators you want to compound rewards.</li>
<li>Watch the countdown timer and profit!</li>
<li>Profit!</li>
</ol>
<h5>Run REStake yourself</h5>
<p>REStake is intended to be run by as many validators as possible, giving delegators the choice of who to auto-compound their rewards with. Ask your favourite validator to become an operator or run it yourself, it's easy!</p>
<p>REStake is intended to be run by as many validators as possible, giving delegators the choice of who to auto-compound their rewards with. Ask your favourite validator to become an operator, it's easy!</p>
<p>The project is entirely open source and instructions for running and contributing to REStake can be <a href="https://github.com/eco-stake/restake" target="_blank" rel="noreferrer">found on Github</a>.</p>
<h5>ECO Stake 🌱</h5>
<p>ECO Stake is an independent, climate positive validator focussed on building useful tools for the Cosmos ecosystem. We built REStake to make it easy for all validators to run an autocompounder with Authz, and it's one of many projects we work on in the ecosystem. <a href="https://ecostake.com" target="_blank" rel="noreferrer">Delegate with us</a> to support more projects like this.</p>
Expand Down
49 changes: 36 additions & 13 deletions src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ import {
Clipboard,
ClipboardCheck,
Eye,
Key
Key,
CurrencyExchange
} from 'react-bootstrap-icons'
import { CopyToClipboard } from 'react-copy-to-clipboard';
import GitHubButton from 'react-github-btn'
Expand All @@ -47,6 +48,7 @@ import TooltipIcon from './TooltipIcon';
import Voting from './Voting';
import Networks from './Networks';
import Grants from './Grants';
import Swap from './Swap';
import Favourite from './Favourite';
import WalletModal from './WalletModal';
import Wallet from '../utils/Wallet.mjs';
Expand Down Expand Up @@ -214,7 +216,11 @@ class App extends React.Component {
}

refreshInterval() {
this.setState({ refresh: true })
const balanceInterval = setInterval(() => {
this.getBalance();
}, 15_000);

this.setState({ refresh: true, balanceInterval })
this.refreshTimeout()
}

Expand All @@ -231,6 +237,7 @@ class App extends React.Component {

clearRefreshInterval() {
clearTimeout(this.state.grantTimeout);
clearInterval(this.state.balanceInterval);
this.setState({ refresh: false })
}

Expand Down Expand Up @@ -288,7 +295,7 @@ class App extends React.Component {
async getBalance() {
if (!this.state.address) return

this.restClient().getBalance(this.state.address)
return this.restClient().getBalance(this.state.address)
.then(
(balances) => {
const balance = balances?.find(
Expand Down Expand Up @@ -511,11 +518,11 @@ class App extends React.Component {
case 'networks':
return <span>REStake automatically imports <a href="https://cosmos.network/" target="_blank" className="text-reset"><strong>Cosmos</strong></a> chains from the <a href="https://github.com/cosmos/chain-registry" target="_blank" className="text-reset"><strong>Chain Registry</strong></a></span>
case 'voting':
return <span>REStake let's you vote on behalf of your other {this.props.network && <strong onClick={this.showNetworkSelect} className="text-decoration-underline" role="button">{this.props.network.prettyName}</strong>} wallets using Authz</span>
return <span>REStake let's you vote on behalf of your other {this.props.network && <strong onClick={this.showNetworkSelect} className="text-decoration-underline text-nowrap" role="button">{this.props.network.prettyName}</strong>} wallets using Authz</span>
case 'grants':
return <span>REStake manages all your {this.props.network && <strong onClick={this.showNetworkSelect} className="text-decoration-underline" role="button">{this.props.network.prettyName}</strong>} Authz grants in one place</span>
return <span>REStake manages all your {this.props.network && <strong onClick={this.showNetworkSelect} className="text-decoration-underline text-nowrap" role="button">{this.props.network.prettyName}</strong>} Authz grants in one place</span>
}
return <span>REStake allows validators to <strong onClick={() => this.setState({ showAbout: true })} className="text-decoration-underline" role="button">auto-compound</strong> your {this.props.network && <strong onClick={this.showNetworkSelect} className="text-decoration-underline" role="button">{this.props.network.prettyName}</strong>} staking rewards</span>
return <span>REStake allows validators to <strong onClick={() => this.setState({ showAbout: true })} className="text-decoration-underline" role="button">auto-compound</strong> your {this.props.network && <strong onClick={this.showNetworkSelect} className="text-decoration-underline text-nowrap" role="button">{this.props.network.prettyName}</strong>} staking rewards</span>
}

networkAlertProps() {
Expand All @@ -532,7 +539,7 @@ class App extends React.Component {

render() {
return (
<Container fluid="lg">
<Container fluid="xl">
<header className="">
<div className="d-flex justify-content-between align-items-center py-3 border-bottom">
<div className="logo d-flex align-items-end text-reset text-decoration-none">
Expand All @@ -549,7 +556,7 @@ class App extends React.Component {
)}
</div>
<div className="d-flex align-items-center text-reset text-decoration-none">
<p className="lead fs-6 text-center m-0 px-3 d-lg-block d-none">
<p className="lead fs-6 text-center m-0 px-5 d-lg-block d-none">
{this.introText()}
</p>
</div>
Expand All @@ -566,33 +573,40 @@ class App extends React.Component {
</div>
</div>
<div className="d-flex justify-content-between border-bottom">
<Navbar className={`navbar navbar-expand ${this.props.theme === 'dark' ? 'navbar-dark' : 'navbar-light'}`}>
<Navbar className={`navbar navbar-expand ${this.props.theme === 'dark' ? 'navbar-dark' : 'navbar-light'} me-3`}>
<div className="justify-content-center">
<Nav activeKey={this.props.active} onSelect={(e) => this.props.setActive(e)}>
<div className="nav-item pe-2 border-end">
<div className="nav-item pe-2 border-end text-center">
<Nav.Link eventKey="networks">
<Stars className="mb-1 me-1" /><span className="d-none d-sm-inline"> Explore</span>
</Nav.Link>
</div>
{this.props.network && (
<>
<div className="nav-item px-2 border-end">
<div className="nav-item px-2 border-end text-center">
<Nav.Link eventKey="delegations">
<Coin className="mb-1 me-1" /><span className="d-none d-sm-inline"> Stake</span>
</Nav.Link>
</div>
<div className="nav-item px-2 border-end">
<div className="nav-item px-2 border-end text-center">
<Nav.Link eventKey="voting">
<EnvelopePaper className="mb-1 me-1" /><span className="d-none d-sm-inline"> Vote</span>
</Nav.Link>
</div>
{this.state.address && this.props.network.authzSupport && (
<div className="nav-item ps-2">
<div className="nav-item px-2 border-end text-center">
<Nav.Link eventKey="grants">
<Magic className="mb-1 me-1" /><span className="d-none d-sm-inline"> Grant</span>
</Nav.Link>
</div>
)}
{!this.props.directory.testnet && (
<div className="nav-item px-2 text-center">
<Nav.Link eventKey="swap">
<CurrencyExchange className="mb-1 me-1" /><span className="d-none d-sm-inline"> Swap</span>
</Nav.Link>
</div>
)}
</>
)}
</Nav>
Expand Down Expand Up @@ -801,6 +815,15 @@ class App extends React.Component {
grantQuerySupport={this.state.grantQuerySupport}
/>
)}
{this.props.active === 'swap' && !this.props.directory.testnet && (
<Swap
networks={this.props.networks}
network={this.props.network}
wallet={this.state.wallet}
theme={this.props.theme}
getBalance={this.getBalance}
/>
)}
</div>
<footer className="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
<a href="https://akash.network" target="_blank" rel="noreferrer" className="col-md-4 mb-0 text-muted">
Expand Down
3 changes: 1 addition & 2 deletions src/components/Delegations.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ class Delegations extends React.Component {

refreshInterval() {
const refreshInterval = setInterval(() => {
this.props.getBalance();
this.getRewards(true);
}, 15_000);
const delegateInterval = setInterval(() => {
Expand Down Expand Up @@ -595,7 +594,7 @@ class Delegations extends React.Component {
</div>
<hr />
<p className="mt-5 text-center">
Enabling REStake will authorize the validator to send <em>Delegate</em> transactions on your behalf for 1 year <a href="https://docs.cosmos.network/master/modules/authz/" target="_blank" rel="noreferrer" className="text-reset">using Authz</a>.<br />
Enabling REStake will authorize the validator to send <em>Delegate</em> transactions on your behalf <a href="https://docs.cosmos.network/master/modules/authz/" target="_blank" rel="noreferrer" className="text-reset">using Authz</a>.<br />
They will only be authorized to delegate to their own validator. You can revoke the authorization at any time and everything is open source.
</p>
<p className="text-center mb-4">
Expand Down
10 changes: 8 additions & 2 deletions src/components/NetworkFinder.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function NetworkFinder() {
const navigate = useNavigate()
const voteMatch = useMatch("/:network/vote/*");
const grantMatch = useMatch("/:network/grants");
const swapMatch = useMatch("/:network/swap/*");

const networkMode = process.env.TESTNET_MODE === '1' ? 'testnet' : 'mainnet'
const directory = getDirectory()
Expand Down Expand Up @@ -96,6 +97,8 @@ function NetworkFinder() {
setActive('voting', network);
} else if(grantMatch && network.authzSupport) {
setActive('grants', network);
} else if (swapMatch) {
setActive('swap', network);
} else {
setActive('delegations', network);
}
Expand All @@ -110,6 +113,9 @@ function NetworkFinder() {
case 'voting':
navigate("/" + network.path + '/vote');
break;
case 'swap':
navigate("/" + network.path + '/swap');
break;
case 'delegations':
navigate("/" + network.path);
break;
Expand Down Expand Up @@ -171,7 +177,7 @@ function NetworkFinder() {
if (!params.network) {
setState({ active: 'networks' })
}
}, [voteMatch, grantMatch, params.network])
}, [voteMatch, grantMatch, swapMatch, params.network])

useEffect(() => {
if (Object.keys(state.networks).length && (!state.network || state.network.path !== params.network)) {
Expand All @@ -189,7 +195,7 @@ function NetworkFinder() {
return network.connect().then(() => {
if (network.connected) {
setState({
active: grantMatch ? 'grants' : voteMatch ? 'voting' : 'delegations',
active: grantMatch ? 'grants' : voteMatch ? 'voting' : swapMatch ? 'swap' : 'delegations',
network: network,
validators: network.getValidators(),
operators: network.getOperators(),
Expand Down
6 changes: 3 additions & 3 deletions src/components/REStakeGrantForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ function REStakeGrantForm(props) {
return (
<>
<p className="small">{operator.moniker} will be able to carry out the following transactions on your behalf:</p>
<p className="small"><strong>Delegate</strong> - allowed to delegate <em>{maxTokensDenom() ? <Coins coins={{ amount: maxTokensDenom(), denom: network.denom }} asset={network.baseAsset} fullPrecision={true} hideValue={true} /> : 'any amount'}</em> to <em>{!state.validators ? 'any validator' : !state.validators.length || (state.validators.length === 1 && state.validators.includes(operator.address)) ? 'only their own validator' : 'validators ' + state.validators.join(', ')}</em>.</p>
<p className="small">This grant will expire automatically on <em>{state.expiryDateValue}</em>.</p>
<p className="small">REStake only re-delegates {operator.moniker}'s accrued rewards and tries not to touch your balance.</p>
<p className="small"><strong>Delegate</strong> - allowed to delegate <em>{maxTokensDenom() ? <>a maximum of <Coins coins={{ amount: maxTokensDenom(), denom: network.denom }} asset={network.baseAsset} fullPrecision={true} hideValue={true} /></> : 'any amount'}</em> to <em>{!state.validators ? 'any validator' : !state.validators.length || (state.validators.length === 1 && state.validators.includes(operator.address)) ? 'only their own validator' : 'validators ' + state.validators.join(', ')}</em>.</p>
<p className="small">This grant will expire automatically on <em>{state.expiryDateValue}</em> and you can revoke it at any time.</p>
<p className="small">{operator.moniker} will only auto-compound their accrued rewards and tries not to touch your balance.<br /><strong>They will pay the transaction fees for you.</strong></p>
{genericGrantOnly && (
<p className="small"><em>{network.prettyName} only supports generic Authz grants with this wallet, full support is coming soon.</em></p>
)}
Expand Down
Loading

0 comments on commit 014b9f4

Please sign in to comment.