Skip to content

Commit 27acaf7

Browse files
authored
Add testapp page for testing new config values (#1404)
* wallet-sdk lint issues * update testapp to have new config page for testing
1 parent 2342396 commit 27acaf7

File tree

11 files changed

+377
-114
lines changed

11 files changed

+377
-114
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Box, Grid, GridItem, Heading } from "@chakra-ui/react";
2+
import React from "react";
3+
4+
import { RpcRequestInput } from "../RpcMethods/method/RpcRequestInput";
5+
import { RpcMethodCard } from "../RpcMethods/RpcMethodCard";
6+
import { ShortcutType } from "../RpcMethods/shortcut/ShortcutType";
7+
8+
export function MethodsSection({
9+
title,
10+
methods,
11+
shortcutsMap,
12+
}: {
13+
title: string;
14+
methods: RpcRequestInput[];
15+
shortcutsMap?: Record<string, ShortcutType[]>;
16+
}) {
17+
return (
18+
<Box mt={4}>
19+
<Heading size="md">{title}</Heading>
20+
<Grid
21+
mt={2}
22+
templateColumns={{
23+
base: "100%",
24+
md: "repeat(2, 50%)",
25+
xl: "repeat(3, 33%)",
26+
}}
27+
gap={2}
28+
>
29+
{methods.map((rpc) => (
30+
<GridItem w="100%" key={rpc.method}>
31+
<RpcMethodCard
32+
method={rpc.method}
33+
params={rpc.params}
34+
format={rpc.format}
35+
shortcuts={shortcutsMap?.[rpc.method]}
36+
/>
37+
</GridItem>
38+
))}
39+
</Grid>
40+
</Box>
41+
);
42+
}

