@swipewallet/venus-js
Version:
A JavaScript SDK for Ethereum and the Venus Protocol.
576 lines (434 loc) • 18.8 kB
HTML
<html>
<head>
<!-- USE CDN, PUBLIC BUILD -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@swipewallet/venus-js@latest/dist/browser/venus.min.js"></script>
<!-- USE LOCAL BUILD (be sure `npm install`) -->
<!-- <script type="text/javascript" src="../../dist/browser/venus.min.js"></script> -->
<link rel="stylesheet"
href="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@10.1.2/build/styles/default.min.css">
<script src="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@10.1.2/build/highlight.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/languages/javascript.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/styles/night-owl.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/picnic" />
<style type="text/css">
p { margin: 0px }
pre { padding: 0px }
.red { color: #e60000; }
.container {
margin: 0px 25px;
width: 800px;
}
.spinner { /* credit https://codepen.io/mandelid/pen/vwKoe */
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid rgba(0,0,0,.3);
border-radius: 50%;
border-top-color: #000;
animation: spin 1s ease-in-out infinite;
-webkit-animation: spin 1s ease-in-out infinite;
}
@keyframes spin { to { -webkit-transform: rotate(360deg); } }
@-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } }
</style>
<title>Venus.js Examples</title>
</head>
<body>
<div class="container">
<h1>Venus.js Examples [Alpha]</h1>
<p>
Code examples for client interaction with the <a href="https://docs.venus.io/venus-js/">Venus</a> protocol via Venus.js.
</p>
<p>
Run <a href="https://www.trufflesuite.com/ganache">Ganache</a> with a <b>fork of main net</b> on your local machine and set MetaMask to <b>Localhost 8545</b> to test writing transactions.
</p>
<p class="red">
<b>
DO NOT use this web page with Ethereum main net or with your funded Ethereum keys / wallet!
</b>
</p>
<div class="item">
<h2>Ethereum Read (JSON RPC eth_call)</h2>
<p>Generic Ethereum blockchain read with JSON RPC. This example fetches the supply rate per block for cETH using the <b>read</b> method.</p>
<button id="eth-call-button">Get Supply Rate Per Block</button>
<br />
<div id="eth-call-content"></div>
<pre><code class="js">// mainnet
const cEthAddress = '0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5';
(async function() {
const srpb = await Venus.eth.read(
cEthAddress,
'function supplyRatePerBlock() returns (uint256)',
// [], // [optional] parameters
// {} // [optional] call options, provider, network, plus Ethers.js "overrides"
);
console.log('cETH market supply rate per block:', srpb.toString());
})().catch(console.error);</code></pre>
</div>
<div class="item">
<h2>Ethereum Send Transaction (JSON RPC eth_sendTransaction)</h2>
<p>Create and send an Ethereum transaction with JSON RPC. This button's transaction transfers your Ether to the Venus protocol using the <b>trx</b> method.</p>
<button id="eth-sendTransaction-button">Supply 1 ETH</button>
<br />
<div id="eth-sendTransaction-content"></div>
<pre><code class="js">const oneEthInWei = '1000000000000000000';
const cEthAddress = '0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5';
const provider = window.ethereum;
(async function() {
console.log('Supplying ETH to the Venus Protocol...');
// Mint some cETH by supplying ETH to the Venus Protocol
const trx = await Venus.eth.trx(
cEthAddress,
'function mint() payable',
[],
{
provider,
value: oneEthInWei
}
);
// const result = await trx.wait(1); // JSON object of trx info, once mined
console.log('Ethers.js transaction object', trx);
})().catch(console.error);</code></pre>
</div>
<div class="item">
<h2>Supply</h2>
<p>This button's transaction transfers your Ether to the Venus protocol using the <b>supply</b> method.</p>
<button id="supply-button">Supply 1 ETH</button>
<br />
<div id="supply-content"></div>
<pre><code class="js">const venus = new Venus(window.ethereum);
// Ethers.js overrides are an optional 3rd parameter for `supply`
// const trxOptions = { gasLimit: 250000, mantissa: false };
(async function() {
console.log('Supplying ETH to the Venus protocol...');
const trx = await venus.supply(Venus.ETH, 1);
console.log('Ethers.js transaction object', trx);
})().catch(console.error);</code></pre>
</div>
<div class="item">
<h2>Redeem</h2>
<p>This button's transaction redeems your Ether from the Venus protocol using the <b>redeem</b> method.</p>
<button id="redeem-button">Redeem 1 ETH</button>
<br />
<div id="redeem-content"></div>
<pre><code class="js">const venus = new Venus(window.ethereum);
(async function() {
console.log('Redeeming ETH...');
const trx = await venus.redeem(Venus.ETH, 1); // also accepts cToken args
console.log('Ethers.js transaction object', trx);
})().catch(console.error);
</code></pre>
</div>
<div class="item">
<h2>Enter Markets</h2>
<p>This button's transaction enables supplied assets to be used as collateral using the <b>enterMarkets</b> method. Note that there is a corresponding <b>exitMarket</b> method for exiting a single market.</p>
<button id="enter-market-button">Enter ETH Market</button>
<br />
<div id="enter-market-content"></div>
<pre><code class="js">const venus = new Venus(window.ethereum);
(async function() {
console.log('Entering ETH market (use as collateral)...');
const trx = await venus.enterMarkets(Venus.ETH); // also accepts []
console.log('Ethers.js transaction object', trx);
// Exit a market (string argument of only 1 market at a time)
// const trx = await venus.exitMarket(Venus.ETH);
})().catch(console.error);</code></pre>
</div>
<div class="item">
<h2>Borrow</h2>
<p>This button's transaction borrows 32 Dai, against collateral, using the <b>borrow</b> method. Remember to supply a supported asset as collateral and enter that market prior to borrowing.</p>
<button id="borrow-button">Borrow 32 Dai</button>
<br />
<div id="borrow-content"></div>
<pre><code class="js">const venus = new Venus(window.ethereum);
(async function() {
const daiScaledUp = '32000000000000000000';
const trxOptions = { mantissa: true };
console.log('Borrowing 32 Dai...');
const trx = await venus.borrow(Venus.DAI, daiScaledUp, trxOptions);
console.log('Ethers.js transaction object', trx);
})().catch(console.error);</code></pre>
</div>
<div class="item">
<h2>Repay Borrow</h2>
<p>This button's transaction repays 32 borrowed Dai using the <b>repayBorrow</b> method. This won't work unless you have an open borrow.</p>
<button id="repay-borrow-button">Repay 32 Dai</button>
<br />
<div id="repay-borrow-content"></div>
<pre><code class="js">const venus = new Venus(window.ethereum);
(async function() {
console.log('Repaying Dai borrow...');
const address = null; // set this to any address to repayBorrowBehalf
const trx = await venus.repayBorrow(Venus.DAI, 32, address);
console.log('Ethers.js transaction object', trx);
})().catch(console.error);</code></pre>
</div>
<div class="item">
<h2>Get Price</h2>
<p>Fetches the BAT price in USDC using the <b>getPrice</b> method.</p>
<button id="get-price-button">Get BAT Price</button>
<br />
<div id="get-price-content"></div>
<pre><code class="js">(async function() {
// Accepts 2 args, cTokens or underlyings. Second arg defaults to USDC.
const price = await venus.getPrice(Venus.BAT);
console.log('BAT in USDC', price);
})().catch(console.error);</code></pre>
</div>
<div class="item">
<h2>Get Address</h2>
<p>Fetches a relevant contract address using <b>getAddress</b> method.</p>
<button id="get-address-button">Get cETH Address</button>
<br />
<div id="get-address-content"></div>
<pre><code class="js">// Accepts vTokens or underlyings. Second arg defaults to main net.
const vSXPAddressRopsten = Venus.util.getAddress(Venus.vSXP, 'ropsten');</code></pre>
</div>
</div>
</body>
<script type="text/javascript">
const ethCallButton = document.getElementById('eth-call-button');
const ethCallContent = document.getElementById('eth-call-content');
const ethSendTransactionButton = document.getElementById('eth-sendTransaction-button');
const ethSendTransactionContent = document.getElementById('eth-sendTransaction-content');
const supplyButton = document.getElementById('supply-button');
const supplyContent = document.getElementById('supply-content');
const redeemButton = document.getElementById('redeem-button');
const redeemContent = document.getElementById('redeem-content');
const enterMarketButton = document.getElementById('enter-market-button');
const enterMarketContent = document.getElementById('enter-market-content');
const borrowButton = document.getElementById('borrow-button');
const borrowContent = document.getElementById('borrow-content');
const repayBorrowButton = document.getElementById('repay-borrow-button');
const repayBorrowContent = document.getElementById('repay-borrow-content');
const getPriceButton = document.getElementById('get-price-button');
const getPriceContent = document.getElementById('get-price-content');
const getAddressButton = document.getElementById('get-address-button');
const getAddressContent = document.getElementById('get-address-content');
const spin = (element) => {
element.innerText = '';
element.classList.add('spinner');
};
const unspin = (element) => element.classList.remove('spinner');
const ethCallExample = () => {
spin(ethCallContent);
// mainnet
const cEthAddress = '0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5';
(async function() {
const srpb = await Venus.eth.read(
cEthAddress,
'function supplyRatePerBlock() returns (uint256)',
// [], // [optional] parameters
// {} // [optional] call options, provider, network, plus Ethers.js "overrides"
);
ethCallContent.innerText = srpb.toString();
console.log('cETH market supply rate per block:', srpb.toString());
})().catch((err) => {
ethCallContent.innerText = 'Error occured; See developer console for details.';
console.error(err);
}).finally(() => { unspin(ethCallContent) });
};
/**
* Run ganache-cli in another command line window before running this script. Be
* sure to fork mainnet.
ganache-cli \
-f https://mainnet.infura.io/v3/_YOUR_INFURA_ID_ \
-m "clutch captain shoe salt awake harvest setup primary inmate ugly among become" \
-i 1
*/
const ethSendTransactionExample = () => {
spin(ethSendTransactionContent);
const oneEthInWei = '1000000000000000000';
const cEthAddress = '0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5';
const provider = window.ethereum;
(async function() {
console.log('Supplying ETH to the Venus Protocol...');
// Mint some cETH by supplying ETH to the Venus Protocol
const trx = await Venus.eth.trx(
cEthAddress,
'function mint() payable',
[],
{
provider,
value: oneEthInWei
}
);
// const result = await trx.wait(1); // JSON object of trx info, once mined
ethSendTransactionContent.innerText = 'Success, see the developer console for the Ethers.js transaction object.';
console.log('Ethers.js transaction object', trx);
})().catch((err) => {
ethSendTransactionContent.innerText = 'Error occured; See developer console for details.';
console.error(err);
}).finally(() => { unspin(ethSendTransactionContent) });
}
/**
* Run ganache-cli in another command line window before running this script. Be
* sure to fork mainnet.
ganache-cli \
-f https://mainnet.infura.io/v3/_YOUR_INFURA_ID_ \
-m "clutch captain shoe salt awake harvest setup primary inmate ugly among become" \
-i 1
*/
const supplyExample = () => {
spin(supplyContent);
const venus = new Venus(window.ethereum);
// Ethers.js overrides are an optional 3rd parameter for `supply`
// const trxOptions = { gasLimit: 250000, mantissa: false };
(async function() {
console.log('Supplying ETH to the Venus protocol...');
const trx = await venus.supply(Venus.ETH, 1);
supplyContent.innerText = 'Success, see the developer console for the Ethers.js transaction object.';
console.log('Ethers.js transaction object', trx);
})().catch((err) => {
supplyContent.innerText = 'Error occured; See developer console for details.';
console.error(err);
}).finally(() => { unspin(supplyContent) });
};
/**
* Run ganache-cli in another command line window before running this script. Be
* sure to fork mainnet.
ganache-cli \
-f https://mainnet.infura.io/v3/_YOUR_INFURA_ID_ \
-m "clutch captain shoe salt awake harvest setup primary inmate ugly among become" \
-i 1
*/
const redeemExample = () => {
spin(redeemContent);
const venus = new Venus(window.ethereum);
(async function() {
console.log('Redeeming ETH...');
const trx = await venus.redeem(Venus.ETH, 1); // also accepts cToken args
console.log('Ethers.js transaction object', trx);
redeemContent.innerText = 'Success, see the developer console for the Ethers.js transaction object.';
})().catch((err) => {
redeemContent.innerText = 'Error occured; See developer console for details.';
console.error(err);
}).finally(() => { unspin(redeemContent) });
};
/**
* Run ganache-cli in another command line window before running this script. Be
* sure to fork mainnet.
ganache-cli \
-f https://mainnet.infura.io/v3/_YOUR_INFURA_ID_ \
-m "clutch captain shoe salt awake harvest setup primary inmate ugly among become" \
-i 1
*/
const enterMarketExample = () => {
spin(enterMarketContent);
const venus = new Venus(window.ethereum);
(async function() {
console.log('Entering ETH market (use as collateral)...');
const trx = await venus.enterMarkets(Venus.ETH); // also accepts []
console.log('Ethers.js transaction object', trx);
// Exit a market (string parameter of only 1 market at a time)
// const trx = await venus.exitMarket(Venus.ETH);
enterMarketContent.innerText = 'Success, see the developer console for the Ethers.js transaction object.';
})().catch((err) => {
enterMarketContent.innerText = 'Error occured; See developer console for details.';
console.error(err);
}).finally(() => { unspin(enterMarketContent) });
};
/**
* Run ganache-cli in another command line window before running this script. Be
* sure to fork mainnet.
ganache-cli \
-f https://mainnet.infura.io/v3/_YOUR_INFURA_ID_ \
-m "clutch captain shoe salt awake harvest setup primary inmate ugly among become" \
-i 1
*/
const borrowExample = () => {
spin(borrowContent);
const venus = new Venus(window.ethereum);
(async function() {
const daiScaledUp = '32000000000000000000';
const trxOptions = { mantissa: true };
console.log('Borrowing 32 Dai...');
const trx = await venus.borrow(Venus.DAI, daiScaledUp, trxOptions);
borrowContent.innerText = 'Success, see the developer console for the Ethers.js transaction object.';
console.log('Ethers.js transaction object', trx);
})().catch((err) => {
borrowContent.innerText = 'Error occured; See developer console for details.';
console.error(err);
}).finally(() => { unspin(borrowContent) });
};
/**
* Run ganache-cli in another command line window before running this script. Be
* sure to fork mainnet.
ganache-cli \
-f https://mainnet.infura.io/v3/_YOUR_INFURA_ID_ \
-m "clutch captain shoe salt awake harvest setup primary inmate ugly among become" \
-i 1
*/
const repayBorrowExample = () => {
spin(repayBorrowContent);
const venus = new Venus(window.ethereum);
(async function() {
console.log('Repaying Dai borrow...');
const address = null; // set this to any address to repayBorrowBehalf
const trx = await venus.repayBorrow(Venus.DAI, 32, address);
repayBorrowContent.innerText = 'Success, see the developer console for the Ethers.js transaction object.';
console.log('Ethers.js transaction object', trx);
})().catch((err) => {
repayBorrowContent.innerText = 'Error occured; See developer console for details.';
console.error(err);
}).finally(() => { unspin(repayBorrowContent) });
};
// get a price using the open price feed
const getPriceExample = () => {
spin(getPriceContent);
const venus = new Venus();
(async function() {
// Accepts 2 args, cTokens or underlyings. Second arg defaults to USDC.
const price = await venus.getPrice(Venus.BAT);
console.log('BAT in USDC', price);
getPriceContent.innerText = price.toString();
})().catch((err) => {
getPriceContent.innerText = 'Error occured; See developer console for details.';
console.error(err);
}).finally(() => { unspin(getPriceContent) });
};
// get a relevant address of a supported protocol contract
const getAddressExample = () => {
spin(getAddressContent);
const venus = new Venus();
(async function() {
// Accepts vTokens or underlyings. Second arg defaults to main net.
const vSxpAddressRopsten = Venus.util.getAddress(Venus.vSXP, 'ropsten');
getAddressContent.innerText = vSxpAddressRopsten.toString();
})().catch((err) => {
getAddressContent.innerText = 'Error occured; See developer console for details.';
console.error(err);
}).finally(() => { unspin(getAddressContent) });
};
window.addEventListener('load', (event) => {
// syntax highlight code snippets
document.querySelectorAll('pre code').forEach((block) => {
hljs.highlightBlock(block);
});
window.ethereum.enable().then(() => {
ethCallButton.onclick = ethCallExample;
ethSendTransactionButton.onclick = ethSendTransactionExample;
supplyButton.onclick = supplyExample;
redeemButton.onclick = redeemExample;
enterMarketButton.onclick = enterMarketExample;
borrowButton.onclick = borrowExample;
repayBorrowButton.onclick = repayBorrowExample;
getPriceButton.onclick = getPriceExample;
getAddressButton.onclick = getAddressExample;
});
});
</script>
</html>