feat: to solana

This commit is contained in:
bartosz-lipinski 2021-03-12 16:20:22 -06:00
parent 85d3f8aaf4
commit 3db159667d
6 changed files with 128 additions and 104 deletions

View File

@ -33,7 +33,7 @@ export const AppLayout = React.memo((props: any) => {
<Wormhole
onCreated={() => setWormholeReady(true)}
show={true}
rotate={isRoot}
rotate={true}
>
<Layout title={LABELS.APP_TITLE}>
{isRoot && (

View File

@ -47,7 +47,7 @@ const WormholeGeometry = ({ rotate }: { rotate?: boolean }) => {
if (mesh.current) {
// x-Axis defines the "top" we're looking at, try e.g. 30.5
mesh.current.rotation.x = 30;
if (!rotate) {
if (rotate) {
mesh.current.rotation.z += 0.0005;
}
}

View File

@ -37,20 +37,28 @@ export const fromSolana = async (
provider: ethers.providers.Web3Provider,
setProgress: (update: ProgressUpdate) => void,
) => {
if (!request.asset) {
if (
!request.asset ||
!request.amount ||
!request.recipient ||
!request.toChain ||
!request.info
) {
return;
}
const walletName = 'MetaMask';
request.signer = provider?.getSigner();
request.recipient = Buffer.from(
(await request.signer.getAddress()).slice(2),
'hex',
);
request.nonce = await provider.getTransactionCount(
request.signer.getAddress(),
const signer = provider?.getSigner();
request.recipient = Buffer.from((await signer.getAddress()).slice(2), 'hex');
const nonce = await provider.getTransactionCount(
signer.getAddress(),
'pending',
);
request.amountBN = ethers.utils.parseUnits(
request.amount.toString(),
request.info.decimals,
);
let counter = 0;
// check difference between lock/approve (invoke lock if allowance < amount)
const steps = {
@ -63,11 +71,6 @@ export const fromSolana = async (
throw new Error('Missing amount');
}
request.amountBN = ethers.utils.parseUnits(
request.amount.toString(),
request.info.decimals,
);
return steps.lock(request);
},
@ -138,75 +141,108 @@ export const fromSolana = async (
proposalKey: PublicKey,
slot: number,
) => {
let completed = false;
let startSlot = slot;
return new Promise<void>((resolve, reject) => {
let completed = false;
let startSlot = slot;
let group = 'Lock assets';
let group = 'Lock assets';
let slotUpdateListener = connection.onSlotChange(slot => {
if (completed) return;
const passedSlots = slot.slot - startSlot;
const isLast = passedSlots - 1 === 31;
if (passedSlots < 32) {
// setLoading({
// loading: true,
// message: "Awaiting confirmations",
// progress: {
// completion: (slot.slot - startSlot) / 32 * 100,
// content: `${slot.slot - startSlot}/${32}`
// }
// })
// setProgress({
// message: ethConfirmationMessage(passedBlocks),
// type: isLast ? 'done' : 'wait',
// step: counter++,
// group,
// replace: passedBlocks > 0,
// });
} else {
//setLoading({loading: true, message: "Awaiting guardian confirmation"})
}
});
let accountChangeListener = connection.onAccountChange(
proposalKey,
async a => {
let slotUpdateListener = connection.onSlotChange(slot => {
if (completed) return;
const passedSlots = slot.slot - startSlot;
const isLast = passedSlots - 1 === 31;
if (passedSlots < 32) {
// setLoading({
// loading: true,
// message: "Awaiting confirmations",
// progress: {
// completion: (slot.slot - startSlot) / 32 * 100,
// content: `${slot.slot - startSlot}/${32}`
// }
// })
// setProgress({
// message: ethConfirmationMessage(passedBlocks),
// type: isLast ? 'done' : 'wait',
// step: counter++,
// group,
// replace: passedBlocks > 0,
// });
} else {
//setLoading({loading: true, message: "Awaiting guardian confirmation"})
}
});
let lockup = TransferOutProposalLayout.decode(a.data);
let vaa = lockup.vaa;
let accountChangeListener = connection.onAccountChange(
proposalKey,
async a => {
if (completed) return;
for (let i = vaa.length; i > 0; i--) {
if (vaa[i] == 0xff) {
vaa = vaa.slice(0, i);
break;
let lockup = TransferOutProposalLayout.decode(a.data);
let vaa = lockup.vaa;
for (let i = vaa.length; i > 0; i--) {
if (vaa[i] == 0xff) {
vaa = vaa.slice(0, i);
break;
}
}
}
// Probably a poke
if (vaa.filter((v: number) => v !== 0).length == 0) {
return;
}
// Probably a poke
if (vaa.filter((v: number) => v !== 0).length == 0) {
return;
}
completed = true;
connection.removeAccountChangeListener(accountChangeListener);
connection.removeSlotChangeListener(slotUpdateListener);
completed = true;
connection.removeAccountChangeListener(accountChangeListener);
connection.removeSlotChangeListener(slotUpdateListener);
// let signatures = await bridge.fetchSignatureStatus(lockup.signatureAccount);
// let sigData = Buffer.of(...signatures.reduce((previousValue, currentValue) => {
// previousValue.push(currentValue.index)
// previousValue.push(...currentValue.signature)
let signatures = await bridge.fetchSignatureStatus(
lockup.signatureAccount,
);
let sigData = Buffer.of(
...signatures.reduce((previousValue, currentValue) => {
previousValue.push(currentValue.index);
previousValue.push(...currentValue.signature);
// return previousValue
// }, new Array<number>()))
return previousValue;
}, new Array<number>()),
);
// vaa = Buffer.concat([vaa.slice(0, 5), Buffer.of(signatures.length), sigData, vaa.slice(6)])
// transferVAA = vaa
},
'single',
);
vaa = Buffer.concat([
vaa.slice(0, 5),
Buffer.of(signatures.length),
sigData,
vaa.slice(6),
]);
// transferVAA = vaa
try {
await steps.postVAA(request);
resolve();
} catch {
reject();
}
},
'single',
);
});
},
postVAA: async (request: TransferRequest) => {
let wh = WormholeFactory.connect(programIds().wormhole.bridge, signer);
// setLoading({
// ...loading,
// loading: true,
// message: "Sign the claim...",
// })
let tx = await wh.submitVAA(vaa);
// setLoading({
// ...loading,
// loading: true,
// message: "Waiting for tokens unlock to be mined...",
// })
await tx.wait(1);
// message.success({content: "Execution of VAA succeeded", key: "eth_tx"})
},
postVAA: async (request: TransferRequest) => {},
};
return steps.transfer(request);

View File

@ -24,11 +24,6 @@ export interface TransferRequestInfo {
}
export interface TransferRequest {
// ethereum specific fields, TODO: remove
nonce?: number;
signer?: ethers.Signer;
amountBN?: BigNumber;
amount?: number;
info?: TransferRequestInfo;

View File

@ -30,17 +30,22 @@ export const toSolana = async (
provider: ethers.providers.Web3Provider,
setProgress: (update: ProgressUpdate) => void,
) => {
if (!request.asset) {
if (!request.asset || !request.amount || !request.info) {
return;
}
const walletName = 'MetaMask';
request.signer = provider?.getSigner();
const signer = provider?.getSigner();
request.nonce = await provider.getTransactionCount(
request.signer.getAddress(),
const nonce = await provider.getTransactionCount(
signer.getAddress(),
'pending',
);
const amountBN = ethers.utils.parseUnits(
request.amount.toString(),
request.info.decimals,
);
let counter = 0;
// check difference between lock/approve (invoke lock if allowance < amount)
const steps = {
@ -49,11 +54,6 @@ export const toSolana = async (
return;
}
request.amountBN = ethers.utils.parseUnits(
request.amount.toString(),
request.info.decimals,
);
return steps.prepare(request);
},
@ -162,24 +162,21 @@ export const toSolana = async (
},
// approves assets for transfer
approve: async (request: TransferRequest) => {
if (!request.amountBN || !request.asset || !request.signer) {
if (!request.asset) {
return;
}
const group = 'Approve assets';
try {
if (request.info?.allowance.lt(request.amountBN)) {
let e = Erc20Factory.connect(request.asset, request.signer);
if (request.info?.allowance.lt(amountBN)) {
let e = Erc20Factory.connect(request.asset, signer);
setProgress({
message: `Waiting for ${walletName} approval`,
type: 'user',
group,
step: counter++,
});
let res = await e.approve(
programIds().wormhole.bridge,
request.amountBN,
);
let res = await e.approve(programIds().wormhole.bridge, amountBN);
setProgress({
message: 'Waiting for ETH transaction to be mined...',
type: 'wait',
@ -216,13 +213,11 @@ export const toSolana = async (
// locks assets in the bridge
lock: async (request: TransferRequest) => {
if (
!request.amountBN ||
!amountBN ||
!request.asset ||
!request.signer ||
!request.recipient ||
!request.toChain ||
!request.info ||
!request.nonce
!request.info
) {
return;
}
@ -230,10 +225,7 @@ export const toSolana = async (
let group = 'Lock assets';
try {
let wh = WormholeFactory.connect(
programIds().wormhole.bridge,
request.signer,
);
let wh = WormholeFactory.connect(programIds().wormhole.bridge, signer);
setProgress({
message: `Waiting for ${walletName} transfer approval`,
type: 'user',
@ -242,10 +234,10 @@ export const toSolana = async (
});
let res = await wh.lockAssets(
request.asset,
request.amountBN,
amountBN,
request.recipient,
request.toChain,
request.nonce,
nonce,
false,
);
setProgress({

View File

@ -3,6 +3,7 @@ import {
getVerboseTokenName,
KnownTokenMap,
} from '@oyster/common';
import { TokenInfo } from '@solana/spl-token-registry';
export const getAssetName = (
parsedAssetAddress: string,
@ -48,6 +49,6 @@ export const chainToName = (chain?: ASSET_CHAIN) => {
return CHAIN_NAME[chain || ASSET_CHAIN.Ethereum];
};
export const filterModalSolTokens = (tokens: any[]) => {
export const filterModalSolTokens = (tokens: TokenInfo[]) => {
return tokens;
};