Skip to content

Commit 1f647c4

Browse files
committed
gnosis safe instructions
1 parent 2f50b35 commit 1f647c4

File tree

10 files changed

+211
-2
lines changed

10 files changed

+211
-2
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"dependencies": {
1515
"@noble/ed25519": "^2.0.0",
1616
"@orderly.network/types": "^0.1.28",
17+
"@radix-ui/react-icons": "^1.3.0",
1718
"@radix-ui/themes": "^2.0.2",
1819
"@safe-global/safe-apps-provider": "^0.18.2",
1920
"@safe-global/safe-apps-sdk": "^9.0.0",

public/batch-create.webp

16.5 KB
Binary file not shown.

public/confirm-tx.webp

36.6 KB
Binary file not shown.

public/multisig-txhash.webp

36.1 KB
Binary file not shown.

public/review-batch.webp

30.6 KB
Binary file not shown.

public/safe.webp

28.7 KB
Binary file not shown.

src/Account.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { useConnectWallet, useSetChain } from '@web3-onboard/react';
44
import { encodeBase58 } from 'ethers';
55
import { FC, useEffect, useState } from 'react';
66

7+
import { SafeInstructions } from './SafeInstructions';
78
import {
89
DelegateSignerResponse,
910
announceDelegateSigner,
@@ -100,14 +101,16 @@ export const Account: FC<{
100101
onClick={async () => {
101102
const address = wallet?.accounts[0]?.address;
102103
if (!wallet || !connectedChain || !address) return;
103-
const hash = await registerDelegateSigner(wallet, connectedChain.id, address);
104+
const hash = await registerDelegateSigner(wallet, brokerId, connectedChain.id, address);
104105
setTxHash(hash);
105106
}}
106107
>
107108
Register Delegate Signer
108109
</Button>
109110
)}
110111

112+
{connectedChain && <SafeInstructions brokerId={brokerId} chainId={connectedChain.id} />}
113+
111114
<Flex direction="column" gap="1">
112115
<label>
113116
Transaction Hash

src/SafeInstructions.tsx

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
import { CopyIcon } from '@radix-ui/react-icons';
2+
import {
3+
Blockquote,
4+
Button,
5+
Code,
6+
Container,
7+
Dialog,
8+
Flex,
9+
IconButton,
10+
ScrollArea,
11+
Strong,
12+
Tabs,
13+
Text
14+
} from '@radix-ui/themes';
15+
import { useConnectWallet } from '@web3-onboard/react';
16+
import { solidityPackedKeccak256 } from 'ethers';
17+
import { FC, useEffect, useState } from 'react';
18+
19+
import { getVaultAddress } from './helpers';
20+
21+
export const SafeInstructions: FC<{ brokerId: string; chainId: string }> = ({
22+
brokerId,
23+
chainId
24+
}) => {
25+
const [abi, setAbi] = useState<string>();
26+
27+
const [{ wallet }] = useConnectWallet();
28+
29+
useEffect(() => {
30+
async function run() {
31+
const res = await fetch(
32+
'https://raw.githubusercontent.com/OrderlyNetwork/contract-evm-abi/main/abi/latest/Vault.json'
33+
);
34+
if (!res.ok) return;
35+
setAbi(await res.text());
36+
}
37+
run();
38+
}, []);
39+
40+
const data = [solidityPackedKeccak256(['string'], [brokerId]), wallet?.accounts[0].address ?? ''];
41+
42+
return (
43+
<Dialog.Root>
44+
<Dialog.Trigger>
45+
<Button>Show Gnosis Safe Instructions</Button>
46+
</Dialog.Trigger>
47+
48+
<Dialog.Content style={{ width: '40rem' }}>
49+
<Dialog.Title>Gnosis Safe Instructions</Dialog.Title>
50+
<Dialog.Description size="2" mb="4">
51+
Follow these instructions to register your Gnosis Safe Wallet via Orderly Network.
52+
</Dialog.Description>
53+
54+
<Tabs.Root defaultValue="safe">
55+
<Tabs.List>
56+
<Tabs.Trigger value="safe">1. Open Wallet</Tabs.Trigger>
57+
<Tabs.Trigger value="transaction">2. Create Tx</Tabs.Trigger>
58+
<Tabs.Trigger value="review-confirm">3. Review & Confirm Tx</Tabs.Trigger>
59+
<Tabs.Trigger value="txhash">4. Get Tx Hash</Tabs.Trigger>
60+
</Tabs.List>
61+
62+
<Container style={{ marginTop: '1rem' }}>
63+
<Tabs.Content value="safe">
64+
<Text>
65+
Visit{' '}
66+
<a href="https://app.safe.global/" target="_blank">
67+
Gnosis Safe
68+
</a>
69+
. Set up your wallet if not already done. Then visit the batch transaction builder
70+
as shown below.
71+
</Text>
72+
<img src="./safe.webp" alt="Gnosis Safe Instructions" style={{ maxWidth: '100%' }} />
73+
</Tabs.Content>
74+
75+
<Tabs.Content value="transaction">
76+
<Flex direction="column" gap="6">
77+
<Flex gap="2" wrap="wrap" align="center">
78+
<Strong>Enter Orderly Vault address</Strong>
79+
<IconButton
80+
size="1"
81+
variant="soft"
82+
onClick={() => {
83+
navigator.clipboard.writeText(getVaultAddress(chainId));
84+
}}
85+
>
86+
<CopyIcon height="12" />
87+
</IconButton>
88+
<Blockquote>{getVaultAddress(chainId)}</Blockquote>
89+
</Flex>
90+
<Flex gap="2" wrap="wrap" align="center">
91+
<Strong>Copy ABI</Strong>
92+
<IconButton
93+
size="1"
94+
variant="soft"
95+
onClick={() => {
96+
if (!abi) return;
97+
navigator.clipboard.writeText(abi);
98+
}}
99+
>
100+
<CopyIcon height="12" />
101+
</IconButton>
102+
<ScrollArea type="always" scrollbars="vertical" style={{ height: '8rem' }}>
103+
<Code>{abi ?? 'loading...'}</Code>
104+
</ScrollArea>
105+
</Flex>
106+
<Flex direction="column">
107+
<Strong>Select contract method</Strong> <Code>delegateSigner</Code>
108+
</Flex>
109+
<Flex gap="2" wrap="wrap" align="center">
110+
<Strong>Insert data tuple</Strong>
111+
<IconButton
112+
size="1"
113+
variant="soft"
114+
onClick={() => {
115+
navigator.clipboard.writeText(JSON.stringify(data));
116+
}}
117+
>
118+
<CopyIcon height="12" />
119+
</IconButton>
120+
<Text>This data will send your wallet address Delegate Signer EOA.</Text>
121+
<Code style={{ wordWrap: 'break-word', overflow: 'hidden' }}>
122+
{JSON.stringify(data, undefined, 2)}
123+
</Code>
124+
</Flex>
125+
126+
<Flex direction="column">
127+
<Strong>Create Batch transaction</Strong>
128+
<img
129+
src="./batch-create.webp"
130+
alt="Create Batch for Gnosis Safe"
131+
style={{ maxWidth: '100%' }}
132+
/>
133+
</Flex>
134+
</Flex>
135+
</Tabs.Content>
136+
137+
<Tabs.Content value="review-confirm">
138+
<Flex direction="column" gap="4">
139+
<Flex direction="column">
140+
<Strong>Review transaction</Strong>
141+
<Text>
142+
You can simulate the transaction in order to make sure, that it will not fail.
143+
</Text>
144+
<img
145+
src="./review-batch.webp"
146+
alt="Review Gnosis Safe batch transaction"
147+
style={{ maxWidth: '100%' }}
148+
/>
149+
</Flex>
150+
151+
<Flex direction="column">
152+
<Strong>Execute transaction</Strong>
153+
<img
154+
src="./confirm-tx.webp"
155+
alt="Confirm Gnosis Safe batch transaction"
156+
style={{ maxWidth: '100%' }}
157+
/>
158+
</Flex>
159+
</Flex>
160+
</Tabs.Content>
161+
162+
<Tabs.Content value="txhash">
163+
<Flex direction="column" gap="4">
164+
<Flex direction="column">
165+
<Strong>Receive Transaction Hash</Strong>
166+
<Text>
167+
After the multisig transaction succeeded with enough wallets signing the
168+
transaction, you need to receive the transaction hash. Copy it in order to
169+
accept the Delegate Signer link at Orderly Network.
170+
</Text>
171+
<img
172+
src="./multisig-txhash.webp"
173+
alt="Receive Gnosis Safe transaction hash"
174+
style={{ maxWidth: '100%' }}
175+
/>
176+
</Flex>
177+
178+
<Flex direction="column">
179+
<Strong>Execute transaction</Strong>
180+
<img
181+
src="./confirm-tx.webp"
182+
alt="Confirm Gnosis Safe batch transaction"
183+
style={{ maxWidth: '100%' }}
184+
/>
185+
</Flex>
186+
</Flex>
187+
</Tabs.Content>
188+
</Container>
189+
</Tabs.Root>
190+
191+
<Flex justify="end">
192+
<Dialog.Close>
193+
<Button>Ok</Button>
194+
</Dialog.Close>
195+
</Flex>
196+
</Dialog.Content>
197+
</Dialog.Root>
198+
);
199+
};

src/helpers/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,15 @@ export type DelegateSignerResponse = {
8181

8282
export async function registerDelegateSigner(
8383
wallet: WalletState,
84+
brokerId: string,
8485
chainId: string,
8586
address: string
8687
): Promise<string> {
8788
const provider = new BrowserProvider(wallet.provider);
8889
const signer = await provider.getSigner();
8990
const contract = DelegateSigner__factory.connect(exampleDelegateContract, signer);
9091
const res = await contract.delegate(getVaultAddress(chainId), {
91-
brokerHash: solidityPackedKeccak256(['string'], ['woofi_dex']),
92+
brokerHash: solidityPackedKeccak256(['string'], [brokerId]),
9293
delegateSigner: address
9394
});
9495
return res.hash;

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,11 @@
16921692
"@radix-ui/react-primitive" "1.0.3"
16931693
"@radix-ui/react-use-controllable-state" "1.0.1"
16941694

1695+
"@radix-ui/react-icons@^1.3.0":
1696+
version "1.3.0"
1697+
resolved "https://registry.yarnpkg.com/@radix-ui/react-icons/-/react-icons-1.3.0.tgz#c61af8f323d87682c5ca76b856d60c2312dbcb69"
1698+
integrity sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==
1699+
16951700
"@radix-ui/[email protected]":
16961701
version "1.0.1"
16971702
resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0"

0 commit comments

Comments
 (0)