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 './style.less';
|
||||||
import { ASSET_CHAIN, chainToName } from '../../utils/assets';
|
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 { useEthereum } from '../../contexts';
|
||||||
import { TokenDisplay } from './../TokenDisplay';
|
import { TokenDisplay } from './../TokenDisplay';
|
||||||
import { WrappedAssetFactory } from '../../contracts/WrappedAssetFactory';
|
import { WrappedAssetFactory } from '../../contracts/WrappedAssetFactory';
|
||||||
|
@ -197,6 +197,26 @@ export const Transfer = () => {
|
||||||
(async () => {
|
(async () => {
|
||||||
let steps: ProgressUpdate[] = [];
|
let steps: ProgressUpdate[] = [];
|
||||||
try {
|
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) {
|
if (request.toChain === ASSET_CHAIN.Solana) {
|
||||||
await toSolana(
|
await toSolana(
|
||||||
connection,
|
connection,
|
||||||
|
|
|
@ -24,7 +24,7 @@ import {
|
||||||
SystemProgram,
|
SystemProgram,
|
||||||
TransactionInstruction,
|
TransactionInstruction,
|
||||||
} from '@solana/web3.js';
|
} from '@solana/web3.js';
|
||||||
import { AccountInfo, Token } from '@solana/spl-token';
|
import { Token } from '@solana/spl-token';
|
||||||
import { ProgressUpdate, TransferRequest } from './interface';
|
import { ProgressUpdate, TransferRequest } from './interface';
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import { createLockAssetInstruction } from '../lock';
|
import { createLockAssetInstruction } from '../lock';
|
||||||
|
@ -42,7 +42,10 @@ export const fromSolana = async (
|
||||||
}
|
}
|
||||||
const walletName = 'MetaMask';
|
const walletName = 'MetaMask';
|
||||||
request.signer = provider?.getSigner();
|
request.signer = provider?.getSigner();
|
||||||
|
request.recipient = Buffer.from(
|
||||||
|
(await request.signer.getAddress()).slice(2),
|
||||||
|
'hex',
|
||||||
|
);
|
||||||
request.nonce = await provider.getTransactionCount(
|
request.nonce = await provider.getTransactionCount(
|
||||||
request.signer.getAddress(),
|
request.signer.getAddress(),
|
||||||
'pending',
|
'pending',
|
||||||
|
@ -65,110 +68,6 @@ export const fromSolana = async (
|
||||||
request.info.decimals,
|
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);
|
return steps.lock(request);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -176,21 +75,15 @@ export const fromSolana = async (
|
||||||
lock: async (request: TransferRequest) => {
|
lock: async (request: TransferRequest) => {
|
||||||
if (
|
if (
|
||||||
!request.amount ||
|
!request.amount ||
|
||||||
!request.asset ||
|
|
||||||
!request.signer ||
|
|
||||||
!request.recipient ||
|
!request.recipient ||
|
||||||
!request.toChain ||
|
!request.toChain ||
|
||||||
!request.info ||
|
!request.info ||
|
||||||
!request.nonce ||
|
|
||||||
!wallet.publicKey
|
!wallet.publicKey
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let group = 'Lock assets';
|
let group = 'Lock assets';
|
||||||
let transferProposal: PublicKey;
|
|
||||||
let transferVAA = new Uint8Array(0);
|
|
||||||
|
|
||||||
const programs = programIds();
|
const programs = programIds();
|
||||||
const bridgeId = programs.wormhole.pubkey;
|
const bridgeId = programs.wormhole.pubkey;
|
||||||
const authorityKey = await bridgeAuthorityKey(bridgeId);
|
const authorityKey = await bridgeAuthorityKey(bridgeId);
|
||||||
|
|
|
@ -24,16 +24,18 @@ export interface TransferRequestInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TransferRequest {
|
export interface TransferRequest {
|
||||||
|
// ethereum specific fields, TODO: remove
|
||||||
nonce?: number;
|
nonce?: number;
|
||||||
signer?: ethers.Signer;
|
signer?: ethers.Signer;
|
||||||
asset?: string;
|
|
||||||
amount?: number;
|
|
||||||
amountBN?: BigNumber;
|
amountBN?: BigNumber;
|
||||||
|
|
||||||
recipient?: Buffer;
|
amount?: number;
|
||||||
|
|
||||||
info?: TransferRequestInfo;
|
info?: TransferRequestInfo;
|
||||||
|
|
||||||
from?: ASSET_CHAIN;
|
from?: ASSET_CHAIN;
|
||||||
|
asset?: string;
|
||||||
|
|
||||||
toChain?: ASSET_CHAIN;
|
toChain?: ASSET_CHAIN;
|
||||||
|
recipient?: Buffer;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue