Skip to content

Commit

Permalink
Merge branch 'main' into harsh/get-dfi-evm
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierre Gee authored Nov 20, 2023
2 parents c3ff597 + 5b63897 commit 46d49a6
Show file tree
Hide file tree
Showing 22 changed files with 581 additions and 214 deletions.
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ services:
- "/var/run/docker.sock:/var/run/docker.sock:ro"

defi-blockchain:
image: defi/defichain:master-11717b5810
image: defi/defichain:4.0.0
ports:
- "19554:19554"
- "19551:19551"
Expand Down Expand Up @@ -64,7 +64,7 @@ services:
- RUST_LOG=debug

defi-playground:
image: ghcr.io/birthdayresearch/playground-api:4.0.0-rc.1.2
image: ghcr.io/birthdayresearch/playground-api:4.0.1
depends_on:
- defi-blockchain
ports:
Expand All @@ -77,7 +77,7 @@ services:
- "traefik.http.routers.playground.entrypoints=web"

defi-whale:
image: ghcr.io/birthdayresearch/whale-api:4.0.0-rc.1.2
image: ghcr.io/birthdayresearch/whale-api:4.0.1
depends_on:
- defi-blockchain
ports:
Expand Down
82 changes: 75 additions & 7 deletions mobile-app/app/components/OceanInterface/OceanInterface.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { useDeFiScanContext } from "@shared-contexts/DeFiScanContext";
import {
getMetaScanTxUrl,
useDeFiScanContext,
} from "@shared-contexts/DeFiScanContext";
import { useWalletContext } from "@shared-contexts/WalletContext";
import { useWhaleApiClient } from "@waveshq/walletkit-ui/dist/contexts";
import {
useNetworkContext,
useWhaleApiClient,
} from "@waveshq/walletkit-ui/dist/contexts";
import { CTransactionSegWit } from "@defichain/jellyfish-transaction/dist";
import { WhaleApiClient } from "@defichain/whale-api-client";
import { Transaction } from "@defichain/whale-api-client/dist/api/transactions";
Expand Down Expand Up @@ -30,11 +36,27 @@ const MAX_AUTO_RETRY = 1;
const MAX_TIMEOUT = 300000;
const INTERVAL_TIME = 5000;

enum VmmapTypes {
Auto = 0,
BlockNumberDVMToEVM = 1,
BlockNumberEVMToDVM = 2,
BlockHashDVMToEVM = 3,
BlockHashEVMToDVM = 4,
TxHashDVMToEVM = 5,
TxHasEVMToDVM = 6,
}

interface VmmapResult {
input: string;
type: string;
output: string;
}

async function broadcastTransaction(
tx: CTransactionSegWit,
client: WhaleApiClient,
retries: number = 0,
logger: NativeLoggingProps
logger: NativeLoggingProps,
): Promise<string> {
try {
return await client.rawtx.send({ hex: tx.toHex() });
Expand All @@ -50,7 +72,7 @@ async function broadcastTransaction(
async function waitForTxConfirmation(
id: string,
client: WhaleApiClient,
logger: NativeLoggingProps
logger: NativeLoggingProps,
): Promise<Transaction> {
const initialTime = getEnvironment(getReleaseChannel()).debug ? 5000 : 30000;
let start = initialTime;
Expand Down Expand Up @@ -96,24 +118,68 @@ export function OceanInterface(): JSX.Element | null {
const client = useWhaleApiClient();
const { wallet, address } = useWalletContext();
const { getTransactionUrl } = useDeFiScanContext();
const { network } = useNetworkContext();

// store
const { height, err: e } = useSelector((state: RootState) => state.ocean);
const transaction = useSelector((state: RootState) =>
firstTransactionSelector(state.ocean)
firstTransactionSelector(state.ocean),
);
const slideAnim = useRef(new Animated.Value(0)).current;
// state
const [tx, setTx] = useState<OceanTransaction | undefined>(transaction);
const [err, setError] = useState<string | undefined>(e?.message);
const [txUrl, setTxUrl] = useState<string | undefined>();
// evm tx state
const [evmTxId, setEvmTxId] = useState<string>();
const [evmTxUrl, setEvmTxUrl] = useState<string>();

const dismissDrawer = useCallback(() => {
setTx(undefined);
setError(undefined);
slideAnim.setValue(0);
}, [slideAnim]);

const getEvmTxId = async (oceanTxId: string) => {
const vmmap: VmmapResult = await client.rpc.call(
"vmmap",
[oceanTxId, VmmapTypes.TxHashDVMToEVM],
"lossless",
);
return vmmap.output;
};

useEffect(() => {
// get evm tx id and url (if any)
const fetchEvmTx = async (txId: string) => {
try {
const mappedEvmTxId = await getEvmTxId(txId);
const txUrl = getMetaScanTxUrl(network, mappedEvmTxId);
setEvmTxId(mappedEvmTxId);
setEvmTxUrl(txUrl);
} catch (error) {
logger.error(error);
}
};

if (tx !== undefined) {
const isTransferDomainTx = tx?.tx.vout.some(
(vout) =>
vout.script?.stack.some(
(item: any) =>
item.type === "OP_DEFI_TX" &&
item.tx?.name === "OP_DEFI_TX_TRANSFER_DOMAIN",
),
);
if (isTransferDomainTx) {
fetchEvmTx(tx.tx.txId);
}
} else {
setEvmTxId(undefined);
setEvmTxUrl(undefined);
}
}, [tx]);

useEffect(() => {
// last available job will remained in this UI state until get dismissed
if (transaction !== undefined) {
Expand All @@ -133,7 +199,7 @@ export function OceanInterface(): JSX.Element | null {
.then(async () => {
try {
setTxUrl(
getTransactionUrl(transaction.tx.txId, transaction.tx.toHex())
getTransactionUrl(transaction.tx.txId, transaction.tx.toHex()),
);
} catch (e) {
logger.error(e);
Expand All @@ -159,7 +225,7 @@ export function OceanInterface(): JSX.Element | null {
logger.error(e);
title = translate(
"screens/OceanInterface",
"Sent (Pending confirmation)"
"Sent (Pending confirmation)",
);
oceanStatusCode = TransactionStatusCode.pending;
}
Expand Down Expand Up @@ -224,6 +290,8 @@ export function OceanInterface(): JSX.Element | null {
oceanStatusCode={tx.oceanStatusCode}
txUrl={txUrl}
txid={tx.tx.txId}
evmTxId={evmTxId}
evmTxUrl={evmTxUrl}
/>
)
)}
Expand Down
39 changes: 30 additions & 9 deletions mobile-app/app/components/OceanInterface/TransactionDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ interface TransactionDetailProps {
broadcasted: boolean;
txid?: string;
txUrl?: string;
evmTxId?: string;
evmTxUrl?: string;
onClose: () => void;
title?: string;
oceanStatusCode?: TransactionStatusCode;
Expand All @@ -25,10 +27,13 @@ export function TransactionDetail({
broadcasted,
txid,
txUrl,
evmTxId,
evmTxUrl,
onClose,
title,
oceanStatusCode,
}: TransactionDetailProps): JSX.Element {
const hasEvmTx = evmTxId !== undefined && evmTxUrl !== undefined;
title = title ?? translate("screens/OceanInterface", "Broadcasting...");

return (
Expand All @@ -42,7 +47,7 @@ export function TransactionDetail({
{
"border-darkwarning-500":
oceanStatusCode === TransactionStatusCode.pending,
}
},
)}
light={tailwind(
"bg-mono-light-v2-00 border-mono-light-v2-500",
Expand All @@ -53,14 +58,14 @@ export function TransactionDetail({
{
"border-warning-500":
oceanStatusCode === TransactionStatusCode.pending,
}
},
)}
style={tailwind(
"w-full rounded-lg-v2 flex flex-row items-center border-0.5",
{
"pl-5": broadcasted,
"px-5": !broadcasted,
}
},
)}
>
{!broadcasted ? (
Expand Down Expand Up @@ -94,12 +99,28 @@ export function TransactionDetail({
{title}
</ThemedTextV2>

{txid !== undefined && txUrl !== undefined && (
<TransactionIDButton
onPress={async () => await gotoExplorer(txUrl)}
txid={txid}
/>
)}
<View style={tailwind("flex-row")}>
{txid !== undefined && txUrl !== undefined && (
<TransactionIDButton
testID="oceanNetwork_explorer"
onPress={async () => await gotoExplorer(txUrl)}
txid={txid}
{...(hasEvmTx && {
styleProps: "w-1/2 pr-2",
dark: tailwind("border-r border-mono-dark-v2-300"),
light: tailwind("border-r border-mono-light-v2-300"),
})}
/>
)}
{hasEvmTx && (
<TransactionIDButton
testID="evmNetwork_explorer"
onPress={async () => await gotoExplorer(evmTxUrl)}
txid={evmTxId}
styleProps="w-1/2 pl-2"
/>
)}
</View>
</View>

{broadcasted && <TransactionCloseButton onPress={onClose} />}
Expand Down
26 changes: 19 additions & 7 deletions mobile-app/app/components/OceanInterface/TransactionIDButton.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
import { TouchableOpacity } from "react-native";
import { tailwind } from "@tailwind";
import { ThemedIcon, ThemedTextV2 } from "@components/themed";
import {
ThemedIcon,
ThemedProps,
ThemedTextV2,
ThemedTouchableOpacity,
} from "@components/themed";

interface TransactionIDButtonProps {
testID: string;
txid: string;
onPress?: () => void;
styleProps?: string;
}

export function TransactionIDButton({
testID,
txid,
onPress,
}: TransactionIDButtonProps): JSX.Element {
styleProps = "w-8/12",
light = tailwind("border-0"),
dark = tailwind("border-0"),
}: TransactionIDButtonProps & ThemedProps): JSX.Element {
return (
<TouchableOpacity
<ThemedTouchableOpacity
onPress={onPress}
style={tailwind("flex-row pt-1 items-center w-8/12")}
testID="oceanNetwork_explorer"
style={tailwind(`flex-row mt-1 items-center ${styleProps}`)}
testID={testID}
light={light}
dark={dark}
>
<ThemedTextV2
dark={tailwind("text-mono-dark-v2-700")}
Expand All @@ -34,6 +46,6 @@ export function TransactionIDButton({
name="external-link"
size={16}
/>
</TouchableOpacity>
</ThemedTouchableOpacity>
);
}
Loading

0 comments on commit 46d49a6

Please sign in to comment.