Skip to content

Commit

Permalink
mobile: use bitrefill new parse
Browse files Browse the repository at this point in the history
  • Loading branch information
nalinbhardwaj committed Nov 5, 2024
1 parent cffce76 commit 39ef9d5
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 31 deletions.
4 changes: 2 additions & 2 deletions apps/daimo-mobile/src/action/dispatch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DaimoRequestV2Status, DollarStr, ProposedSwap } from "@daimo/common";
import { BigIntStr, DaimoRequestV2Status, ProposedSwap } from "@daimo/common";
import { ReactElement, createContext } from "react";
import { Address } from "viem";

Expand All @@ -13,7 +13,7 @@ export type Action =
| { name: "createBackup" }
| { name: "hideBottomSheet" }
| { name: "swap"; swap: ProposedSwap }
| { name: "bitrefill"; address: Address; amount: DollarStr };
| { name: "bitrefill"; address: Address; amount: BigIntStr };

type ActionName = Action["name"];

Expand Down
37 changes: 37 additions & 0 deletions apps/daimo-mobile/src/logic/paymentURI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { BigIntStr } from "@daimo/common";
import { polygonUSDC } from "@daimo/contract";
import { isAddress, getAddress } from "viem";

export function parsePaymentUri(uri: string) {
const [protocol, rest] = uri.split(":");
if (protocol !== "ethereum") throw new Error("Invalid protocol");

const [tokenAddressAndChain, pathAndQuery] = rest.split("/");
const [tokenAddress, chainId] = tokenAddressAndChain.split("@");
if (
!isAddress(tokenAddress) ||
getAddress(tokenAddress) !== polygonUSDC.token
) {
throw new Error("Invalid token address");
}
if (!chainId || chainId !== "137") {
throw new Error("Unsupported chain ID");
}

const [path, queryString] = pathAndQuery.split("?");
if (path !== "transfer") throw new Error("Invalid path");

const params = new URLSearchParams(queryString);
const recipientAddress = params.get("address");
const amount = params.get("uint256");

if (!recipientAddress || !isAddress(recipientAddress)) {
throw new Error("Invalid recipient address");
}
if (!amount) throw new Error("Missing amount");

return {
recipientAddress: getAddress(recipientAddress),
amount: BigInt(Number(amount)).toString() as BigIntStr,
};
}
26 changes: 4 additions & 22 deletions apps/daimo-mobile/src/view/screen/deposit/BitrefillWebview.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { assert, zDollarStr } from "@daimo/common";
import { useContext } from "react";
import { View } from "react-native";
import { WebView } from "react-native-webview";
import { getAddress, isAddress } from "viem";
import { z } from "zod";
import { getAddress } from "viem";

import { DispatcherContext } from "../../../action/dispatch";
import { useNav } from "../../../common/nav";
import { i18NLocale } from "../../../i18n";
import { parsePaymentUri } from "../../../logic/paymentURI";
import { ScreenHeader } from "../../shared/ScreenHeader";
import { useTheme } from "../../style/theme";

Expand All @@ -22,29 +21,12 @@ export function BitrefillWebView() {
case "payment_intent": {
console.log(`[BITREFILL] payment_intent ${paymentUri}`);

const PaymentUriSchema = z.object({
protocol: z.literal("ethereum"),
address: z.string().refine((addr) => isAddress(addr), {
message: "Invalid Ethereum address",
}),
amount: zDollarStr,
});

try {
const [protocol, rest] = paymentUri.split(":");
assert(protocol === "ethereum");
const [address, queryString] = rest.split("?");
const params = new URLSearchParams(queryString);

const parsedUri = PaymentUriSchema.parse({
protocol,
address,
amount: params.get("amount") || "",
});
const parsedUri = parsePaymentUri(paymentUri);

dispatcher.dispatch({
name: "bitrefill",
address: getAddress(parsedUri.address),
address: getAddress(parsedUri.recipientAddress),
amount: parsedUri.amount,
});
} catch (error) {
Expand Down
14 changes: 9 additions & 5 deletions apps/daimo-mobile/src/view/sheet/BitrefillBottomSheet.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { DollarStr, usdEntry } from "@daimo/common";
import { BigIntStr, usdEntry } from "@daimo/common";
import { polygonUSDC } from "@daimo/contract";
import { useState } from "react";
import { View } from "react-native";
import { Address } from "viem";
import { Address, formatUnits } from "viem";

import { i18n } from "../../i18n";
import { EAccountContact } from "../../logic/daimoContacts";
Expand All @@ -21,7 +21,7 @@ export function BitrefillBottomSheet({
amount,
}: {
address: Address;
amount: DollarStr;
amount: BigIntStr;
}) {
const Inner = useWithAccount(BitrefillBottomSheetInner);
return <Inner address={address} amount={amount} />;
Expand All @@ -34,14 +34,18 @@ function BitrefillBottomSheetInner({
}: {
account: Account;
address: Address;
amount: `${number}`;
amount: BigIntStr;
}) {
const { color } = useTheme();
const recipient: EAccountContact = { type: "eAcc", addr: address };
// Show "bitrefill" as the name, but only on the send screen
const recipientWithName = { ...recipient, name: "Bitrefill" };

const money = usdEntry(amount);
const roundedUpDollars = Math.ceil(
parseFloat(formatUnits(BigInt(amount), 6))
);

const money = usdEntry(roundedUpDollars);
const toCoin = polygonUSDC;

const [success, setSuccess] = useState(false);
Expand Down
4 changes: 2 additions & 2 deletions apps/daimo-mobile/src/view/sheet/GlobalBottomSheet.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DaimoRequestV2Status, ProposedSwap } from "@daimo/common";
import { BigIntStr, DaimoRequestV2Status, ProposedSwap } from "@daimo/common";
import BottomSheet, {
BottomSheetBackdrop,
BottomSheetView,
Expand Down Expand Up @@ -89,7 +89,7 @@ type DisplayedSheet =
| { action: "swap"; payload: { swap: ProposedSwap } }
| {
action: "bitrefill";
payload: { address: Address; amount: `${number}` };
payload: { address: Address; amount: BigIntStr };
};

// Shows the main, global bottom sheet. This ensures that only a single of
Expand Down
15 changes: 15 additions & 0 deletions apps/daimo-mobile/test/paymentURI.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { parsePaymentUri } from "../src/logic/paymentURI";

describe("Payment URI", () => {
// https://github.com/daimo-eth/daimo/issues/1356
it("Parses Bitrefill URI", () => {
const uri = parsePaymentUri(
`ethereum:0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359@137/transfer?address=0xaCB6230043d1Fc3dE02a43Aa748540bb9F260931&uint256=1e8`
);

expect(uri.recipientAddress).toEqual(
"0xaCB6230043d1Fc3dE02a43Aa748540bb9F260931"
);
expect(uri.amount).toEqual("100000000");
});
});

0 comments on commit 39ef9d5

Please sign in to comment.