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

Connext integration #3

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@
"dependencies": {
"@apollo/client": "^3.3.20",
"@arcxmoney/analytics": "^1.6.0",
"@connext/chain-abstraction": "1.0.2-alpha.11",
"@connext/sdk": "^2.0.2",
"@ethersproject/abi": "^5.7.0",
"@ethersproject/constants": "^5.7.0",
"@ethersproject/contracts": "^5.7.0",
Expand Down Expand Up @@ -125,13 +127,16 @@
"assert": "^2.0.0",
"axios": "^0.21.1",
"axios-cache-adapter": "^2.7.3",
"browserify-zlib": "^0.2.0",
"canvas-confetti": "^1.6.0",
"crypto-browserify": "^3.12.0",
"cryptocurrency-icons": "^0.17.2",
"decimal.js-light": "^2.5.1",
"dotenv": "^16.0.3",
"eth-provider": "^0.12.1",
"ethereumjs-util": "^7.1.3",
"ethers": "^5",
"fs": "^0.0.1-security",
"graphql": "^15.5.0",
"graphql-tag": "^2.12.4",
"https-browserify": "^1.0.0",
Expand All @@ -142,6 +147,7 @@
"md5": "^2.3.0",
"notistack": "^2.0.4",
"os-browserify": "^0.3.0",
"path": "^0.12.7",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-intl": "^6.3.2",
Expand All @@ -160,7 +166,9 @@
"url": "^0.11.0",
"uuid": "^9.0.0",
"wagmi": "^0.12.7",
"web3modal": "^1.9.3"
"web3modal": "^1.9.3",
"zlib": "^1.0.5",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are all of these new dependencies needed?

"zlib-browserify": "^0.0.3"
},
"lint-staged": {
"*.{js,jsx,ts,tsx,css,md}": [
Expand Down
64 changes: 64 additions & 0 deletions src/config/constants/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -724,4 +724,68 @@ export const getGhTokenListLogoUrl = (chainId: number, address: string) =>
// oasis: 42262,

export const UNSUPPORTED_WAGMI_CHAIN = [122, 128, 106, 42262];

export const SUPPORTED_CHAINS_BY_CONNEXT: Record<number, { domainId: string; name: string; network: string }> = {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could extend de NetworkStruct type to add the domainId, and with that you would already have if it is mainnet or a testnet, plus all the names. Furthermore, i would assign keys here as [NETWORKS.optimism.chainId]

1: {
domainId: '6648936',
// Ethereum Mainnet
name: 'Ethereum',
network: 'mainnet',
},
10: {
domainId: '1869640809',
// Optimism
name: 'Optimism',
network: 'mainnet',
},
100: {
domainId: '6778479',
// Gnosis Chain
name: 'Gnosis',
network: 'mainnet',
},
137: {
domainId: '1886350457',
// Polygon
name: 'Polygon',
network: 'mainnet',
},
420: {
domainId: '1735356532',
// Optimism-Goerli
name: 'OptGoerli',
network: 'testnet',
},
42161: {
domainId: '1634886255',
// Arbitrum One
name: 'Arbitrum',
network: 'mainnet',
},
421613: {
domainId: '1734439522',
// Arbitrum-Goerli
name: 'ArbGoerli',
network: 'testnet',
},
5: {
domainId: '1735353714',
// Goerli
name: 'Goerli',
network: 'testnet',
},
56: {
domainId: '6450786',
// BNB Chain
name: 'BNB',
network: 'mainnet',
},
80001: {
domainId: '9991',
// Mumbai
name: 'Mumbai',
network: 'testnet',
},
};

/* eslint-enable */
8 changes: 8 additions & 0 deletions src/home/swap-container/components/step1/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import TokenIcon from 'common/token-icon';
import useSelectedNetwork from 'hooks/useSelectedNetwork';
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import { Button } from '@mui/material';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use our button please from @common/components/button

// import useWalletService from 'hooks/useWalletService';

const StyledGrid = styled(Grid)<{ $show: boolean }>`
Expand Down Expand Up @@ -118,6 +119,7 @@ interface SwapFirstStepProps {
buttonToShow: React.ReactNode;
fromValueUsdPrice: number;
onChangeNetwork: (chainId: number) => void;
handlePolygonDestinantion: () => void;
}

const SwapFirstStep = React.forwardRef<HTMLDivElement, SwapFirstStepProps>((props, ref) => {
Expand All @@ -139,6 +141,7 @@ const SwapFirstStep = React.forwardRef<HTMLDivElement, SwapFirstStepProps>((prop
show,
fromValueUsdPrice,
onChangeNetwork,
handlePolygonDestinantion,
} = props;

// const walletService = useWalletService();
Expand Down Expand Up @@ -244,6 +247,11 @@ const SwapFirstStep = React.forwardRef<HTMLDivElement, SwapFirstStepProps>((prop
<TokenButton token={to} onClick={() => startSelectingCoin(to || emptyTokenWithAddress('to'))} />
</StyledTokenContainer>
</StyledTokensContainer>
<div style={{ width: '100%', display: 'flex', justifyContent: 'end' }}>
<Button onClick={() => handlePolygonDestinantion()} style={{ display: 'flex', marginTop: '10px' }}>
Select Polygon
</Button>
</div>
</StyledContentContainer>
</Grid>
<Grid item xs={12}>
Expand Down
15 changes: 13 additions & 2 deletions src/home/swap-container/components/swap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ interface SwapProps {
setFromYield: (newYield?: null | YieldOption) => void;
setToYield: (newYield?: null | YieldOption) => void;
handleChangeNetwork: (newChainId: number) => void;
handlePolygonDestinantion: () => void;
isPolygonDestnantion: boolean;
}

const Swap = ({
Expand All @@ -144,6 +146,8 @@ const Swap = ({
setFromYield,
setToYield,
handleChangeNetwork,
isPolygonDestnantion,
handlePolygonDestinantion,
}: SwapProps) => {
const web3Service = useWeb3Service();
const containerRef = React.useRef(null);
Expand Down Expand Up @@ -363,15 +367,21 @@ const Swap = ({
),
});
trackEvent('DCA - Create position submitting');
const result = await positionService.deposit(
// change it to xCall here.
// eslint-disable-next-line no-console
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please don't disable these lint-rules, its fine if it fails the lint action since later you can remove them

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted ✅

console.log('Doing xcall', { from, to, fromValue, frequencyType, frequencyValue, fromYield, toYield });
const result = await positionService.xCallDeposit(
from,
to,
fromValue,
frequencyType,
frequencyValue,
shouldEnableYield ? fromYield?.tokenAddress : undefined,
shouldEnableYield ? toYield?.tokenAddress : undefined
shouldEnableYield ? toYield?.tokenAddress : undefined,
isPolygonDestnantion
);
// eslint-disable-next-line no-console
console.log(result, 'result from Xcall from button');
trackEvent('DCA - Create position submitted');
const hubAddress = await contractService.getHUBAddress();
const companionAddress = await contractService.getHUBCompanionAddress();
Expand Down Expand Up @@ -1116,6 +1126,7 @@ const Swap = ({
show={showFirstStep}
fromValueUsdPrice={fromValueUsdPrice}
onChangeNetwork={handleChangeNetwork}
handlePolygonDestinantion={handlePolygonDestinantion}
/>
</Slide>
<Slide
Expand Down
9 changes: 9 additions & 0 deletions src/home/swap-container/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const SwapContainer = ({ swapIntervalsData, handleChangeNetwork }: SwapContainer
const replaceHistory = useReplaceHistory();
const trackEvent = useTrackEvent();
const [yieldOptions, isLoadingYieldOptions] = useYieldOptions(currentNetwork.chainId, true);
const [isPolygonDestnantion, setIsPolygonDestination] = React.useState<boolean>(false);

React.useEffect(() => {
if (fromParamToken) {
Expand Down Expand Up @@ -115,6 +116,12 @@ const SwapContainer = ({ swapIntervalsData, handleChangeNetwork }: SwapContainer
trackEvent('DCA - Set to', { fromAddress: from?.address, toAddress: newTo?.address });
};

const handlePolygonDestinantion = () => {
// eslint-disable-next-line no-console
console.log('Clicked');
setIsPolygonDestination(true);
};

const toggleFromTo = () => {
dispatch(setTo(from));

Expand Down Expand Up @@ -183,6 +190,8 @@ const SwapContainer = ({ swapIntervalsData, handleChangeNetwork }: SwapContainer
setToYield={onSetToYield}
availableFrequencies={availableFrequencies}
handleChangeNetwork={handleChangeNetwork}
isPolygonDestnantion={isPolygonDestnantion}
handlePolygonDestinantion={handlePolygonDestinantion}
/>
</Grid>
<Hidden mdDown>
Expand Down
96 changes: 96 additions & 0 deletions src/services/connextService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { getPoolFeeForUniV3, getXCallCallData, prepareSwapAndXCall } from '@connext/chain-abstraction';
import { DestinationCallDataParams, Swapper, SwapAndXCallParams } from '@connext/chain-abstraction/dist/types';
import { SdkConfig, create } from '@connext/sdk';
import { RAW_NETWORKS, SUPPORTED_CHAINS_BY_CONNEXT } from 'config';
import WalletService from './walletService';

interface DomainID {
[key: number]: string;
}

export default class ConnextService {
sdkConfig: SdkConfig;

walletService: WalletService;

destinantionChainID: number;

constructor(walletService: WalletService, destinantionChainID: number) {
this.walletService = walletService;
this.destinantionChainID = destinantionChainID;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be no longer neededright?

}

getRPCURL(chainID: number) {
const network = Object.values(RAW_NETWORKS).find((net) => net.chainId === chainID);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to use RAW_NETWORKS. The NETWORKS object will be more complete since its also hydrated from our SDK

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

return network?.rpc[0];
}

async getCalculatedRelayerFees(originDomain: string, destinationDomain: string) {
const domainConfig: { [domainId: string]: { providers: string[] } } = {};

const domainChainIds = Object.entries(SUPPORTED_CHAINS_BY_CONNEXT)
.filter(([key]) => typeof key === 'number')
.map(([key, value]) => ({ domainId: value.domainId, chainId: key }));

domainChainIds.forEach((obj) => {
domainConfig[obj.domainId] = { providers: [this.getRPCURL(parseInt(obj.chainId, 10)) as string] };
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

obj.chainId is already a string, no need to parse it

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should check that this.getRPCUrl actually does return something in case it could find the chainId

});

this.sdkConfig = {
signerAddress: this.walletService.account as string,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.walletService.getAccount() already returns string. Is it necessary to set the sdkConfig as a property of the class? Its not used anywhere else

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense, we can change that

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bump to this

network: 'mainnet', // can change it to testnet as well
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this parameter for?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For initing the connext core SDK

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right but I mean, what does it imply if it is "mainnet"? or "testnet"? shouldn't it work the same regardless of what type of network it is?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So for initialising the SDK we have to define if this is for mainnet or testnet. If we define any env for the environment we can modify it according to that!

chains: domainConfig,
};
const { sdkBase } = await create(this.sdkConfig);
const relayerFees = await sdkBase.estimateRelayerFee({
originDomain,
destinationDomain,
isHighPriority: true,
});
return relayerFees.toString();
}

async getPoolFeeForUniV3Helper(domainID: string, token0: string, token1: string, rpcURL: string) {
if (!rpcURL || !token0 || !token1) {
return null;
}
const poolFee = await getPoolFeeForUniV3(domainID, rpcURL, token0, token1);
return poolFee;
}

async getXCallCallDataHelper(domainID: string, forwardCallData: string, params: DestinationCallDataParams) {
const swapper = Swapper.UniV3;
const callDataForMeantTarget = await getXCallCallData(domainID, swapper, forwardCallData, params);
return callDataForMeantTarget;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
async getXCallCallDataHelper(domainID: string, forwardCallData: string, params: DestinationCallDataParams) {
const swapper = Swapper.UniV3;
const callDataForMeantTarget = await getXCallCallData(domainID, swapper, forwardCallData, params);
return callDataForMeantTarget;
}
getXCallCallDataHelper(domainID: string, forwardCallData: string, params: DestinationCallDataParams) {
return getXCallCallData(domainID, Swapper.UniV3;, forwardCallData, params);
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bump


async prepareSwapAndXCallHelper(swapAndXCallParams: SwapAndXCallParams, signerAddress: string) {
const txRequest = await prepareSwapAndXCall(swapAndXCallParams, signerAddress);
return txRequest;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
async prepareSwapAndXCallHelper(swapAndXCallParams: SwapAndXCallParams, signerAddress: string) {
const txRequest = await prepareSwapAndXCall(swapAndXCallParams, signerAddress);
return txRequest;
}
prepareSwapAndXCallHelper(swapAndXCallParams: SwapAndXCallParams, signerAddress: string) {
return prepareSwapAndXCall(swapAndXCallParams, signerAddress);
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bump


getDomainID(networkName: number): string {
const domainID: DomainID = {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this already on SUPPERTED_CHAINS_BY_CONNEXT?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding it as a class method so that it can be fetched by connextService itself, will move the supported chains by connext here as well

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bump to this

1: '6648936',
137: '1886350457',
10: '1869640809',
42161: '1634886255',
100: '6778479',
56: '6450786',
};

return domainID[networkName];
}

getNativeUSDCAddress(networkName: number) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will connext only work with USDC?

const USDC_ADDRESS: DomainID = {
1: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
137: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174',
10: '0x7F5c764cBc14f9669B88837ca1490cCa17c31607',
42161: '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8',
100: '0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83',
56: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',
};
return USDC_ADDRESS[networkName];
}
}
Loading