feat: add fromSolana

This commit is contained in:
bartosz-lipinski 2021-03-11 14:49:41 -06:00
parent b2f60da823
commit 8b2520e414
3 changed files with 31 additions and 116 deletions

View File

@ -10,7 +10,7 @@ import { Input } from './../Input';
import './style.less';
import { ASSET_CHAIN, chainToName } from '../../utils/assets';
import { ProgressUpdate, toSolana, TransferRequest } from '../../models/bridge';
import { fromSolana, ProgressUpdate, toSolana, TransferRequest } from '../../models/bridge';
import { useEthereum } from '../../contexts';
import { TokenDisplay } from './../TokenDisplay';
import { WrappedAssetFactory } from '../../contracts/WrappedAssetFactory';
@ -197,6 +197,26 @@ export const Transfer = () => {
(async () => {
let steps: ProgressUpdate[] = [];
try {
if(request.from === ASSET_CHAIN.Solana) {
debugger;
await fromSolana(
connection,
wallet,
request,
provider,
update => {
if (update.replace) {
steps.pop();
steps = [...steps, update];
} else {
steps = [...steps, update];
}
setActiveSteps(steps);
},
);
}
if (request.toChain === ASSET_CHAIN.Solana) {
await toSolana(
connection,

View File

@ -24,7 +24,7 @@ import {
SystemProgram,
TransactionInstruction,
} from '@solana/web3.js';
import { AccountInfo, Token } from '@solana/spl-token';
import { Token } from '@solana/spl-token';
import { ProgressUpdate, TransferRequest } from './interface';
import BN from 'bn.js';
import { createLockAssetInstruction } from '../lock';
@ -42,7 +42,10 @@ export const fromSolana = async (
}
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(),
'pending',
@ -65,110 +68,6 @@ export const fromSolana = async (
request.info.decimals,
);
return steps.prepare(request);
},
// creates wrapped account on solana
prepare: async (request: TransferRequest) => {
if (!request.info || !request.from || !wallet.publicKey) {
return;
}
const group = 'Initiate transfer';
try {
const bridgeId = programIds().wormhole.pubkey;
const authority = await bridgeAuthorityKey(bridgeId);
const meta: AssetMeta = {
decimals: Math.min(request.info?.decimals, 9),
address: request.info?.assetAddress,
chain: request.from,
};
const mintKey = await wrappedAssetMintKey(bridgeId, authority, meta);
const recipientKey =
cache
.byParser(TokenAccountParser)
.map(key => {
let account = cache.get(key) as ParsedAccount<AccountInfo>;
if (account?.info.mint.toBase58() === mintKey.toBase58()) {
return key;
}
return;
})
.find(_ => _) || '';
const recipient: PublicKey = recipientKey
? new PublicKey(recipientKey)
: (
await PublicKey.findProgramAddress(
[
wallet.publicKey.toBuffer(),
programIds().token.toBuffer(),
mintKey.toBuffer(),
],
programIds().associatedToken,
)
)[0];
request.recipient = recipient.toBuffer();
const accounts = await getMultipleAccounts(
connection,
[mintKey.toBase58(), recipient.toBase58()],
'single',
);
const instructions: TransactionInstruction[] = [];
const signers: Account[] = [];
if (!accounts.array[0]) {
// create mint using wormhole instruction
instructions.push(
await createWrappedAssetInstruction(
meta,
bridgeId,
authority,
mintKey,
wallet.publicKey,
),
);
}
if (!accounts.array[1]) {
createAssociatedTokenAccountInstruction(
instructions,
recipient,
wallet.publicKey,
wallet.publicKey,
mintKey,
);
}
if (instructions.length > 0) {
setProgress({
message: 'Waiting for Solana approval...',
type: 'user',
group,
step: counter++,
});
const { txid } = await sendTransaction(
connection,
wallet,
instructions,
signers,
true,
);
}
} catch (err) {
setProgress({
message: `Couldn't create Solana account!`,
type: 'error',
group,
step: counter++,
});
throw err;
}
return steps.lock(request);
},
@ -176,21 +75,15 @@ export const fromSolana = async (
lock: async (request: TransferRequest) => {
if (
!request.amount ||
!request.asset ||
!request.signer ||
!request.recipient ||
!request.toChain ||
!request.info ||
!request.nonce ||
!wallet.publicKey
) {
return;
}
let group = 'Lock assets';
let transferProposal: PublicKey;
let transferVAA = new Uint8Array(0);
const programs = programIds();
const bridgeId = programs.wormhole.pubkey;
const authorityKey = await bridgeAuthorityKey(bridgeId);

View File

@ -24,16 +24,18 @@ export interface TransferRequestInfo {
}
export interface TransferRequest {
// ethereum specific fields, TODO: remove
nonce?: number;
signer?: ethers.Signer;
asset?: string;
amount?: number;
amountBN?: BigNumber;
recipient?: Buffer;
amount?: number;
info?: TransferRequestInfo;
from?: ASSET_CHAIN;
asset?: string;
toChain?: ASSET_CHAIN;
recipient?: Buffer;
}