web: properly parse pending transfer for client-side submission
This commit is contained in:
parent
f6750a3762
commit
7a5373a8cc
|
@ -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)}</>)
|
||||
}
|
||||
},
|
||||
];
|
||||
|
|
|
@ -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
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue