Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Axelar config and handle mobile bridge integration wallets #917

Merged
merged 11 commits into from
Oct 22, 2022
4 changes: 0 additions & 4 deletions packages/web/config/ibc-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ export const IBCAssetInfos: (IBCAsset & {
wallets: ["metamask" as const, "walletconnect" as const],
method: "deposit-address" as const,
sourceChains: [AxelarSourceChainConfigs.usdc.ethereum],
tokenMinDenom: IS_TESTNET ? "uausdc" : "uusdc", // test: "uausdc"
transferFeeMinAmount: IS_TESTNET ? "150000" : "10500000", // From https://docs.axelar.dev/resources/mainnet#cross-chain-relayer-gas-fee
},
},
{
Expand All @@ -56,8 +54,6 @@ export const IBCAssetInfos: (IBCAsset & {
wallets: ["metamask" as const, "walletconnect" as const],
method: "deposit-address" as const,
sourceChains: [AxelarSourceChainConfigs.weth.ethereum],
tokenMinDenom: IS_TESTNET ? "weth-wei" : "weth-wei",
transferFeeMinAmount: IS_TESTNET ? "60000000000000" : "6300000000000000",
},
},
{
Expand Down
1 change: 1 addition & 0 deletions packages/web/hooks/ui-config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from "./use-fake-fee-config";
export * from "./use-remove-liquidity-config";
export * from "./use-slippage-config";
export * from "./use-trade-token-in-config";
export * from "./use-transfer-config";
35 changes: 35 additions & 0 deletions packages/web/hooks/ui-config/use-transfer-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useState, useEffect } from "react";
import { AccountSetBase } from "@keplr-wallet/stores";
import {
ObservableAssets,
ObservableTransferUIConfig,
} from "../../stores/assets";
import { makeLocalStorageKVStore } from "../../stores/kv-store";
import { useWindowSize } from "../window";

export function useTransferConfig(
assetsStore: ObservableAssets,
account: AccountSetBase
) {
const { isMobile } = useWindowSize();

const [transferConfig, setTransferConfig] =
useState<ObservableTransferUIConfig | null>(null);
const [transferKvStore] = useState(() =>
makeLocalStorageKVStore("transfer-ui-config")
);
useEffect(
() =>
setTransferConfig(
new ObservableTransferUIConfig(
assetsStore,
account,
transferKvStore,
isMobile
)
),
[assetsStore, account, isMobile]
);

return transferConfig;
}
6 changes: 3 additions & 3 deletions packages/web/integrations/axelar/hooks/use-deposit-address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export function useDepositAddress(
sourceChain: string,
destChain: string,
address: string | undefined,
tokenMinDenom: string,
coinMinimalDenom: string,
generateOnMount = true,
environment = Environment.MAINNET
): {
Expand All @@ -20,7 +20,7 @@ export function useDepositAddress(
if (address && depositAddress === null) {
setIsLoading(true);
new AxelarAssetTransfer({ environment })
.getDepositAddress(sourceChain, destChain, address, tokenMinDenom)
.getDepositAddress(sourceChain, destChain, address, coinMinimalDenom)
.then((generatedAddress) => {
setDepositAddress(generatedAddress);
})
Expand All @@ -36,7 +36,7 @@ export function useDepositAddress(
address,
sourceChain,
destChain,
tokenMinDenom,
coinMinimalDenom,
setIsLoading,
]);

Expand Down
7 changes: 7 additions & 0 deletions packages/web/integrations/axelar/source-chain-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,37 @@ export const SourceChainConfigs: {
? "0x526f0A95EDC3DF4CBDB7bb37d4F7Ed451dB8e369"
: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // test: 'aUSDC' on metamask/etherscan
logoUrl: "/networks/ethereum.svg",
transferFeeMinAmount: IS_TESTNET ? "150000" : "10500000", // From https://docs.axelar.dev/resources/mainnet#cross-chain-relayer-gas-fee
},
bnbChain: {
id: "Binance" as const,
erc20ContractAddress: "0x4268B8F0B87b6Eae5d897996E6b845ddbD99Adf3",
logoUrl: "/networks/binance.svg",
transferFeeMinAmount: IS_TESTNET ? "150000" : "1500000",
},
avalanche: {
id: "Avalanche" as const,
erc20ContractAddress: "0xfaB550568C688d5D8A52C7d794cb93Edc26eC0eC",
logoUrl: "/networks/avalanche.svg",
transferFeeMinAmount: IS_TESTNET ? "150000" : "1500000",
},
polygon: {
id: "Polygon" as const,
erc20ContractAddress: "0x750e4C4984a9e0f12978eA6742Bc1c5D248f40ed",
logoUrl: "/networks/polygon.svg",
transferFeeMinAmount: IS_TESTNET ? "150000" : "1500000",
},
fantom: {
id: "Fantom" as const,
erc20ContractAddress: "0x1B6382DBDEa11d97f24495C9A90b7c88469134a4",
logoUrl: "/networks/fantom.svg",
transferFeeMinAmount: IS_TESTNET ? "150000" : "1500000",
},
moonbeam: {
id: "Moonbeam" as const,
erc20ContractAddress: "0xCa01a1D0993565291051daFF390892518ACfAD3A",
logoUrl: "/networks/moonbeam.svg",
transferFeeMinAmount: IS_TESTNET ? "150000" : "1500000",
},
},
weth: {
Expand All @@ -53,6 +59,7 @@ export const SourceChainConfigs: {
? "0xc778417E063141139Fce010982780140Aa0cD5Ab"
: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
logoUrl: "/networks/ethereum.svg",
transferFeeMinAmount: IS_TESTNET ? "60000000000000" : "6300000000000000",
},
},
};
14 changes: 7 additions & 7 deletions packages/web/integrations/axelar/transfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ const AxelarTransfer: FunctionComponent<
selectedSourceChainKey,
onRequestClose,
onRequestSwitchWallet,
tokenMinDenom,
transferFeeMinAmount,
sourceChains,
isTestNet = process.env.NEXT_PUBLIC_IS_TESTNET === "true",
connectCosmosWalletButtonOverride,
Expand Down Expand Up @@ -98,9 +96,11 @@ const AxelarTransfer: FunctionComponent<
EthClientChainIds_AxelarChainIdsMap[selectedSourceChainKey] ??
selectedSourceChainKey;

const erc20ContractAddress = sourceChains.find(
({ id }) => id === selectedSourceChainKey
)?.erc20ContractAddress;
const sourceChainConfig = sourceChains.find( ({ id }) => id === selectedSourceChainKey );

const erc20ContractAddress = sourceChainConfig?.erc20ContractAddress;
const transferFeeMinAmount = sourceChainConfig?.transferFeeMinAmount ?? "0";

const axelarChainId =
chainStore.getChainFromCurrency(originCurrency.coinDenom)?.chainId ||
"axelar-dojo-1";
Expand Down Expand Up @@ -222,15 +222,15 @@ const AxelarTransfer: FunctionComponent<
sourceChain,
destChain,
isWithdraw || correctChainSelected ? address : undefined,
tokenMinDenom,
originCurrency.coinMinimalDenom,
undefined,
isTestNet ? Environment.TESTNET : Environment.MAINNET
);

// notify user they are withdrawing into a different account then they last deposited to
const [lastDepositAccountAddress, setLastDepositAccountAddress] =
useLocalStorageState<string | null>(
`axelar-last-deposit-addr-${tokenMinDenom}`,
`axelar-last-deposit-addr-${originCurrency.coinMinimalDenom}`,
null
);
const warnOfDifferentDepositAddress =
Expand Down
13 changes: 7 additions & 6 deletions packages/web/integrations/axelar/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ export interface AxelarBridgeConfig {
/** Ex: `uusdc`. NOTE: Will get currency info from `originCurrency` on the IBC balance (from registrar).
* See: https://docs.axelar.dev/resources/mainnet#assets
*/
tokenMinDenom: string;
/** Amount of Axelar transfer fee in `originCurrency`.
* TODO: use `useTransferFeeQuery` should fees become dynamic and once APIs become production ready.
* See calculator tool on Axelar docs to get current fee constants: https://docs.axelar.dev/resources/mainnet#cross-chain-relayer-gas-fee.
*/
transferFeeMinAmount: string;
}

/** See: https://docs.axelar.dev/dev/build/chain-names/mainnet
Expand Down Expand Up @@ -61,4 +55,11 @@ export type SourceChainConfig = {
};

logoUrl: string;

/** Amount of Axelar transfer fee in `originCurrency`.
* TODO: use `useTransferFeeQuery` should fees become dynamic and once APIs become production ready.
* See calculator tool on Axelar docs to get current fee constants: https://docs.axelar.dev/resources/mainnet#cross-chain-relayer-gas-fee.
*/
transferFeeMinAmount: string;

};
1 change: 1 addition & 0 deletions packages/web/integrations/ethereum/metamask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const IS_TESTNET = process.env.NEXT_PUBLIC_IS_TESTNET === "true";

