Distinguish SOL from Wrapped SOL (#60)

This commit is contained in:
Armani Ferrante 2021-06-24 19:01:38 -07:00 committed by GitHub
parent 671225aec8
commit 958f809be5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 20 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@project-serum/swap-ui", "name": "@project-serum/swap-ui",
"version": "0.1.9", "version": "0.1.10",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"homepage": "https://github.com/project-serum/swap-ui", "homepage": "https://github.com/project-serum/swap-ui",

View File

@ -31,7 +31,7 @@ import { useCanSwap, useReferral } from "../context/Swap";
import TokenDialog from "./TokenDialog"; import TokenDialog from "./TokenDialog";
import { SettingsButton } from "./Settings"; import { SettingsButton } from "./Settings";
import { InfoLabel } from "./Info"; import { InfoLabel } from "./Info";
import { WRAPPED_SOL_MINT } from "../utils/pubkeys"; import { SOL_MINT, WRAPPED_SOL_MINT } from "../utils/pubkeys";
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
card: { card: {
@ -364,11 +364,10 @@ export function SwapButton() {
let txs: { tx: Transaction; signers: Array<Signer | undefined> }[] = []; let txs: { tx: Transaction; signers: Array<Signer | undefined> }[] = [];
const amount = new BN(fromAmount * 10 ** fromMintInfo.decimals); const amount = new BN(fromAmount * 10 ** fromMintInfo.decimals);
const isSol = const isSol = fromMint.equals(SOL_MINT) || toMint.equals(SOL_MINT);
fromMint.equals(WRAPPED_SOL_MINT) || toMint.equals(WRAPPED_SOL_MINT);
const wrappedSolAccount = isSol ? Keypair.generate() : undefined; const wrappedSolAccount = isSol ? Keypair.generate() : undefined;
// Wrap the SOL into an SPL token. // Wrap the SOL into wrapped SOL.
if (isSol) { if (isSol) {
txs.push( txs.push(
await wrapSol( await wrapSol(
@ -401,12 +400,12 @@ export function SwapButton() {
const toOpenOrders = toMarket const toOpenOrders = toMarket
? openOrders.get(toMarket?.address.toString()) ? openOrders.get(toMarket?.address.toString())
: undefined; : undefined;
const fromWalletAddr = fromMint.equals(WRAPPED_SOL_MINT) const fromWalletAddr = fromMint.equals(SOL_MINT)
? wrappedSolAccount!.publicKey ? wrappedSolAccount!.publicKey
: fromWallet : fromWallet
? fromWallet.publicKey ? fromWallet.publicKey
: undefined; : undefined;
const toWalletAddr = toMint.equals(WRAPPED_SOL_MINT) const toWalletAddr = toMint.equals(SOL_MINT)
? wrappedSolAccount!.publicKey ? wrappedSolAccount!.publicKey
: toWallet : toWallet
? toWallet.publicKey ? toWallet.publicKey
@ -478,7 +477,7 @@ async function wrapSol(
); );
// Transfer lamports. These will be converted to an SPL balance by the // Transfer lamports. These will be converted to an SPL balance by the
// token program. // token program.
if (fromMint.equals(WRAPPED_SOL_MINT)) { if (fromMint.equals(SOL_MINT)) {
tx.add( tx.add(
SystemProgram.transfer({ SystemProgram.transfer({
fromPubkey: provider.wallet.publicKey, fromPubkey: provider.wallet.publicKey,

View File

@ -15,6 +15,8 @@ import {
DEX_PID, DEX_PID,
USDC_MINT, USDC_MINT,
USDT_MINT, USDT_MINT,
SOL_MINT,
WRAPPED_SOL_MINT,
WORM_USDC_MINT, WORM_USDC_MINT,
WORM_USDT_MINT, WORM_USDT_MINT,
WORM_USDC_MARKET, WORM_USDC_MARKET,
@ -389,7 +391,11 @@ export function useFairRoute(
if (fromMarket === undefined) { if (fromMarket === undefined) {
return undefined; return undefined;
} }
if (fromMarket?.baseMintAddress.equals(fromMint)) { if (
fromMarket?.baseMintAddress.equals(fromMint) ||
(fromMarket?.baseMintAddress.equals(WRAPPED_SOL_MINT) &&
fromMint.equals(SOL_MINT))
) {
return fromBbo.bestBid && 1.0 / fromBbo.bestBid; return fromBbo.bestBid && 1.0 / fromBbo.bestBid;
} else { } else {
return fromBbo.bestOffer && fromBbo.bestOffer; return fromBbo.bestOffer && fromBbo.bestOffer;
@ -442,7 +448,10 @@ export function useRouteVerbose(
const [wormholeMarket, kind] = swapMarket; const [wormholeMarket, kind] = swapMarket;
return { markets: [wormholeMarket], kind }; return { markets: [wormholeMarket], kind };
} }
const markets = swapClient.route(fromMint, toMint); const markets = swapClient.route(
fromMint.equals(SOL_MINT) ? WRAPPED_SOL_MINT : fromMint,
toMint.equals(SOL_MINT) ? WRAPPED_SOL_MINT : toMint
);
if (markets === null) { if (markets === null) {
return null; return null;
} }

View File

@ -10,7 +10,7 @@ import {
TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID,
} from "@solana/spl-token"; } from "@solana/spl-token";
import { getOwnedTokenAccounts, parseTokenAccountData } from "../utils/tokens"; import { getOwnedTokenAccounts, parseTokenAccountData } from "../utils/tokens";
import { WRAPPED_SOL_MINT } from "../utils/pubkeys"; import { SOL_MINT } from "../utils/pubkeys";
export type TokenContext = { export type TokenContext = {
provider: Provider; provider: Provider;
@ -47,7 +47,7 @@ export function TokenContextProvider(props: any) {
// @ts-ignore // @ts-ignore
account: { account: {
amount: new BN(acc.lamports), amount: new BN(acc.lamports),
mint: WRAPPED_SOL_MINT, mint: SOL_MINT,
}, },
}); });
setRefresh((r) => r + 1); setRefresh((r) => r + 1);
@ -95,7 +95,7 @@ export function useOwnedTokenAccount(
); );
let tokenAccount = tokenAccounts[0]; let tokenAccount = tokenAccounts[0];
const isSol = mint?.equals(WRAPPED_SOL_MINT); const isSol = mint?.equals(SOL_MINT);
// Stream updates when the balance changes. // Stream updates when the balance changes.
useEffect(() => { useEffect(() => {
@ -107,7 +107,7 @@ export function useOwnedTokenAccount(
(info: { lamports: number }) => { (info: { lamports: number }) => {
const token = { const token = {
amount: new BN(info.lamports), amount: new BN(info.lamports),
mint: WRAPPED_SOL_MINT, mint: SOL_MINT,
} as TokenAccount; } as TokenAccount;
if (token.amount !== tokenAccount.account.amount) { if (token.amount !== tokenAccount.account.amount) {
const index = _OWNED_TOKEN_ACCOUNTS_CACHE.indexOf(tokenAccount); const index = _OWNED_TOKEN_ACCOUNTS_CACHE.indexOf(tokenAccount);
@ -190,4 +190,7 @@ const _OWNED_TOKEN_ACCOUNTS_CACHE: Array<{
}> = []; }> = [];
// Cache storing all previously fetched mint infos. // Cache storing all previously fetched mint infos.
const _MINT_CACHE = new Map<string, Promise<MintInfo>>(); // @ts-ignore
const _MINT_CACHE = new Map<string, Promise<MintInfo>>([
[SOL_MINT.toString(), { decimals: 9 }],
]);

View File

@ -1,6 +1,6 @@
import React, { useContext, useMemo } from "react"; import React, { useContext, useMemo } from "react";
import { TokenInfo } from "@solana/spl-token-registry"; import { TokenInfo } from "@solana/spl-token-registry";
import { USDC_MINT, USDT_MINT } from "../utils/pubkeys"; import { SOL_MINT } from "../utils/pubkeys";
type TokenListContext = { type TokenListContext = {
tokenMap: Map<string, TokenInfo>; tokenMap: Map<string, TokenInfo>;
@ -18,11 +18,32 @@ export const SPL_REGISTRY_SOLLET_TAG = "wrapped-sollet";
// Tag in the spl-token-registry for wormhole wrapped tokens. // Tag in the spl-token-registry for wormhole wrapped tokens.
export const SPL_REGISTRY_WORM_TAG = "wormhole"; export const SPL_REGISTRY_WORM_TAG = "wormhole";
const SOL_TOKEN_INFO = {
chainId: 101,
address: SOL_MINT.toString(),
name: "Native SOL",
decimals: "9",
symbol: "SOL",
logoURI:
"https://cdn.jsdelivr.net/gh/trustwallet/assets@master/blockchains/solana/info/logo.png",
tags: [],
extensions: {
website: "https://solana.com/",
serumV3Usdc: "9wFFyRfZBsuAha4YcuxcXLKwMxJR43S7fPfQLusDBzvT",
serumV3Usdt: "HWHvQhFmJB3NUcu1aihKmrKegfVxBEHzwVX6yZCKEsi1",
coingeckoId: "solana",
waterfallbot: "https://t.me/SOLwaterfall",
},
};
export function TokenListContextProvider(props: any) { export function TokenListContextProvider(props: any) {
const tokenList = useMemo( const tokenList = useMemo(() => {
() => props.tokenList.filterByClusterSlug("mainnet-beta").getList(), const list = props.tokenList.filterByClusterSlug("mainnet-beta").getList();
[props.tokenList] // Manually add a fake SOL mint for the native token. The component is
); // opinionated in that it distinguishes between wrapped SOL and SOL.
list.push(SOL_TOKEN_INFO);
return list;
}, [props.tokenList]);
// Token map for quick lookup. // Token map for quick lookup.
const tokenMap = useMemo(() => { const tokenMap = useMemo(() => {

View File

@ -16,6 +16,11 @@ export const USDT_MINT = new PublicKey(
"Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB" "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"
); );
// Arbitrary mint to represent SOL (not wrapped SOL).
export const SOL_MINT = new PublicKey(
"Ejmc1UB4EsES5oAaRN63SpoxMJidt3ZGBrqrZk49vjTZ"
);
export const WRAPPED_SOL_MINT = new PublicKey( export const WRAPPED_SOL_MINT = new PublicKey(
"So11111111111111111111111111111111111111112" "So11111111111111111111111111111111111111112"
); );