Skip to content

Commit

Permalink
feat: add linking to custom accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
bartosz-lipinski committed Nov 6, 2020
1 parent e9827a7 commit 46d723a
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 283 deletions.
29 changes: 15 additions & 14 deletions src/components/currencyInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,26 +71,27 @@ export const CurrencyInput = (props: {
return map;
}, new Map<string, { account: TokenAccount; pool: PoolInfo | undefined }[]>());

// TODO: group multple accounts of same time and select one with max amount
const renderAdditionalTokens = [...grouppedUserAccounts.keys()].map(
const additionalAccounts = [...grouppedUserAccounts.keys()];
if (tokens.findIndex((t) => t.mintAddress === props.mint) < 0 && props.mint && !grouppedUserAccounts.has(props?.mint)) {
additionalAccounts.push(props.mint);
}

const renderAdditionalTokens = additionalAccounts.map(
(mint) => {
let pool: PoolInfo | undefined;
const list = grouppedUserAccounts.get(mint);
if (!list || list.length <= 0) {
return undefined;
}

const account = list[0];

if (account.account.info.amount.eqn(0)) {
return undefined;
if (list && list.length > 0) {
// TODO: group multple accounts of same time and select one with max amount
const account = list[0];
pool = account.pool;
}

let name: string;
let icon: JSX.Element;
if (account.pool) {
name = getPoolName(env, account.pool);
if (pool) {
name = getPoolName(env, pool);

const sorted = account.pool.pubkeys.holdingMints
const sorted = pool.pubkeys.holdingMints
.map((a: PublicKey) => a.toBase58())
.sort();
icon = <PoolIcon mintA={sorted[0]} mintB={sorted[1]} />;
Expand All @@ -101,7 +102,7 @@ export const CurrencyInput = (props: {

return (
<Option
key={account.account.pubkey.toBase58()}
key={mint}
value={mint}
name={name}
title={mint}
Expand Down
5 changes: 5 additions & 0 deletions src/components/currencyInput/styles.less
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
.ccy-input {
margin-top: 10px;
margin-bottom: 10px;


.ant-select-selector,
.ant-select-selector:focus,
.ant-select-selector:active {
border-color: transparent !important;
box-shadow: none !important;
}
;
}

.ccy-input-header {
Expand Down
4 changes: 2 additions & 2 deletions src/components/identicon/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useRef } from "react";

import Jazzicon from "jazzicon";

import bs58 from 'bs58';
import "./style.less";

export const Identicon = (props: {
Expand All @@ -15,7 +15,7 @@ export const Identicon = (props: {
if (address && ref.current) {
ref.current.innerHTML = "";
ref.current.appendChild(
Jazzicon(style?.width || 16, parseInt(address.slice(0, 10), 16))
Jazzicon(style?.width || 16, parseInt(bs58.decode(address).toString('hex').slice(5, 15), 16))
);
}
}, [address, style]);
Expand Down
7 changes: 7 additions & 0 deletions src/components/pool/add.less
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,10 @@
position: absolute;
right: 5px;
}

.input-card {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 10px;
}
108 changes: 57 additions & 51 deletions src/components/pool/add.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,57 +122,63 @@ export const AddToLiquidity = () => {
);

return (
<div>
<Popover
trigger="hover"
content={
<div style={{ width: 300 }}>
Liquidity providers earn a fixed percentage fee on all trades
proportional to their share of the pool. Fees are added to the pool,
accrue in real time and can be claimed by withdrawing your
liquidity.
</div>
}
>
<Button type="text">Read more about providing liquidity.</Button>
</Popover>

<CurrencyInput
title="Input"
onInputChange={(val: any) => {
setPoolOperation(PoolOperation.Add);
if (A.amount !== val) {
setLastTypedAccount(A.mintAddress);
}
A.setAmount(val);
}}
amount={A.amount}
mint={A.mintAddress}
onMintChange={(item) => {
A.setMint(item);
}}
/>
<div>+</div>
<CurrencyInput
title="Input"
onInputChange={(val: any) => {
setPoolOperation(PoolOperation.Add);
if (B.amount !== val) {
setLastTypedAccount(B.mintAddress);
<>
<div className="input-card">
<Popover
trigger="hover"
content={
<div style={{ width: 300 }}>
Liquidity providers earn a fixed percentage fee on all trades
proportional to their share of the pool. Fees are added to the
pool, accrue in real time and can be claimed by withdrawing your
liquidity.
</div>
}
B.setAmount(val);
}}
amount={B.amount}
mint={B.mintAddress}
onMintChange={(item) => {
B.setMint(item);
}}
/>
<SupplyOverview
mintAddress={[A.mintAddress, B.mintAddress]}
pool={pool}
/>
<PoolAddress pool={pool} style={{ marginBottom: 10 }} showLabel={true} />
>
<Button type="text">Read more about providing liquidity.</Button>
</Popover>

<CurrencyInput
title="Input"
onInputChange={(val: any) => {
setPoolOperation(PoolOperation.Add);
if (A.amount !== val) {
setLastTypedAccount(A.mintAddress);
}
A.setAmount(val);
}}
amount={A.amount}
mint={A.mintAddress}
onMintChange={(item) => {
A.setMint(item);
}}
/>
<div>+</div>
<CurrencyInput
title="Input"
onInputChange={(val: any) => {
setPoolOperation(PoolOperation.Add);
if (B.amount !== val) {
setLastTypedAccount(B.mintAddress);
}
B.setAmount(val);
}}
amount={B.amount}
mint={B.mintAddress}
onMintChange={(item) => {
B.setMint(item);
}}
/>
<SupplyOverview
mintAddress={[A.mintAddress, B.mintAddress]}
pool={pool}
/>
<PoolAddress
pool={pool}
style={{ marginBottom: 10 }}
showLabel={true}
/>
</div>
{pool && (
<Button
className="add-button"
Expand All @@ -193,6 +199,6 @@ export const AddToLiquidity = () => {
</Button>
)}
{!pool && createPoolButton}
</div>
</>
);
};
9 changes: 1 addition & 8 deletions src/components/pool/supplyOverview.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useEffect, useMemo, useRef } from "react";
import { Card } from "antd";
import { PoolInfo } from "../../models";
import { useEnrichedPools } from "./../../context/market";
import echarts from "echarts";
Expand Down Expand Up @@ -84,11 +83,5 @@ export const SupplyOverview = (props: {
return null;
}

return (
<Card style={{ borderWidth: 0 }}>
<div style={{ display: "flex" }}>
<div ref={chartDiv} style={{ height: 150, width: "100%" }} />
</div>
</Card>
);
return <div ref={chartDiv} style={{ height: 150, width: "100%" }} />;
};
1 change: 0 additions & 1 deletion src/components/trade/trade.less
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,5 @@
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
margin-bottom: 10px;
}
2 changes: 1 addition & 1 deletion src/context/market.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ function createEnrichedPools(
const lpMint = cache.getMint(p.pubkeys.mint);

const name = getPoolName(env, p);
const link = `#/?pair=${name.replace("/", "-")}`;
const link = `#/?pair=${getPoolName(env, p, false).replace("/", "-")}`;

return {
key: p.pubkeys.account.toBase58(),
Expand Down
39 changes: 25 additions & 14 deletions src/utils/currencyPair.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { TokenAccount } from "../models";
import { convert } from "./utils";
import PopularTokens from "../utils/token-list.json";
import { useHistory, useLocation } from "react-router-dom";
import bs58 from 'bs58';

export interface CurrencyContextState {
mintAddress: string;
Expand Down Expand Up @@ -56,20 +57,20 @@ export function CurrencyPairProvider({ children = null as any }) {
// updates browser history on token changes
useEffect(() => {
// set history
const base = PopularTokens[env].find((t) => t.mintAddress === mintAddressA)
?.tokenSymbol;
const quote = PopularTokens[env].find((t) => t.mintAddress === mintAddressB)
?.tokenSymbol;

if (base && quote) {
const base =
PopularTokens[env].find((t) => t.mintAddress === mintAddressA)
?.tokenSymbol || mintAddressA;
const quote =
PopularTokens[env].find((t) => t.mintAddress === mintAddressB)
?.tokenSymbol || mintAddressB;

if (base && quote && location.pathname.indexOf("info") < 0) {
history.push({
pathname: "/",
search: `?pair=${base}-${quote}`,
});
} else {
if (mintAddressA && mintAddressB) {
history.push({
pathname: "/",
search: ``,
});
} else {
Expand All @@ -90,11 +91,15 @@ export function CurrencyPairProvider({ children = null as any }) {
}
setMintAddressA(
PopularTokens[env].find((t) => t.tokenSymbol === defaultBase)
?.mintAddress || ""
?.mintAddress ||
defaultBase ||
""
);
setMintAddressB(
PopularTokens[env].find((t) => t.tokenSymbol === defaultQuote)
?.mintAddress || ""
?.mintAddress ||
defaultQuote ||
""
);
}, [location, location.search, setMintAddressA, setMintAddressB]);

Expand Down Expand Up @@ -188,9 +193,15 @@ export const useCurrencyPairState = () => {
const context = useContext(CurrencyPairContext);
return context as CurrencyPairContextState;
};

const isValidAddress = (address: string) => {
const decoded = bs58.decode(address);
return decoded.length === 32;
};

function getDefaultTokens(env: ENV, search: string) {
let defaultBase;
let defaultQuote;
let defaultBase = "SOL";
let defaultQuote = "USDC";

const nameToToken = (PopularTokens[env] as any[]).reduce((map, item) => {
map.set(item.tokenSymbol, item);
Expand All @@ -204,11 +215,11 @@ function getDefaultTokens(env: ENV, search: string) {
let items = pair.split("-");

if (items.length > 1) {
if (nameToToken.has(items[0])) {
if (nameToToken.has(items[0]) || isValidAddress(items[0])) {
defaultBase = items[0];
}

if (nameToToken.has(items[1])) {
if (nameToToken.has(items[1]) || isValidAddress(items[1])) {
defaultQuote = items[1];
}
}
Expand Down
12 changes: 8 additions & 4 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,17 @@ export function shortenAddress(address: string, chars = 4): string {
return `${address.slice(0, chars)}...${address.slice(-chars)}`;
}

export function getTokenName(env: ENV, mintAddress: string): string {
export function getTokenName(
env: ENV,
mintAddress: string,
shorten = true
): string {
const knownSymbol = AddressToToken.get(env)?.get(mintAddress)?.tokenSymbol;
if (knownSymbol) {
return knownSymbol;
}

return `${mintAddress.substring(0, 5)}...`;
return shorten ? `${mintAddress.substring(0, 5)}...` : mintAddress;
}

export function getTokenIcon(
Expand All @@ -74,9 +78,9 @@ export function getTokenIcon(
return AddressToToken.get(env)?.get(mintAddress)?.icon;
}

export function getPoolName(env: ENV, pool: PoolInfo) {
export function getPoolName(env: ENV, pool: PoolInfo, shorten = true) {
const sorted = pool.pubkeys.holdingMints.map((a) => a.toBase58()).sort();
return sorted.map((item) => getTokenName(env, item)).join("/");
return sorted.map((item) => getTokenName(env, item, shorten)).join("/");
}

export function isKnownMint(env: ENV, mintAddress: string) {
Expand Down
Loading

0 comments on commit 46d723a

Please sign in to comment.