From 54487439f0bcd94c98fa56aeddadef89dfb19c16 Mon Sep 17 00:00:00 2001 From: Shady Khalifa Date: Mon, 31 Jul 2023 15:17:30 +0300 Subject: [PATCH 1/9] Add Tangle EVM Testnet --- libs/dapp-types/src/ChainId.ts | 5 +++++ libs/dapp-types/src/EVMChainId.ts | 1 + 2 files changed, 6 insertions(+) diff --git a/libs/dapp-types/src/ChainId.ts b/libs/dapp-types/src/ChainId.ts index fda3c33103..2a7b11d4d3 100644 --- a/libs/dapp-types/src/ChainId.ts +++ b/libs/dapp-types/src/ChainId.ts @@ -116,6 +116,11 @@ export enum PresetTypedChainId { ChainType.EVM, EVMChainId.DemeterLocalnet ), + + TangleTestnet = calculateTypedChainId( + ChainType.EVM, + EVMChainId.TangleTestnet + ), } export { EVMChainId, SubstrateChainId }; diff --git a/libs/dapp-types/src/EVMChainId.ts b/libs/dapp-types/src/EVMChainId.ts index 2b4e2fe48b..e81da06fd6 100644 --- a/libs/dapp-types/src/EVMChainId.ts +++ b/libs/dapp-types/src/EVMChainId.ts @@ -16,6 +16,7 @@ export enum EVMChainId { MoonbaseAlpha = 1287, AvalancheFuji = 43113, ScrollAlpha = 534353, + TangleTestnet = 4006, /** Self hosted EVM */ AthenaOrbit = 3884533461, From e3ed0f1ec327b958b4dc0c59668108aca3afbf54 Mon Sep 17 00:00:00 2001 From: Shady Khalifa Date: Mon, 31 Jul 2023 15:21:37 +0300 Subject: [PATCH 2/9] Update Anchor Addressess --- libs/dapp-config/src/anchors/anchor-config.ts | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/libs/dapp-config/src/anchors/anchor-config.ts b/libs/dapp-config/src/anchors/anchor-config.ts index 31585d779c..3e1ddd21a7 100644 --- a/libs/dapp-config/src/anchors/anchor-config.ts +++ b/libs/dapp-config/src/anchors/anchor-config.ts @@ -7,19 +7,19 @@ import { LOCALNET_CHAIN_IDS } from '../chains'; const localAnchorRecord = process.env.BRIDGE_DAPP_LOCAL_ORBIT_ANCHOR_ADDRESS ? LOCALNET_CHAIN_IDS.reduce>>( - (acc, chainId) => { - const typedChainId = calculateTypedChainId(ChainType.EVM, chainId); - const anchorAddress: string = process.env - .BRIDGE_DAPP_LOCAL_ORBIT_ANCHOR_ADDRESS as string; + (acc, chainId) => { + const typedChainId = calculateTypedChainId(ChainType.EVM, chainId); + const anchorAddress: string = process.env + .BRIDGE_DAPP_LOCAL_ORBIT_ANCHOR_ADDRESS as string; - acc[typedChainId] = { - [anchorAddress]: 0, - }; + acc[typedChainId] = { + [anchorAddress]: 0, + }; - return acc; - }, - {} - ) + return acc; + }, + {} + ) : {}; // 0x38e7aa90c77f86747fab355eecaa0c2e4c3a463d - webbAlpha - mocked backend @@ -52,13 +52,16 @@ export const anchorDeploymentBlock: Record> = { }, [PresetTypedChainId.HermesOrbit]: { - '0xDa68464c391Da8ff60b40273F2Ef0a9971694F99': 25, + '0x19E60bbC8b19CBBA2936BEC4B5CE6542013DF02c': 70, }, [PresetTypedChainId.AthenaOrbit]: { - '0xDa68464c391Da8ff60b40273F2Ef0a9971694F99': 25, + '0x19E60bbC8b19CBBA2936BEC4B5CE6542013DF02c': 70, }, [PresetTypedChainId.DemeterOrbit]: { - '0xDa68464c391Da8ff60b40273F2Ef0a9971694F99': 25, + '0x19E60bbC8b19CBBA2936BEC4B5CE6542013DF02c': 70, + }, + [PresetTypedChainId.TangleTestnet]: { + '0x19E60bbC8b19CBBA2936BEC4B5CE6542013DF02c': 158_874, }, ...localAnchorRecord, From b9acbb994b3771d19c1b1b402b76bd16585e0404 Mon Sep 17 00:00:00 2001 From: Shady Khalifa Date: Mon, 31 Jul 2023 15:21:53 +0300 Subject: [PATCH 3/9] add webbtTNT to the faucet --- apps/faucet/src/config/tokens.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/faucet/src/config/tokens.ts b/apps/faucet/src/config/tokens.ts index 9784e26014..e39c11c5e3 100644 --- a/apps/faucet/src/config/tokens.ts +++ b/apps/faucet/src/config/tokens.ts @@ -7,12 +7,15 @@ type TokenConfigType = Record; const tokens: Record = { [PresetTypedChainId.AthenaOrbit]: { webbWETH: '0x915EbFAd9c4Af2F420782a5F03BD544f9a1FF1d1', + webbtTNT: '0x6aBC6e8E4E4a1fcB43341CeC49cBd5FA3b494520', }, [PresetTypedChainId.HermesOrbit]: { webbWETH: '0x915EbFAd9c4Af2F420782a5F03BD544f9a1FF1d1', + webbtTNT: '0x6aBC6e8E4E4a1fcB43341CeC49cBd5FA3b494520', }, [PresetTypedChainId.DemeterOrbit]: { webbWETH: '0x915EbFAd9c4Af2F420782a5F03BD544f9a1FF1d1', + webbtTNT: '0x6aBC6e8E4E4a1fcB43341CeC49cBd5FA3b494520', }, }; From e7a58b5bb002c002cd7a4e7d302f23408462e63b Mon Sep 17 00:00:00 2001 From: Shady Khalifa Date: Mon, 31 Jul 2023 15:22:16 +0300 Subject: [PATCH 4/9] Run formatting --- libs/dapp-config/src/anchors/anchor-config.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/libs/dapp-config/src/anchors/anchor-config.ts b/libs/dapp-config/src/anchors/anchor-config.ts index 3e1ddd21a7..8b7dc4936b 100644 --- a/libs/dapp-config/src/anchors/anchor-config.ts +++ b/libs/dapp-config/src/anchors/anchor-config.ts @@ -7,19 +7,19 @@ import { LOCALNET_CHAIN_IDS } from '../chains'; const localAnchorRecord = process.env.BRIDGE_DAPP_LOCAL_ORBIT_ANCHOR_ADDRESS ? LOCALNET_CHAIN_IDS.reduce>>( - (acc, chainId) => { - const typedChainId = calculateTypedChainId(ChainType.EVM, chainId); - const anchorAddress: string = process.env - .BRIDGE_DAPP_LOCAL_ORBIT_ANCHOR_ADDRESS as string; + (acc, chainId) => { + const typedChainId = calculateTypedChainId(ChainType.EVM, chainId); + const anchorAddress: string = process.env + .BRIDGE_DAPP_LOCAL_ORBIT_ANCHOR_ADDRESS as string; - acc[typedChainId] = { - [anchorAddress]: 0, - }; + acc[typedChainId] = { + [anchorAddress]: 0, + }; - return acc; - }, - {} - ) + return acc; + }, + {} + ) : {}; // 0x38e7aa90c77f86747fab355eecaa0c2e4c3a463d - webbAlpha - mocked backend From 64bbc232f1d99d77b3ddc5d22671cb5a604e8504 Mon Sep 17 00:00:00 2001 From: Shady Khalifa Date: Mon, 31 Jul 2023 15:38:59 +0300 Subject: [PATCH 5/9] Add Tangle EVM to the list of chains --- libs/dapp-config/src/chains/evm/index.tsx | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/libs/dapp-config/src/chains/evm/index.tsx b/libs/dapp-config/src/chains/evm/index.tsx index 196328e619..ed4e146f69 100644 --- a/libs/dapp-config/src/chains/evm/index.tsx +++ b/libs/dapp-config/src/chains/evm/index.tsx @@ -221,6 +221,37 @@ export const chainsConfig: Record = { }, }, + [PresetTypedChainId.TangleTestnet]: { + chainType: ChainType.EVM, + id: EVMChainId.TangleTestnet, + name: 'Tangle Testnet', + network: 'Tangle', + group: 'webb-dev', + tag: 'test', + nativeCurrency: { + name: 'Test Tangle Network Token', + symbol: 'tTNT', + decimals: 18, + }, + blockExplorers: { + default: { + name: 'Tangle Testnet Explorer', + url: 'https://tangle-testnet-explorer.webb.tools', + }, + }, + rpcUrls: { + default: { + http: ['https://tangle-standalone-archive.webb.tools'], + }, + public: { + http: ['https://tangle-standalone-archive.webb.tools'], + }, + }, + env: ['development', 'test'], + contracts: { + multicall3: undefined, + }, + }, // Localnet [PresetTypedChainId.HermesLocalnet]: { chainType: ChainType.EVM, From d309f30461b7cae3784b3f4305585df0599ac812 Mon Sep 17 00:00:00 2001 From: Shady Khalifa Date: Mon, 31 Jul 2023 15:52:13 +0300 Subject: [PATCH 6/9] Remove old webbETH token and add tangle evm --- apps/faucet/src/config/tokens.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/faucet/src/config/tokens.ts b/apps/faucet/src/config/tokens.ts index e39c11c5e3..d269586b2f 100644 --- a/apps/faucet/src/config/tokens.ts +++ b/apps/faucet/src/config/tokens.ts @@ -6,15 +6,15 @@ type TokenConfigType = Record; // TODO: We should fetch the token info (e.g. symbol, decimals, name, ...) from the chain const tokens: Record = { [PresetTypedChainId.AthenaOrbit]: { - webbWETH: '0x915EbFAd9c4Af2F420782a5F03BD544f9a1FF1d1', webbtTNT: '0x6aBC6e8E4E4a1fcB43341CeC49cBd5FA3b494520', }, [PresetTypedChainId.HermesOrbit]: { - webbWETH: '0x915EbFAd9c4Af2F420782a5F03BD544f9a1FF1d1', webbtTNT: '0x6aBC6e8E4E4a1fcB43341CeC49cBd5FA3b494520', }, [PresetTypedChainId.DemeterOrbit]: { - webbWETH: '0x915EbFAd9c4Af2F420782a5F03BD544f9a1FF1d1', + webbtTNT: '0x6aBC6e8E4E4a1fcB43341CeC49cBd5FA3b494520', + }, + [PresetTypedChainId.TangleTestnet]: { webbtTNT: '0x6aBC6e8E4E4a1fcB43341CeC49cBd5FA3b494520', }, }; From f85c45f88f4701743697d86ebdd352f1599cb437 Mon Sep 17 00:00:00 2001 From: Shady Khalifa Date: Mon, 31 Jul 2023 15:54:43 +0300 Subject: [PATCH 7/9] touch something in the dApp to trigger a deployment --- apps/bridge-dapp/src/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bridge-dapp/src/index.tsx b/apps/bridge-dapp/src/index.tsx index 99693afc6a..4cf5be1420 100644 --- a/apps/bridge-dapp/src/index.tsx +++ b/apps/bridge-dapp/src/index.tsx @@ -1,7 +1,7 @@ import './styles.css'; import '@webb-tools/webb-ui-components/tailwind.css'; import * as Sentry from '@sentry/react'; -import { BrowserTracing } from '@sentry/tracing'; +import { BrowserTracing } from '@sentry/browser'; import { createRoot } from 'react-dom/client'; import App from './App'; From 2434ae139a4b615ecb4194adb5c79a476f8cc264 Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Tue, 1 Aug 2023 01:19:04 +0700 Subject: [PATCH 8/9] feat: add native token for the faucet --- apps/faucet/src/config/tokens.ts | 5 +++++ .../faucet/src/containers/MintButtonContainer.tsx | 15 ++++++++++++++- apps/faucet/src/errors/FaucetError.ts | 2 ++ apps/faucet/src/errors/FaucetErrorCode.ts | 5 +++++ apps/faucet/src/errors/FaucetErrorPayload.ts | 5 +++++ apps/faucet/src/types/index.ts | 3 ++- 6 files changed, 33 insertions(+), 2 deletions(-) diff --git a/apps/faucet/src/config/tokens.ts b/apps/faucet/src/config/tokens.ts index d269586b2f..4d5cada502 100644 --- a/apps/faucet/src/config/tokens.ts +++ b/apps/faucet/src/config/tokens.ts @@ -1,4 +1,5 @@ import { PresetTypedChainId } from '@webb-tools/dapp-types/ChainId'; +import { zeroAddress } from 'viem'; // Record of token symbol to token address type TokenConfigType = Record; @@ -6,15 +7,19 @@ type TokenConfigType = Record; // TODO: We should fetch the token info (e.g. symbol, decimals, name, ...) from the chain const tokens: Record = { [PresetTypedChainId.AthenaOrbit]: { + ETH: zeroAddress, webbtTNT: '0x6aBC6e8E4E4a1fcB43341CeC49cBd5FA3b494520', }, [PresetTypedChainId.HermesOrbit]: { + ETH: zeroAddress, webbtTNT: '0x6aBC6e8E4E4a1fcB43341CeC49cBd5FA3b494520', }, [PresetTypedChainId.DemeterOrbit]: { + ETH: zeroAddress, webbtTNT: '0x6aBC6e8E4E4a1fcB43341CeC49cBd5FA3b494520', }, [PresetTypedChainId.TangleTestnet]: { + tTNT: zeroAddress, webbtTNT: '0x6aBC6e8E4E4a1fcB43341CeC49cBd5FA3b494520', }, }; diff --git a/apps/faucet/src/containers/MintButtonContainer.tsx b/apps/faucet/src/containers/MintButtonContainer.tsx index 47510d9781..9dd9389936 100644 --- a/apps/faucet/src/containers/MintButtonContainer.tsx +++ b/apps/faucet/src/containers/MintButtonContainer.tsx @@ -1,4 +1,5 @@ import { LoggerService } from '@webb-tools/browser-utils'; +import { ZERO_BIG_INT } from '@webb-tools/dapp-config/constants'; import isValidAddress from '@webb-tools/dapp-types/utils/isValidAddress'; import { Button } from '@webb-tools/webb-ui-components'; import { err, ok, Result } from 'neverthrow'; @@ -26,10 +27,19 @@ const logger = LoggerService.get('MintButtonContainer'); const mintTokens = async ( accessToken: string, - { chain: typedChainId, recepient, recepientAddressType }: InputValuesType, + { + chain: typedChainId, + recepient, + recepientAddressType, + contractAddress, + }: InputValuesType, config: FaucetContextType['config'], abortSignal?: AbortSignal ): Promise>> => { + if (!contractAddress) { + return err(FaucetError.from(FaucetErrorCode.MISSING_CONTRACT_ADDRESS)); + } + if (!typedChainId) { return err(FaucetError.from(FaucetErrorCode.INVALID_SELECTED_CHAIN)); } @@ -49,8 +59,11 @@ const mintTokens = async ( 'Content-Type': 'application/x-www-form-urlencoded', } as const satisfies HeadersInit; + const onlyNativeToken = BigInt(contractAddress) === ZERO_BIG_INT; + const body = { faucet: { + onlyNativeToken, typedChainId: { [chain.type]: chain.chainId, }, diff --git a/apps/faucet/src/errors/FaucetError.ts b/apps/faucet/src/errors/FaucetError.ts index 9d2d8227c4..825c9c0f57 100644 --- a/apps/faucet/src/errors/FaucetError.ts +++ b/apps/faucet/src/errors/FaucetError.ts @@ -8,6 +8,8 @@ const errorMessages: { [FaucetErrorCode.INVALID_STORE_KEY]: 'Invalid store key', [FaucetErrorCode.TWITTER_LOGIN_FAILED]: 'Twitter login failed', [FaucetErrorCode.INVALID_RESPONSE]: 'Invalid response', + [FaucetErrorCode.MISSING_CONTRACT_ADDRESS]: + 'Missing contract address in the operation', [FaucetErrorCode.INVALID_REQUEST_BODY]: 'Invalid request body', [FaucetErrorCode.REFRESH_TOKENS_FAILED]: 'Refresh tokens failed', [FaucetErrorCode.TWITTER_LOGIN_DENIED]: 'Twitter login denied', diff --git a/apps/faucet/src/errors/FaucetErrorCode.ts b/apps/faucet/src/errors/FaucetErrorCode.ts index 2f0edf118f..d0fa6b70ff 100644 --- a/apps/faucet/src/errors/FaucetErrorCode.ts +++ b/apps/faucet/src/errors/FaucetErrorCode.ts @@ -24,6 +24,11 @@ enum FaucetErrorCode { */ INVALID_REQUEST_BODY, + /** + * Missing contract address in the operation + */ + MISSING_CONTRACT_ADDRESS, + /** * Inavlid selected chain */ diff --git a/apps/faucet/src/errors/FaucetErrorPayload.ts b/apps/faucet/src/errors/FaucetErrorPayload.ts index 39b18f6be7..4cac465cd3 100644 --- a/apps/faucet/src/errors/FaucetErrorPayload.ts +++ b/apps/faucet/src/errors/FaucetErrorPayload.ts @@ -67,6 +67,11 @@ type ErrorPayload = { context: string; }; + /** + * No payload for this error + */ + [FaucetErrorCode.MISSING_CONTRACT_ADDRESS]: undefined; + /** * Extra info for the mint tokens failed error */ diff --git a/apps/faucet/src/types/index.ts b/apps/faucet/src/types/index.ts index 068dd7839f..9fcf1e80a6 100644 --- a/apps/faucet/src/types/index.ts +++ b/apps/faucet/src/types/index.ts @@ -188,7 +188,8 @@ export type MintTokenErrorCodes = | FaucetErrorCode.INVALID_SELECTED_CHAIN | FaucetErrorCode.MINT_TOKENS_FAILED | FaucetErrorCode.JSON_PARSE_ERROR - | FaucetErrorCode.TOO_MANY_CLAIM_REQUESTS; + | FaucetErrorCode.TOO_MANY_CLAIM_REQUESTS + | FaucetErrorCode.MISSING_CONTRACT_ADDRESS; /** * The mint token result type From c53f786236210c9df3c95764fa3871917b7e752e Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Tue, 1 Aug 2023 01:42:03 +0700 Subject: [PATCH 9/9] chore: update the UI when user select native token --- .env.example | 1 + apps/faucet/src/components/TokenDropdown.tsx | 14 ++++++++++++-- apps/faucet/src/config/shared.ts | 5 +++++ apps/faucet/src/containers/InputsContainer.tsx | 15 +++++++++++++-- apps/faucet/src/provider/index.tsx | 6 +++--- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/.env.example b/.env.example index 55012b5a6e..cd3ddf8e3e 100644 --- a/.env.example +++ b/.env.example @@ -14,6 +14,7 @@ NOTION_API_KEY="" # Faucet DApp NEXT_PUBLIC_AMOUNT="20" +NEXT_PUBLIC_NATIVE_AMOUNT="0.5" NEXT_PUBLIC_FAUCET_BACKEND_URL="http://127.0.0.1:8000" NEXT_PUBLIC_TWITTER_CLIENT_ID="" TWITTER_CLIENT_SECRET="" diff --git a/apps/faucet/src/components/TokenDropdown.tsx b/apps/faucet/src/components/TokenDropdown.tsx index ec81d17493..b5005c2987 100644 --- a/apps/faucet/src/components/TokenDropdown.tsx +++ b/apps/faucet/src/components/TokenDropdown.tsx @@ -1,4 +1,5 @@ import { RadioGroup, RadioItem } from '@radix-ui/react-dropdown-menu'; +import { ZERO_BIG_INT } from '@webb-tools/dapp-config/constants'; import { TokenIcon } from '@webb-tools/icons'; import { Dropdown, @@ -12,10 +13,11 @@ import { useObservableState } from 'observable-hooks'; import React, { useCallback, useEffect, useMemo } from 'react'; import { map } from 'rxjs'; +import constants from '../config/shared'; import { useFaucetContext } from '../provider'; const TokenDropdown = () => { - const { config, inputValues$ } = useFaucetContext(); + const { config, inputValues$, amount$ } = useFaucetContext(); const token = useObservableState( inputValues$.pipe(map((inputValues) => inputValues.token)) @@ -24,13 +26,21 @@ const TokenDropdown = () => { const setToken = useCallback( (token: string | undefined, contractAddress?: string) => { const currentVal = inputValues$.getValue(); + + // If the contract address is 0, then we are using the native token + if (contractAddress && BigInt(contractAddress) === ZERO_BIG_INT) { + amount$.next(constants.nativeAmount); + } else if (contractAddress) { + amount$.next(constants.amount); + } + inputValues$.next({ ...currentVal, contractAddress, token, }); }, - [inputValues$] + [amount$, inputValues$] ); const selectedChain = useObservableState( diff --git a/apps/faucet/src/config/shared.ts b/apps/faucet/src/config/shared.ts index b8561d65b1..e7058afe20 100644 --- a/apps/faucet/src/config/shared.ts +++ b/apps/faucet/src/config/shared.ts @@ -11,6 +11,10 @@ const amount = process.env.NEXT_PUBLIC_AMOUNT ? +process.env.NEXT_PUBLIC_AMOUNT : 20; +const nativeAmount = process.env.NEXT_PUBLIC_NATIVE_AMOUNT + ? +process.env.NEXT_PUBLIC_NATIVE_AMOUNT + : 0.5; + const twitterClientId = process.env.NEXT_PUBLIC_TWITTER_CLIENT_ID || ''; if (!twitterClientId) { throw FaucetError.from(FaucetErrorCode.MISSING_ENV_VAR, { @@ -21,6 +25,7 @@ if (!twitterClientId) { const config = { amount, faucetBackendUrl, + nativeAmount, twitterClientId, }; diff --git a/apps/faucet/src/containers/InputsContainer.tsx b/apps/faucet/src/containers/InputsContainer.tsx index f4c1413532..f54116f4ce 100644 --- a/apps/faucet/src/containers/InputsContainer.tsx +++ b/apps/faucet/src/containers/InputsContainer.tsx @@ -1,4 +1,5 @@ import { chainsConfig } from '@webb-tools/dapp-config/chains/chain-config'; +import { ZERO_BIG_INT } from '@webb-tools/dapp-config/constants'; import { ExternalLinkLine } from '@webb-tools/icons'; import { Button, @@ -79,10 +80,12 @@ const InputWrapper = ({ }; const AmountChip = () => { - const { amount, inputValues$ } = useFaucetContext(); + const { amount$, inputValues$ } = useFaucetContext(); const [getStore] = useStore(); + const amount = useObservableState(amount$); + const token = useObservableState( inputValues$.pipe(map((inputValues) => inputValues.token)) ); @@ -92,6 +95,14 @@ const AmountChip = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [getStore(StoreKey.twitterHandle)]); + if (Number.isNaN(amount)) { + return ( + + -- + + ); + } + return ( {amount} {token} @@ -117,7 +128,7 @@ const TokenAddressLink = () => { return `${chainsConfig[typedChainId]?.blockExplorers?.default.url}/token/${tokenAddress}`; }, [tokenAddress, typedChainId]); - return tokenAddress ? ( + return tokenAddress && BigInt(tokenAddress) !== ZERO_BIG_INT ? (