mirror of https://github.com/certusone/oyster.git
feat: add fromSolana
This commit is contained in:
parent
b2f60da823
commit
8b2520e414
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue