|
|
@@ -2,13 +2,16 @@ import React, {useContext, useEffect, useState} from 'react';
|
|
|
import ClientContext from "../providers/ClientContext";
|
|
|
import * as solanaWeb3 from '@solana/web3.js';
|
|
|
import {PublicKey} from '@solana/web3.js';
|
|
|
-import {Button, Form, Input, InputNumber, message, Select, Space} from "antd";
|
|
|
+import {Button, Col, Form, Input, InputNumber, message, Row, Select, Space} from "antd";
|
|
|
import {ethers} from "ethers";
|
|
|
import {Erc20Factory} from "../contracts/Erc20Factory";
|
|
|
import {Arrayish, BigNumber, BigNumberish} from "ethers/utils";
|
|
|
import {WormholeFactory} from "../contracts/WormholeFactory";
|
|
|
import {WrappedAssetFactory} from "../contracts/WrappedAssetFactory";
|
|
|
import {SolanaBridge} from "../utils/bridge";
|
|
|
+import {BRIDGE_ADDRESS} from "../config";
|
|
|
+import SplBalances from "../components/SplBalances";
|
|
|
+import {SlotContext} from "../providers/SlotContext";
|
|
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
@@ -21,7 +24,7 @@ async function lockAssets(asset: string,
|
|
|
amount: BigNumberish,
|
|
|
recipient: Arrayish,
|
|
|
target_chain: BigNumberish) {
|
|
|
- let wh = WormholeFactory.connect("0xac3eB48829fFC3C37437ce4459cE63F1F4d4E0b4", signer);
|
|
|
+ let wh = WormholeFactory.connect(BRIDGE_ADDRESS, signer);
|
|
|
try {
|
|
|
message.loading({content: "Signing transaction...", key: "eth_tx", duration: 1000},)
|
|
|
let res = await wh.lockAssets(asset, amount, recipient, target_chain)
|
|
|
@@ -38,7 +41,7 @@ async function approveAssets(asset: string,
|
|
|
let e = Erc20Factory.connect(asset, signer);
|
|
|
try {
|
|
|
message.loading({content: "Signing transaction...", key: "eth_tx", duration: 1000})
|
|
|
- let res = await e.approve("0xac3eB48829fFC3C37437ce4459cE63F1F4d4E0b4", amount)
|
|
|
+ let res = await e.approve(BRIDGE_ADDRESS, amount)
|
|
|
message.loading({content: "Waiting for transaction to be mined...", key: "eth_tx", duration: 1000})
|
|
|
await res.wait(1);
|
|
|
message.success({content: "Approval on ETH succeeded!", key: "eth_tx"})
|
|
|
@@ -49,13 +52,7 @@ async function approveAssets(asset: string,
|
|
|
|
|
|
function Transfer() {
|
|
|
let c = useContext<solanaWeb3.Connection>(ClientContext);
|
|
|
-
|
|
|
- let [slot, setSlot] = useState(0);
|
|
|
- useEffect(() => {
|
|
|
- c.onSlotChange(value => {
|
|
|
- setSlot(value.slot);
|
|
|
- });
|
|
|
- })
|
|
|
+ let slot = useContext(SlotContext);
|
|
|
|
|
|
let [coinInfo, setCoinInfo] = useState({
|
|
|
balance: new BigNumber(0),
|
|
|
@@ -73,22 +70,13 @@ function Transfer() {
|
|
|
fetchBalance(address)
|
|
|
}, [address])
|
|
|
|
|
|
-
|
|
|
-
|
|
|
async function fetchBalance(token: string) {
|
|
|
- let p = new SolanaBridge(new PublicKey("FHbUryAag7ZfkFKbaCZaqWYsRgEtu7EWFrniy3VQ9Z3w"), new PublicKey("FHbUryAag7ZfkFKbaCZaqWYsRgEtu7EWFrniy3VQ9Z3w"), new PublicKey("FHbUryAag7ZfkFKbaCZaqWYsRgEtu7EWFrniy3VQ9Z3w"))
|
|
|
- console.log(p.programID.toBuffer())
|
|
|
- console.log(await p.createWrappedAsset(new PublicKey("FHbUryAag7ZfkFKbaCZaqWYsRgEtu7EWFrniy3VQ9Z3w"), 2000, {
|
|
|
- chain: 200,
|
|
|
-
|
|
|
- address: Buffer.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
|
|
- }))
|
|
|
try {
|
|
|
let e = WrappedAssetFactory.connect(token, provider);
|
|
|
let addr = await signer.getAddress();
|
|
|
let balance = await e.balanceOf(addr);
|
|
|
let decimals = await e.decimals();
|
|
|
- let allowance = await e.allowance(addr, "0xac3eB48829fFC3C37437ce4459cE63F1F4d4E0b4");
|
|
|
+ let allowance = await e.allowance(addr, BRIDGE_ADDRESS);
|
|
|
|
|
|
let info = {
|
|
|
balance: balance.div(new BigNumber(10).pow(decimals)),
|
|
|
@@ -99,7 +87,7 @@ function Transfer() {
|
|
|
wrappedAddress: ""
|
|
|
}
|
|
|
|
|
|
- let b = WormholeFactory.connect("0xac3eB48829fFC3C37437ce4459cE63F1F4d4E0b4", provider);
|
|
|
+ let b = WormholeFactory.connect(BRIDGE_ADDRESS, provider);
|
|
|
|
|
|
let isWrapped = await b.isWrappedAsset(token)
|
|
|
if (isWrapped) {
|
|
|
@@ -117,60 +105,70 @@ function Transfer() {
|
|
|
return (
|
|
|
<>
|
|
|
<p>Slot: {slot}</p>
|
|
|
- <Space>
|
|
|
- <Form onFinish={(values) => {
|
|
|
- let recipient = new solanaWeb3.PublicKey(values["recipient"]).toBuffer()
|
|
|
- let transferAmount = new BigNumber(values["amount"]).mul(new BigNumber(10).pow(coinInfo.decimals));
|
|
|
- if (coinInfo.allowance.toNumber() >= amount || coinInfo.isWrapped) {
|
|
|
- lockAssets(values["address"], transferAmount, recipient, values["target_chain"])
|
|
|
- } else {
|
|
|
- approveAssets(values["address"], transferAmount)
|
|
|
- }
|
|
|
- }}>
|
|
|
- <Form.Item name="address" validateStatus={addressValid ? "success" : "error"}>
|
|
|
- <Input addonAfter={`Balance: ${coinInfo.balance}`} name="address" placeholder={"ERC20 address"}
|
|
|
- onBlur={(v) => {
|
|
|
- setAddress(v.target.value)
|
|
|
- }}/>
|
|
|
- </Form.Item>
|
|
|
- <Form.Item name="amount" rules={[{
|
|
|
- required: true, validator: (rule, value, callback) => {
|
|
|
- let big = new BigNumber(value);
|
|
|
- callback(big.lte(coinInfo.balance) ? undefined : "Amount exceeds balance")
|
|
|
- }
|
|
|
- }]}>
|
|
|
- <InputNumber name={"amount"} placeholder={"Amount"} type={"number"} onChange={value => {
|
|
|
- // @ts-ignore
|
|
|
- setAmount(value || 0)
|
|
|
- }}/>
|
|
|
- </Form.Item>
|
|
|
- <Form.Item name="target_chain" rules={[{required: true, message: "Please choose a target chain"}]}>
|
|
|
- <Select placeholder="Target Chain">
|
|
|
- <Select.Option value={1}>
|
|
|
- Solana
|
|
|
- </Select.Option>
|
|
|
- </Select>
|
|
|
- </Form.Item>
|
|
|
- <Form.Item name="recipient" rules={[{
|
|
|
- required: true,
|
|
|
- validator: (rule, value, callback) => {
|
|
|
- try {
|
|
|
- new solanaWeb3.PublicKey(value);
|
|
|
- callback();
|
|
|
- } catch (e) {
|
|
|
- callback("Not a valid Solana address");
|
|
|
+ <Row>
|
|
|
+ <Col>
|
|
|
+ <Space>
|
|
|
+ <Form onFinish={(values) => {
|
|
|
+ let recipient = new solanaWeb3.PublicKey(values["recipient"]).toBuffer()
|
|
|
+ let transferAmount = new BigNumber(values["amount"]).mul(new BigNumber(10).pow(coinInfo.decimals));
|
|
|
+ if (coinInfo.allowance.toNumber() >= amount || coinInfo.isWrapped) {
|
|
|
+ lockAssets(values["address"], transferAmount, recipient, values["target_chain"])
|
|
|
+ } else {
|
|
|
+ approveAssets(values["address"], transferAmount)
|
|
|
}
|
|
|
- }
|
|
|
- },]}>
|
|
|
- <Input name="recipient" placeholder={"Address of the recipient"}/>
|
|
|
- </Form.Item>
|
|
|
- <Form.Item>
|
|
|
- <Button type="primary" htmlType="submit">
|
|
|
- {coinInfo.allowance.toNumber() >= amount || coinInfo.isWrapped ? "Transfer" : "Approve"}
|
|
|
- </Button>
|
|
|
- </Form.Item>
|
|
|
- </Form>
|
|
|
- </Space>
|
|
|
+ }}>
|
|
|
+ <Form.Item name="address" validateStatus={addressValid ? "success" : "error"}>
|
|
|
+ <Input addonAfter={`Balance: ${coinInfo.balance}`} name="address"
|
|
|
+ placeholder={"ERC20 address"}
|
|
|
+ onBlur={(v) => {
|
|
|
+ setAddress(v.target.value)
|
|
|
+ }}/>
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item name="amount" rules={[{
|
|
|
+ required: true, validator: (rule, value, callback) => {
|
|
|
+ let big = new BigNumber(value);
|
|
|
+ callback(big.lte(coinInfo.balance) ? undefined : "Amount exceeds balance")
|
|
|
+ }
|
|
|
+ }]}>
|
|
|
+ <InputNumber name={"amount"} placeholder={"Amount"} type={"number"} onChange={value => {
|
|
|
+ // @ts-ignore
|
|
|
+ setAmount(value || 0)
|
|
|
+ }}/>
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item name="target_chain"
|
|
|
+ rules={[{required: true, message: "Please choose a target chain"}]}>
|
|
|
+ <Select placeholder="Target Chain">
|
|
|
+ <Select.Option value={1}>
|
|
|
+ Solana
|
|
|
+ </Select.Option>
|
|
|
+ </Select>
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item name="recipient" rules={[{
|
|
|
+ required: true,
|
|
|
+ validator: (rule, value, callback) => {
|
|
|
+ try {
|
|
|
+ new solanaWeb3.PublicKey(value);
|
|
|
+ callback();
|
|
|
+ } catch (e) {
|
|
|
+ callback("Not a valid Solana address");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },]}>
|
|
|
+ <Input name="recipient" placeholder={"Address of the recipient"}/>
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item>
|
|
|
+ <Button type="primary" htmlType="submit">
|
|
|
+ {coinInfo.allowance.toNumber() >= amount || coinInfo.isWrapped ? "Transfer" : "Approve"}
|
|
|
+ </Button>
|
|
|
+ </Form.Item>
|
|
|
+ </Form>
|
|
|
+ </Space>
|
|
|
+ </Col>
|
|
|
+ <Col>
|
|
|
+ <SplBalances/>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+
|
|
|
</>
|
|
|
);
|
|
|
}
|