mirror of https://github.com/certusone/oyster.git
feat: add associated token account
This commit is contained in:
parent
2820b3f22e
commit
c0f8f94108
|
@ -0,0 +1,5 @@
|
|||
import { ASSET_CHAIN } from "../../models/bridge/constants";
|
||||
|
||||
export const TokenDisplay = ({ asset, chain }: { asset: string, chain: ASSET_CHAIN }) => {
|
||||
return '';
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { Card, notification, Spin, Button } from 'antd';
|
||||
import { LAMPORTS_PER_SOL } from '@solana/web3.js';
|
||||
import { LABELS } from '../../constants';
|
||||
|
|
|
@ -56,7 +56,7 @@ export const EthereumProvider: FunctionComponent = ({children}) => {
|
|||
logoURI: val.logoURI ? val.logoURI?.replace('ipfs://', 'https://cloudflare-ipfs.com/ipfs/') : ` https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/${val.address}/logo.png `,
|
||||
tags: val.tags ? [...val.tags, extraTag] : [extraTag]
|
||||
};
|
||||
acc.set(val.address, item);
|
||||
acc.set(val.address.toLowerCase(), item);
|
||||
return acc;
|
||||
}, map));
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@ import {
|
|||
cache,
|
||||
TokenAccountParser,
|
||||
ParsedAccount,
|
||||
formatNumber,
|
||||
formatAmount,
|
||||
createAssociatedTokenAccountInstruction,
|
||||
} from '@oyster/common';
|
||||
|
||||
import { ethers } from 'ethers';
|
||||
|
@ -23,7 +26,6 @@ import {
|
|||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import { createTokenAccount } from '@oyster/common/dist/lib/actions';
|
||||
import { AccountInfo, AccountLayout } from '@solana/spl-token';
|
||||
|
||||
export interface ProgressUpdate {
|
||||
|
@ -92,11 +94,10 @@ export const transfer = async (
|
|||
return;
|
||||
}
|
||||
|
||||
const multiplier = ethers.utils
|
||||
.bigNumberify(10)
|
||||
.pow(ethers.utils.bigNumberify(request.info.decimals));
|
||||
let amountBN = ethers.utils.bigNumberify(request.amount).mul(multiplier);
|
||||
request.amountBN = amountBN;
|
||||
request.amountBN = ethers.utils.parseUnits(
|
||||
formatAmount(request.amount, 9),
|
||||
request.info.decimals,
|
||||
);
|
||||
|
||||
return steps.prepare(request);
|
||||
},
|
||||
|
@ -142,6 +143,8 @@ export const transfer = async (
|
|||
programIds().associatedToken,
|
||||
)
|
||||
)[0];
|
||||
|
||||
console.log('Recipient: ', recipient.toBase58());
|
||||
request.recipient = recipient.toBuffer();
|
||||
|
||||
const accounts = await getMultipleAccounts(
|
||||
|
@ -149,6 +152,7 @@ export const transfer = async (
|
|||
[mintKey.toBase58(), recipient.toBase58()],
|
||||
'single',
|
||||
);
|
||||
debugger;
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
const signers: Account[] = [];
|
||||
|
||||
|
@ -166,15 +170,12 @@ export const transfer = async (
|
|||
}
|
||||
|
||||
if (!accounts.array[1]) {
|
||||
createTokenAccount(
|
||||
createAssociatedTokenAccountInstruction(
|
||||
instructions,
|
||||
recipient,
|
||||
wallet.publicKey,
|
||||
wallet.publicKey,
|
||||
await connection.getMinimumBalanceForRentExemption(
|
||||
AccountLayout.span,
|
||||
),
|
||||
mintKey,
|
||||
wallet.publicKey,
|
||||
signers,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
import { AccountLayout, MintLayout, Token } from '@solana/spl-token';
|
||||
import { Account, PublicKey, SystemProgram, TransactionInstruction } from '@solana/web3.js';
|
||||
import { TOKEN_PROGRAM_ID, WRAPPED_SOL_MINT } from '../utils/ids';
|
||||
import {
|
||||
Account,
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
SYSVAR_RENT_PUBKEY,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import {
|
||||
SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
|
||||
TOKEN_PROGRAM_ID,
|
||||
WRAPPED_SOL_MINT,
|
||||
} from '../utils/ids';
|
||||
import { TokenAccount } from '../models/account';
|
||||
import { cache, TokenAccountParser } from '../contexts/accounts';
|
||||
|
||||
|
@ -10,17 +20,37 @@ export function ensureSplAccount(
|
|||
toCheck: TokenAccount,
|
||||
payer: PublicKey,
|
||||
amount: number,
|
||||
signers: Account[]
|
||||
signers: Account[],
|
||||
) {
|
||||
if (!toCheck.info.isNative) {
|
||||
return toCheck.pubkey;
|
||||
}
|
||||
|
||||
const account = createUninitializedAccount(instructions, payer, amount, signers);
|
||||
const account = createUninitializedAccount(
|
||||
instructions,
|
||||
payer,
|
||||
amount,
|
||||
signers,
|
||||
);
|
||||
|
||||
instructions.push(Token.createInitAccountInstruction(TOKEN_PROGRAM_ID, WRAPPED_SOL_MINT, account, payer));
|
||||
instructions.push(
|
||||
Token.createInitAccountInstruction(
|
||||
TOKEN_PROGRAM_ID,
|
||||
WRAPPED_SOL_MINT,
|
||||
account,
|
||||
payer,
|
||||
),
|
||||
);
|
||||
|
||||
cleanupInstructions.push(Token.createCloseAccountInstruction(TOKEN_PROGRAM_ID, account, payer, payer, []));
|
||||
cleanupInstructions.push(
|
||||
Token.createCloseAccountInstruction(
|
||||
TOKEN_PROGRAM_ID,
|
||||
account,
|
||||
payer,
|
||||
payer,
|
||||
[],
|
||||
),
|
||||
);
|
||||
|
||||
return account;
|
||||
}
|
||||
|
@ -32,7 +62,7 @@ export function createTempMemoryAccount(
|
|||
payer: PublicKey,
|
||||
signers: Account[],
|
||||
owner: PublicKey,
|
||||
space = DEFAULT_TEMP_MEM_SPACE
|
||||
space = DEFAULT_TEMP_MEM_SPACE,
|
||||
) {
|
||||
const account = new Account();
|
||||
instructions.push(
|
||||
|
@ -43,7 +73,7 @@ export function createTempMemoryAccount(
|
|||
lamports: 0,
|
||||
space: space,
|
||||
programId: owner,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
signers.push(account);
|
||||
|
@ -55,7 +85,7 @@ export function createUninitializedMint(
|
|||
instructions: TransactionInstruction[],
|
||||
payer: PublicKey,
|
||||
amount: number,
|
||||
signers: Account[]
|
||||
signers: Account[],
|
||||
) {
|
||||
const account = new Account();
|
||||
instructions.push(
|
||||
|
@ -65,7 +95,7 @@ export function createUninitializedMint(
|
|||
lamports: amount,
|
||||
space: MintLayout.span,
|
||||
programId: TOKEN_PROGRAM_ID,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
signers.push(account);
|
||||
|
@ -77,7 +107,7 @@ export function createUninitializedAccount(
|
|||
instructions: TransactionInstruction[],
|
||||
payer: PublicKey,
|
||||
amount: number,
|
||||
signers: Account[]
|
||||
signers: Account[],
|
||||
) {
|
||||
const account = new Account();
|
||||
instructions.push(
|
||||
|
@ -87,7 +117,7 @@ export function createUninitializedAccount(
|
|||
lamports: amount,
|
||||
space: AccountLayout.span,
|
||||
programId: TOKEN_PROGRAM_ID,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
signers.push(account);
|
||||
|
@ -95,17 +125,77 @@ export function createUninitializedAccount(
|
|||
return account.publicKey;
|
||||
}
|
||||
|
||||
export function createAssociatedTokenAccountInstruction(
|
||||
instructions: TransactionInstruction[],
|
||||
associatedTokenAddress: PublicKey,
|
||||
payer: PublicKey,
|
||||
walletAddress: PublicKey,
|
||||
splTokenMintAddress: PublicKey,
|
||||
) {
|
||||
const keys = [
|
||||
{
|
||||
pubkey: payer,
|
||||
isSigner: true,
|
||||
isWritable: true,
|
||||
},
|
||||
{
|
||||
pubkey: associatedTokenAddress,
|
||||
isSigner: false,
|
||||
isWritable: true,
|
||||
},
|
||||
{
|
||||
pubkey: walletAddress,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: splTokenMintAddress,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: SystemProgram.programId,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: TOKEN_PROGRAM_ID,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: SYSVAR_RENT_PUBKEY,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
];
|
||||
instructions.push(
|
||||
new TransactionInstruction({
|
||||
keys,
|
||||
programId: SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
|
||||
data: Buffer.from([]),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export function createTokenAccount(
|
||||
instructions: TransactionInstruction[],
|
||||
payer: PublicKey,
|
||||
accountRentExempt: number,
|
||||
mint: PublicKey,
|
||||
owner: PublicKey,
|
||||
signers: Account[]
|
||||
signers: Account[],
|
||||
) {
|
||||
const account = createUninitializedAccount(instructions, payer, accountRentExempt, signers);
|
||||
const account = createUninitializedAccount(
|
||||
instructions,
|
||||
payer,
|
||||
accountRentExempt,
|
||||
signers,
|
||||
);
|
||||
|
||||
instructions.push(Token.createInitAccountInstruction(TOKEN_PROGRAM_ID, mint, account, owner));
|
||||
instructions.push(
|
||||
Token.createInitAccountInstruction(TOKEN_PROGRAM_ID, mint, account, owner),
|
||||
);
|
||||
|
||||
return account;
|
||||
}
|
||||
|
@ -119,18 +209,18 @@ export function findOrCreateAccountByMint(
|
|||
accountRentExempt: number,
|
||||
mint: PublicKey, // use to identify same type
|
||||
signers: Account[],
|
||||
excluded?: Set<string>
|
||||
excluded?: Set<string>,
|
||||
): PublicKey {
|
||||
const accountToFind = mint.toBase58();
|
||||
const account = cache
|
||||
.byParser(TokenAccountParser)
|
||||
.map((id) => cache.get(id))
|
||||
.map(id => cache.get(id))
|
||||
.find(
|
||||
(acc) =>
|
||||
acc =>
|
||||
acc !== undefined &&
|
||||
acc.info.mint.toBase58() === accountToFind &&
|
||||
acc.info.owner.toBase58() === owner.toBase58() &&
|
||||
(excluded === undefined || !excluded.has(acc.pubkey.toBase58()))
|
||||
(excluded === undefined || !excluded.has(acc.pubkey.toBase58())),
|
||||
);
|
||||
const isWrappedSol = accountToFind === WRAPPED_SOL_MINT.toBase58();
|
||||
|
||||
|
@ -139,10 +229,25 @@ export function findOrCreateAccountByMint(
|
|||
toAccount = account.pubkey;
|
||||
} else {
|
||||
// creating depositor pool account
|
||||
toAccount = createTokenAccount(instructions, payer, accountRentExempt, mint, owner, signers);
|
||||
toAccount = createTokenAccount(
|
||||
instructions,
|
||||
payer,
|
||||
accountRentExempt,
|
||||
mint,
|
||||
owner,
|
||||
signers,
|
||||
);
|
||||
|
||||
if (isWrappedSol) {
|
||||
cleanupInstructions.push(Token.createCloseAccountInstruction(TOKEN_PROGRAM_ID, toAccount, payer, payer, []));
|
||||
cleanupInstructions.push(
|
||||
Token.createCloseAccountInstruction(
|
||||
TOKEN_PROGRAM_ID,
|
||||
toAccount,
|
||||
payer,
|
||||
payer,
|
||||
[],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export * as actions from './actions';
|
||||
export * from './actions';
|
||||
export * as components from './components';
|
||||
export * from './components'; // Allow direct exports too
|
||||
export * as constants from './constants';
|
||||
|
|
Loading…
Reference in New Issue