examples/testapp/src/components/RpcMethods/RpcMethodCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export function RpcMethodCard({ format, method, params, shortcuts }) {
9595
params: values,
9696
});
9797
setResponse(response);
98-
verify(response, data);
98+
await verify(response, data);
9999
} catch (err) {
100100
const { code, message, data } = err;
101101
setError({ code, message, data });
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
import {
2+
Alert,
3+
AlertIcon,
4+
AlertTitle,
5+
Box,
6+
Button,
7+
Card,
8+
CardBody,
9+
CardHeader,
10+
Code,
11+
Flex,
12+
FormControl,
13+
FormLabel,
14+
FormHelperText,
15+
Heading,
16+
Input,
17+
Menu,
18+
MenuButton,
19+
MenuItem,
20+
MenuList,
21+
Text,
22+
VStack,
23+
Divider,
24+
} from "@chakra-ui/react";
25+
import React, { useCallback, useMemo, useState } from "react";
26+
import { createCoinbaseWalletSDK } from "@coinbase/wallet-sdk";
27+
import { useCBWSDK } from "../../context/CBWSDKReactContextProvider";
28+
import {
29+
Preference,
30+
} from "@coinbase/wallet-sdk/dist/core/provider/interface";
31+
import { CheckIcon, ChevronDownIcon } from "@chakra-ui/icons";
32+
import { keccak256, slice, toHex } from "viem";
33+
import { CreateCoinbaseWalletSDKOptions } from "@coinbase/wallet-sdk/dist/createCoinbaseWalletSDK";
34+
35+
type PostOnboardingAction = "none" | "onramp" | "magicspend";
36+
37+
const postOnboardingActions = ["none", "onramp", "magicspend"] as const;
38+
39+
type OnrampPrefillOptions = {
40+
contractAddress?: string;
41+
amount: string;
42+
chainId: number;
43+
};
44+
45+
type Config = {
46+
postOnboardingAction?: PostOnboardingAction;
47+
onrampPrefillOptions?: OnrampPrefillOptions;
48+
attributionDataSuffix?: string;
49+
};
50+
51+
export function SDKConfig() {
52+
const { option, scwUrl } = useCBWSDK();
53+
const [config, setConfig] = React.useState<Config>({});
54+
55+
const options: CreateCoinbaseWalletSDKOptions = useMemo(() => {
56+
const preference: Preference = {
57+
options: option,
58+
keysUrl: scwUrl,
59+
...config,
60+
};
61+
return {
62+
appName: "SDK Playground",
63+
appLogoUrl: null,
64+
appChainIds: [84532, 8452],
65+
preference,
66+
};
67+
}, [config, option, scwUrl]);
68+
69+
const startOnboarding = useCallback(async () => {
70+
const sdk = createCoinbaseWalletSDK(options);
71+
const provider = sdk.getProvider();
72+
await provider.request({ method: "eth_requestAccounts" });
73+
}, [options]);
74+
75+
const handlePostOnboardingAction = useCallback(
76+
(action: PostOnboardingAction) => {
77+
const config_ = { ...config, postOnboardingAction: action };
78+
if (action !== "onramp") {
79+
delete config_.onrampPrefillOptions;
80+
}
81+
setConfig(config_);
82+
},
83+
[config]
84+
);
85+
86+
const handleOnrampPrefill = useCallback(
87+
(key: "contractAddress" | "amount" | "chainId") => (e) => {
88+
const value = e.target.value;
89+
setConfig((prev) => ({
90+
...prev,
91+
onrampPrefillOptions: {
92+
...prev.onrampPrefillOptions,
93+
[key]: value,
94+
},
95+
}));
96+
},
97+
[]
98+
);
99+
100+
const handleSetDataSuffix = useCallback((e) => {
101+
const value = e.target.value;
102+
setConfig((prev) => ({
103+
...prev,
104+
attributionDataSuffix: value,
105+
}));
106+
}, []);
107+
108+
const [dataSuffix, setDataSuffix] = useState("Coinbase Wallet");
109+
const fourByteHex = useMemo(
110+
() => slice(keccak256(toHex(dataSuffix)), 0, 4),
111+
[dataSuffix]
112+
);
113+
114+
return (
115+
<Card>
116+
<CardHeader>
117+
<Alert status="error">
118+
<AlertIcon />
119+
<AlertTitle>
120+
This section ONLY works for testing onboarding config
121+
</AlertTitle>
122+
</Alert>
123+
<Alert status="info" mt={2}>
124+
<AlertIcon />
125+
<AlertTitle>
126+
Please signout of your Smart Wallet and reset the playground before
127+
testing
128+
</AlertTitle>
129+
</Alert>
130+
</CardHeader>
131+
<CardBody>
132+
<Flex justify="space-between" align="center">
133+
<Box>
134+
<Heading size="md">Post Onboarding Action</Heading>
135+
<Code mt={2}>postOnboardingAction</Code>
136+
</Box>
137+
<Menu>
138+
<MenuButton
139+
colorScheme="telegram"
140+
as={Button}
141+
rightIcon={<ChevronDownIcon />}
142+
>
143+
{config?.postOnboardingAction}
144+
</MenuButton>
145+
<MenuList>
146+
{postOnboardingActions.map((action) => (
147+
<MenuItem
148+
color={"MenuText"}
149+
key={action}
150+
icon={
151+
action === config.postOnboardingAction ? (
152+
<CheckIcon />
153+
) : null
154+
}
155+
onClick={() => handlePostOnboardingAction(action)}
156+
>
157+
{action}
158+
</MenuItem>
159+
))}
160+
</MenuList>
161+
</Menu>
162+
</Flex>
163+
{config.postOnboardingAction === "onramp" && (
164+
<>
165+
<Divider my={6} />
166+
<Flex justify="space-between" align="center" mt={6}>
167+
<Box>
168+
<Heading size="md">Onramp Prefill Options</Heading>
169+
<Text fontSize="sm" maxW="400px">
170+
Optional: Only works when postOnboardingAction is set to
171+
onramp. Amount and chainId are required. If contract address
172+
is omitted, onramp assumes native asset for that chain
173+
</Text>
174+
<Code mt={2}>onrampPrefillOptions</Code>
175+
</Box>
176+
<VStack>
177+
<Input
178+
placeholder="Contract Address"
179+
onChange={handleOnrampPrefill("contractAddress")}
180+
/>
181+
<Input
182+
placeholder="Amount (wei)"
183+
required
184+
onChange={handleOnrampPrefill("amount")}
185+
/>
186+
<Input
187+
placeholder="Chain ID"
188+
required
189+
onChange={(e) =>
190+
handleOnrampPrefill("chainId")({
191+
target: { value: parseInt(e.target.value, 10) },
192+
})
193+
}
194+
/>
195+
</VStack>
196+
</Flex>
197+
</>
198+
)}
199+
<Divider my={6} />
200+
<Flex justify="space-between" align="center">
201+
<Box>
202+
<Heading size="md">Attribution Data Suffix</Heading>
203+
<Text fontSize="sm">
204+
First 4 bytes of a unique string to identify your onchain activity
205+
</Text>
206+
<FormControl mt={2}>
207+
<FormLabel>
208+
<Code>attributionDataSuffix</Code>
209+
</FormLabel>
210+
<Input
211+
mt={2}
212+
type="text"
213+
placeholder="Enter String"
214+
onChange={(e) => setDataSuffix(e.target.value)}
215+
value={dataSuffix}
216+
/>
217+
<FormHelperText>
218+
Convert any string into a 4 byte data suffix
219+
</FormHelperText>
220+
</FormControl>
221+
<Code mt={2} colorScheme="telegram">
222+
{fourByteHex}
223+
</Code>
224+
</Box>
225+
<VStack>
226+
<Input
227+
placeholder="Data Suffix (4 bytes)"
228+
onChange={handleSetDataSuffix}
229+
/>
230+
</VStack>
231+
</Flex>
232+
</CardBody>
233+
<Button size="lg" colorScheme="telegram" onClick={startOnboarding}>
234+
Start Onboarding
235+
</Button>
236+
</Card>
237+
);
238+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Container } from "@chakra-ui/react";
2+
import { WIDTH_2XL } from "../components/Layout";
3+
import dynamic from "next/dynamic";
4+
5+
const SDKConfig = dynamic(
6+
() =>
7+
import("../components/SDKConfig/SdkConfig").then((mod) => mod.SDKConfig),
8+
{ ssr: false }
9+
);
10+
11+
export default function Config() {
12+
return (
13+
<Container maxW={WIDTH_2XL} mb={8}>
14+
<SDKConfig />
15+
</Container>
16+
);
17+
}

0 commit comments

Comments
 (0)