Skip to content

Commit

Permalink
Merge branch 'dev' into release/v0.2
Browse files Browse the repository at this point in the history
merge in latest dev
.
  • Loading branch information
brucedonovan committed Sep 18, 2023
2 parents 284e862 + 07bec22 commit 9a5248f
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 26 deletions.
24 changes: 22 additions & 2 deletions src/components/cactiComponents/ErrorResponse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ChevronUpIcon,
ExclamationTriangleIcon,
} from '@heroicons/react/24/outline';
import { useAccount } from 'wagmi';
import { Markdown } from '../current/Markdown';
import { buttonStyle } from '../current/layout/sidebar/NewChatButton';
import { ResponseTitle, ResponseWrap } from './helpers/layout';
Expand All @@ -14,6 +15,7 @@ export interface ErrorResponseProps {
text: string;
error: string;
}

/**
* Error response element
*
Expand All @@ -22,6 +24,8 @@ export interface ErrorResponseProps {
*/

export const ErrorResponse = (props: ErrorResponseProps): JSX.Element => {
const { address } = useAccount();

return (
<ResponseWrap>
<Disclosure as="div" defaultOpen={false}>
Expand All @@ -43,8 +47,24 @@ export const ErrorResponse = (props: ErrorResponseProps): JSX.Element => {
<div className="p-4 font-mono text-xs">
<Markdown>{props.error}</Markdown>
</div>
<div className="flex w-full justify-center">
<button className={buttonStyle}> Submit Bug Report </button>
<div className="flex w-full justify-center gap-2 ">
{/* <form name="bug-report" method="POST" data-netlify="true">
<input type="hidden" name="form-name" value="bug-report" />
<input type="hidden" name="name" id="yourname" value={address} />
<input type="hidden" name="message" id="yourmessage" value={props.error} />
<button className={buttonStyle} type="submit">
Submit Bug Report
</button>
</form> */}

<a
className={buttonStyle}
href={`https://discord.gg/hu8zVcBty6`}
target="_blank"
rel="noreferrer"
>
Get help on Discord
</a>
</div>
</Disclosure.Panel>
</>
Expand Down
13 changes: 11 additions & 2 deletions src/components/current/Markdown.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import React, { ReactNode } from 'react';
import ReactMarkdown from 'react-markdown';

//======================================
export const Markdown = ({ children }: { children: string }) => {
// regex to match URLs in text that arent already formatted as links in markdown
const urlRegex = /(?<!\]\()https?:\/\/[^\s]+(?!\))/g;

// add markdown syntax to format links in text if they aren't already marked
const processedText = children.replace(urlRegex, (url) => `[${url}](${url})`);

return (
<ReactMarkdown
components={{
ul: (props) => <ul className="list-disc" {...props} />,
a: (props) => <a className="text-blue-400 underline" {...props} />,
a: (props) => (
<a className="testerino text-blue-400 underline" target="_blank" {...props} />
),
code: (props) => <code className="text-orange-300" {...props} />,
}}
>
{children}
{processedText}
</ReactMarkdown>
);
};
4 changes: 2 additions & 2 deletions src/components/current/layout/sidebar/MoreItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ const MoreItems = () => {
<MoreItem
icon={<DiscordIcon />}
label="Discord"
action={() => navigateToExternalUrl('https://github.com/yieldprotocol/chatweb3-backend')}
action={() => navigateToExternalUrl('https://discord.gg/BkCg3yFK')}
/>
<MoreItem
icon={<TwitterIcon />}
label="Twitter"
action={() => navigateToExternalUrl('https://github.com/yieldprotocol/chatweb3-backend')}
action={() => navigateToExternalUrl('https://twitter.com/wearecacti')}
/>
<MoreItem
icon={<WrenchIcon />}
Expand Down
75 changes: 57 additions & 18 deletions src/components/current/widgets/hop/HopBridge.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import React, { useEffect, useState } from 'react';
import { Hop } from '@hop-protocol/sdk';
import { CanonicalToken, ChainSlug } from '@hop-protocol/sdk/dist/src/constants';
import { Interface, UnsignedTransaction } from 'ethers/lib/utils';
import { erc20ABI } from 'wagmi';
import { ActionResponse, HeaderResponse, SingleLineResponse } from '@/components/cactiComponents';
import {
ActionResponse,
ErrorResponse,
HeaderResponse,
SingleLineResponse,
} from '@/components/cactiComponents';
import { ApprovalBasicParams } from '@/components/cactiComponents/hooks/useApproval';
import useInput from '@/hooks/useInput';
import useSigner from '@/hooks/useSigner';
Expand All @@ -16,27 +22,61 @@ interface HopBridgeProps {
}

const HopBridge = ({ inputString, tokenSymbol, toChain, fromChain }: HopBridgeProps) => {
const _fromChain = fromChain === 'ethereum-mainnet' ? 'mainnet' : fromChain;
const _fromChain = fromChain === 'ethereum-mainnet' ? 'mainnet' : fromChain.toLowerCase();
const _toChain = toChain === 'ethereum-mainnet' ? 'mainnet' : toChain.toLowerCase();

const signer = useSigner();
const { data: tokenIn } = useToken(tokenSymbol);
const input = useInput(inputString, tokenIn?.symbol!);
const [approvalParams, setApprovalParams] = useState<ApprovalBasicParams>();
const [sendParams, setSendParams] = useState<UnsignedTransaction>();
const [error, setError] = useState<string>();
const [error, setError] = useState<string | null>(null);

// TODO simple check to see if the chain is potentially supported; not all chains with chain slugs are supported within hop though (i.e.: zksync is unsupported)
const isSupportedChain = (name: string) =>
name === 'mainnet' ||
Object.keys(ChainSlug)
.map((s) => s.toLowerCase())
.includes(name.toLowerCase());

const isSupportedToken = (symbol: string) =>
Object.keys(CanonicalToken).includes(symbol.toUpperCase());

useEffect(() => {
(async () => {
if (!input?.value) return console.error('No value to bridge');
setError(null);

if (!isSupportedChain(_fromChain)) {
return setError(
`Unsupported from chain. Available chains: ${Object.keys(ChainSlug).join(', ')}`
);
}

if (!isSupportedChain(_toChain)) {
return setError(
`Unsupported to chain. Available chains: ${Object.keys(ChainSlug).join(', ')}`
);
}

if (!isSupportedToken(tokenSymbol)) {
return setError(
`Unsupported token. Available tokens: ${Object.keys(CanonicalToken).join(', ')}`
);
}

if (!input?.value) {
setError('Please provide a value to bridge');
return console.error('No value to bridge');
}

try {
const hop = new Hop(_fromChain, signer);
// mainnet is the network we use for all bridge operations
const hop = new Hop('mainnet', signer);
const bridge = hop.bridge(tokenSymbol);

const needsApproval = await bridge.needsApproval(input.value, _fromChain);
if (needsApproval) {
// TODO wip

if (needsApproval) {
const { data } = await bridge.populateSendApprovalTx(input.value, _fromChain);

const erc20Interface = new Interface(erc20ABI);
Expand All @@ -51,31 +91,30 @@ const HopBridge = ({ inputString, tokenSymbol, toChain, fromChain }: HopBridgePr
});
}

// TODO get the relevant to chain from hop
const req = await bridge.populateSendTx(input?.value, _fromChain, toChain);
const req = await bridge.populateSendTx(input.value, _fromChain, _toChain);
setSendParams({ ...req, gasLimit: 10_000_000 }); // TODO figure out a better way to handle gas limits on forks
} catch (e) {
setError(e as string);
console.error('An error occurred:', e);
setError((e as Error).message);
console.error(e);
}
})();
}, [_fromChain, input?.value, toChain, tokenIn?.address, tokenSymbol]); // TODO signer is causing infinite loop
}, [_fromChain, input?.value, _toChain, tokenIn?.address, tokenSymbol]); // TODO signer is causing infinite loop

return (
<>
<HeaderResponse
text={`Bridge ${tokenSymbol} from ${_fromChain} to ${toChain} using Hop Protocol`}
text={`Bridge ${tokenSymbol} from ${_fromChain} to ${_toChain} using Hop Protocol`}
altUrl={`https://app.hop.exchange/`}
/>
{error && (
<ErrorResponse text={`An error occurred while preparing the transaction`} error={error} />
)}
<SingleLineResponse tokenSymbol={tokenSymbol} value={input?.formatted} />
<ActionResponse
label={
error ??
`Bridge ${input?.formatted || ''} ${tokenSymbol} from ${_fromChain} to ${toChain}`
}
label={`Bridge ${input?.formatted || ''} ${tokenSymbol} from ${_fromChain} to ${_toChain}`}
approvalParams={approvalParams}
txParams={undefined}
sendParams={sendParams}
disabled={!!error}
/>
</>
);
Expand Down
6 changes: 5 additions & 1 deletion src/components/current/widgets/nft/NftAsset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Address } from 'wagmi';
import { ImageResponse } from '@/components/cactiComponents';
import { ImageVariant } from '@/components/cactiComponents/ImageResponse';
import { InlineChip } from '@/components/cactiComponents/InlineChip';
import { getBackendApiUrl } from '@/utils/backend';

export interface NftAssetProps {
network: Network;
Expand Down Expand Up @@ -39,9 +40,12 @@ export const NftAsset = ({
price,
attributes,
}: NftAssetProps) => {

const backendUrl = getBackendApiUrl();

return (
<ImageResponse
image={previewImageUrl}
image={`${backendUrl}/center_image/${network}/${address}/${tokenId}/small`}
imageTags={
variant === ImageVariant.SHOWCASE
? [`Token Id: ${tokenId}`, `${network.replace('-mainnet', '')}`]
Expand Down
2 changes: 1 addition & 1 deletion src/components/devTools/MintButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const MintButton = () => {
ethers.utils.parseEther('10').toHexString(), // hex encoded wei amount
];
setLoading(true);
//@ts-ignore
// @ts-ignore
await provider.send('tenderly_addBalance', params);
await refetch();
setLoading(false);
Expand Down

0 comments on commit 9a5248f

Please sign in to comment.