web: properly parse pending transfer for client-side submission

This commit is contained in:
Hendrik Hofstadt 2020-08-28 16:44:00 +02:00
parent f6750a3762
commit 7a5373a8cc
2 changed files with 74 additions and 20 deletions

View File

@ -8,38 +8,59 @@ import {ethers} from "ethers";
import {WormholeFactory} from "../contracts/WormholeFactory";
import {BRIDGE_ADDRESS} from "../config";
import {keccak256} from "ethers/utils";
import BN from 'bn.js';
import {PublicKey} from "@solana/web3.js";
// @ts-ignore
const provider = new ethers.providers.Web3Provider(window.ethereum);
interface LockupWithStatus extends Lockup {
status: LockupStatus,
}
enum LockupStatus {
AWAITING_VAA,
UNCLAIMED_VAA,
COMPLETED
}
function TransferProposals() {
let s = useContext(SlotContext);
let t = useContext(SolanaTokenContext);
let tokens = useContext(SolanaTokenContext);
let b = useContext(BridgeContext);
let [lockups, setLockups] = useState<Lockup[]>([])
let [lockups, setLockups] = useState<LockupWithStatus[]>([])
useEffect(() => {
if (s % 10 !== 0) return;
let updateLockups = async () => {
let lockups = [];
let lockups: LockupWithStatus[] = [];
for (let account of tokens.balances) {
let accLockups = await b.fetchTransferProposals(account.account)
lockups.push(...accLockups)
lockups.push(...accLockups.map(v => {
return {
status: LockupStatus.AWAITING_VAA,
...v
}
}))
}
let wormhole = WormholeFactory.connect(BRIDGE_ADDRESS, provider);
for (let lockup of lockups) {
console.log(lockup)
if (lockup.vaaTime === undefined || lockup.vaaTime === 0) continue;
let signingData = lockup.vaa.slice(lockup.vaa[5] * 66 + 6)
for (let i = signingData.length; i > 0; i--) {
if (signingData[i] == 0xff) {
signingData = signingData.slice(0, i)
break
}
}
let hash = keccak256(signingData)
let submissionStatus = await wormhole.consumedVAAs(hash);
let status = await wormhole.consumedVAAs(hash)
lockup.initialized = status;
lockup.status = submissionStatus ? LockupStatus.COMPLETED : LockupStatus.UNCLAIMED_VAA;
}
setLockups(lockups);
@ -47,27 +68,57 @@ function TransferProposals() {
updateLockups()
}, [s])
let statusToPrompt = (v: LockupStatus) => {
switch (v) {
case LockupStatus.AWAITING_VAA:
return ("Awaiting VAA");
case LockupStatus.UNCLAIMED_VAA:
return ("Submit to chain");
case LockupStatus.COMPLETED:
return ("Completed");
}
}
const columns = [
{
title: 'SourceAccount',
key: 'source',
render: (n: any, v: Lockup) => v.sourceAddress.toString()
render: (n: any, v: LockupWithStatus) => "SOL: " + v.sourceAddress.toString()
},
{
title: 'Mint',
title: 'TargetAccount',
key: 'target',
render: (n: any, v: LockupWithStatus) => {
switch (v.toChain) {
case 1:
return "SOL: " + new PublicKey(v.targetAddress).toString()
case 2:
return "ETH: 0x" + new Buffer(v.targetAddress.slice(12)).toString("hex")
}
}
},
{
title: 'Asset',
key: 'assetAddress',
render: (n: any, v: Lockup) => v.assetAddress.toString()
render: (n: any, v: LockupWithStatus) => {
switch (v.assetChain) {
case 1:
return "SOL: " + new PublicKey(v.assetAddress).toString()
case 2:
return "ETH: 0x" + new Buffer(v.assetAddress.slice(12)).toString("hex")
}
}
},
{
title: 'Amount',
key: 'amount',
render: (n: any, v: Lockup) => v.amount.toString()
render: (n: any, v: LockupWithStatus) => v.amount.div(new BN(10).pow(new BN(v.assetDecimals))).toString()
},
{
title: 'Status',
key: 'status',
render: (n: any, v: Lockup) => {
return (<>Pending {v.initialized}</>)
render: (n: any, v: LockupWithStatus) => {
return (<>{statusToPrompt(v.status)}</>)
}
},
];

View File

@ -20,6 +20,7 @@ export interface Lockup {
targetAddress: Uint8Array,
assetAddress: Uint8Array,
assetChain: number,
assetDecimals: number,
nonce: number,
vaa: Uint8Array,
vaaTime: number,
@ -176,8 +177,10 @@ class SolanaBridge {
BufferLayout.blob(32, 'assetAddress'),
BufferLayout.u8('assetChain'),
BufferLayout.u8('assetDecimals'),
BufferLayout.seq(BufferLayout.u8(), 1), // 4 byte alignment because a u32 is following
BufferLayout.u32('nonce'),
BufferLayout.blob(1001, 'vaa'),
BufferLayout.seq(BufferLayout.u8(), 3), // 4 byte alignment because a u32 is following
BufferLayout.u32('vaaTime'),
BufferLayout.u8('initialized'),
]);
@ -186,18 +189,18 @@ class SolanaBridge {
for (let acc of raw_accounts) {
acc = acc.account;
let parsedAccount = dataLayout.decode(bs58.decode(acc.data))
console.log(parsedAccount);
accounts.push({
amount: new BN(parsedAccount.amount, 2, "le"),
assetAddress: parsedAccount.assetAddress,
assetChain: acc.assetChain,
initialized: acc.initialized == 1,
nonce: acc.nonce,
assetChain: parsedAccount.assetChain,
assetDecimals: parsedAccount.assetDecimals,
initialized: parsedAccount.initialized == 1,
nonce: parsedAccount.nonce,
sourceAddress: new PublicKey(parsedAccount.sourceAddress),
targetAddress: parsedAccount.targetAddress,
toChain: acc.toChain,
vaa: acc.vaa,
vaaTime: acc.vaaTime
toChain: parsedAccount.toChain,
vaa: parsedAccount.vaa,
vaaTime: parsedAccount.vaaTime
})
}