export class ObservableMetamask implements EthWallet {
readonly key: WalletKey = "metamask";
readonly mobileEnabled = false;

readonly displayInfo: WalletDisplay = {
iconUrl: "/icons/metamask-fox.svg",
Expand Down
3 changes: 2 additions & 1 deletion packages/web/integrations/ethereum/walletconnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const CONNECTED_ACCOUNT_KEY = "wc-eth-connected-account";
const CONNECTED_ACCOUNT_CHAINID = "wc-eth-connected-chainId";

export class ObservableWalletConnect implements EthWallet {
key: WalletKey = "walletconnect";
readonly key: WalletKey = "walletconnect";
readonly mobileEnabled = false;

displayInfo: WalletDisplay = {
iconUrl: "/icons/walletconnect.svg",
Expand Down
3 changes: 3 additions & 0 deletions packages/web/integrations/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ export interface Wallet<
readonly key: WalletKey;
readonly displayInfo: WalletDisplay;

/** Works on mobile browsers. */
readonly mobileEnabled: boolean;

readonly accountAddress?: string;
/** Human readable chain, falls back to hex ID (`0x...`) if unknown. */
readonly chainId?: string;
Expand Down
43 changes: 30 additions & 13 deletions packages/web/modals/connect-non-ibc-wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ export const ConnectNonIbcWallet: FunctionComponent<
onSelectWallet: (key: string) => void;
}
> = observer((props) => {
const { initiallySelectedWalletId, isWithdraw, wallets, onSelectWallet } =
props;

const [selectedWalletKey, setSelectedWalletId] = useState<string | null>(
props.initiallySelectedWalletId ?? null
initiallySelectedWalletId ?? null
);

const selectedWallet = props.wallets.find((w) => w.key === selectedWalletKey);
const selectedWallet = wallets.find((w) => w.key === selectedWalletKey);
const canOnboardSelectedWallet =
selectedWallet && !selectedWallet.isInstalled && selectedWallet.onboard;

Expand All @@ -28,12 +31,13 @@ export const ConnectNonIbcWallet: FunctionComponent<
className: "h-14 md:w-full w-96 mt-3 mx-auto !px-1",
size: "lg",
disabled:
props.initiallySelectedWalletId === undefined && !selectedWalletKey,
(initiallySelectedWalletId === undefined && !selectedWalletKey) ||
wallets.length === 0,
onClick: () => {
if (canOnboardSelectedWallet) {
selectedWallet!.onboard?.();
} else if (selectedWalletKey) {
props.onSelectWallet(selectedWalletKey);
onSelectWallet(selectedWalletKey);
} else {
console.error(
"Wallet selection invalid state: selectedWalletKey undefined"
Expand All @@ -44,6 +48,8 @@ export const ConnectNonIbcWallet: FunctionComponent<
<h6 className="md:text-base text-lg">
{canOnboardSelectedWallet
? `Install ${selectedWallet.displayInfo.displayName}`
: wallets.length === 0
? "None available"
: "Next"}
</h6>
),
Expand All @@ -56,19 +62,30 @@ export const ConnectNonIbcWallet: FunctionComponent<
<ModalBase
{...props}
isOpen={props.isOpen && showModalBase}
title={props.isWithdraw ? "Withdraw to" : "Deposit from"}
title={isWithdraw ? "Withdraw to" : "Deposit from"}
>
<div className="grid grid-cols-3 md:grid-cols-2 gap-4 m-4">
{props.wallets.map((wallet, i) => (
{props.wallets.length === 0 ? (
<WalletCard
key={i}
id={wallet.key}
{...wallet.displayInfo}
isConnected={wallet.isConnected}
isSelected={wallet.key === selectedWalletKey}
onClick={() => setSelectedWalletId(wallet.key)}
className="opacity-30"
id="placeholder"
displayName="None"
iconUrl="/icons/error-x.svg"
/>
))}
) : (
<>
{wallets.map((wallet, i) => (
<WalletCard
key={i}
id={wallet.key}
{...wallet.displayInfo}
isConnected={wallet.isConnected}
isSelected={wallet.key === selectedWalletKey}
onClick={() => setSelectedWalletId(wallet.key)}
/>
))}
</>
)}
</div>
{accountActionButton}
</ModalBase>
Expand Down
Loading