Skip to content

Commit 9023719

Browse files
committed
lil app
0 parents  commit 9023719

File tree

6 files changed

+5351
-0
lines changed

6 files changed

+5351
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.parcel-cache
2+
node_modules
3+
dist

package.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "gnosis-safe-adapter",
3+
"version": "1.0.0",
4+
"main": "index.js",
5+
"license": "MIT",
6+
"dependencies": {
7+
"@anders-t/ethers-ledger": "^1.0.4",
8+
"@ethersproject/contracts": "^5.7.0",
9+
"@ethersproject/hardware-wallets": "^5.7.0",
10+
"@ethersproject/providers": "^5.7.2",
11+
"@ethersproject/wallet": "^5.7.0",
12+
"@picocss/pico": "^1.5.10",
13+
"@safe-global/protocol-kit": "^1.0.1",
14+
"ethers": "5",
15+
"node-hid": "^2.1.2"
16+
},
17+
"devDependencies": {
18+
"@safe-global/safe-core-sdk-types": "^2.0.0",
19+
"assert": "^2.0.0",
20+
"os-browserify": "^0.3.0",
21+
"parcel": "^2.9.2",
22+
"path-browserify": "^1.0.0",
23+
"stream-browserify": "^3.0.0",
24+
"ts-node": "^10.9.1",
25+
"typescript": "^5.1.3"
26+
}
27+
}

src/app.css

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app.ts

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// import { LedgerSigner } from "@anders-t/ethers-ledger";
2+
// https://github.com/ethers-io/ext-signer/issues/4#issuecomment-918817511
3+
import { StaticJsonRpcProvider } from "@ethersproject/providers";
4+
import Safe, {
5+
ContractNetworksConfig,
6+
EthersAdapter,
7+
} from "@safe-global/protocol-kit";
8+
import { ethers } from "ethers";
9+
import { parseEther } from "ethers/lib/utils";
10+
11+
const contractNetworks: ContractNetworksConfig = {
12+
[999]: {
13+
multiSendAddress: "0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761",
14+
safeMasterCopyAddress: "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552",
15+
safeProxyFactoryAddress: "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2",
16+
multiSendCallOnlyAddress: "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
17+
fallbackHandlerAddress: "0x1AC114C2099aFAf5261731655Dc6c306bFcd4Dbd",
18+
createCallAddress: "0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4",
19+
signMessageLibAddress: "0xA65387F16B013cf2Af4605Ad8aA5ec25a2cbA3a2",
20+
},
21+
[7777777]: {
22+
multiSendAddress: "0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761",
23+
safeMasterCopyAddress: "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552",
24+
safeProxyFactoryAddress: "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2",
25+
multiSendCallOnlyAddress: "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
26+
fallbackHandlerAddress: "0x1AC114C2099aFAf5261731655Dc6c306bFcd4Dbd",
27+
createCallAddress: "0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4",
28+
signMessageLibAddress: "0xA65387F16B013cf2Af4605Ad8aA5ec25a2cbA3a2",
29+
},
30+
};
31+
32+
function log(text) {
33+
console.log(text);
34+
const log = document.querySelector("#log");
35+
if (!log) {
36+
return;
37+
}
38+
log.innerHTML += `<li>${text}</li>`;
39+
}
40+
41+
async function getSafeSDK(network: string, safeAddress: string) {
42+
await (window as any).ethereum.enable();
43+
44+
const provider = new StaticJsonRpcProvider(network);
45+
const ledgerSigner = new ethers.providers.Web3Provider(
46+
(window as any).ethereum
47+
).getSigner();
48+
49+
const ethAdapter = new EthersAdapter({ ethers, signerOrProvider: provider });
50+
51+
log(`ChainId: ${await ethAdapter.getChainId()}`);
52+
53+
const safeSdk: Safe = await Safe.create({
54+
ethAdapter: ethAdapter,
55+
safeAddress,
56+
contractNetworks,
57+
});
58+
// const sdk = await safeSdk.connect({ethAdapter: ethAdapter1, safeAddress })
59+
log("has safe");
60+
61+
const safeSdk2 = await safeSdk.connect({
62+
ethAdapter: new EthersAdapter({ ethers, signerOrProvider: ledgerSigner }),
63+
safeAddress,
64+
contractNetworks,
65+
});
66+
return { safeSdk, safeSdk2 };
67+
}
68+
69+
async function runit(network, operation, safeAddress, transaction) {
70+
const { safeSdk, safeSdk2 } = await getSafeSDK(network, safeAddress);
71+
72+
log("creating txn");
73+
const txn = await safeSdk.createTransaction({
74+
safeTransactionData: transaction,
75+
});
76+
77+
if (operation === "execute") {
78+
const execute = await safeSdk2.executeTransaction(txn);
79+
log(`publishing approval tx ${execute.hash}`);
80+
await execute.transactionResponse?.wait();
81+
log("executed");
82+
}
83+
if (operation === "sign") {
84+
const txHash = await safeSdk2.getTransactionHash(txn);
85+
log(`has safe tx hash ${txHash}`);
86+
87+
const approveTxResponse = await safeSdk2.approveTransactionHash(txHash);
88+
log(`publishing approval tx ${approveTxResponse.hash}`);
89+
await approveTxResponse.transactionResponse?.wait();
90+
log("published");
91+
}
92+
}
93+
94+
function app() {
95+
const signForm = document.querySelector("#sign");
96+
if (signForm) {
97+
signForm.addEventListener("submit", (evt) => {
98+
evt.preventDefault();
99+
const data = {};
100+
const formData = new FormData(signForm as any);
101+
for (const pair of formData.entries()) {
102+
data[pair[0]] = pair[1];
103+
}
104+
try {
105+
const txn = {
106+
to: data["to"],
107+
value: parseEther(data["value"] || "0").toString(),
108+
data: data["data"] || "0x",
109+
};
110+
console.log({ txn });
111+
runit(data["network"], data["operation"], data["safeAddress"], txn);
112+
} catch (e) {
113+
alert(e.toString());
114+
return;
115+
}
116+
});
117+
}
118+
const executeForm = document.querySelector("#execute");
119+
if (executeForm) {
120+
executeForm.addEventListener("submit", (evt) => {
121+
evt.preventDefault();
122+
const data = {};
123+
const formData = new FormData(executeForm as any);
124+
for (const pair of formData.entries()) {
125+
data[pair[0]] = pair[1];
126+
}
127+
// do execute
128+
execute(data["safeAddress"], data["txnHash"]);
129+
});
130+
}
131+
}
132+
133+
app();

src/index.html

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8"/>
5+
<title>zora signer</title>
6+
<script type="module" src="app.ts"></script>
7+
<link rel="stylesheet" href="./app.css">
8+
<style>
9+
input,textarea,label {
10+
display: block;
11+
}
12+
</style>
13+
</head>
14+
<body>
15+
<main class="container">
16+
<form id="sign">
17+
<h2>sign a thing // gnosis on-chain and simple</h2>
18+
<div>
19+
<strong>NETWORK:</strong>
20+
<label>ZORA TESTNET <input type="radio" name="network" value="https://testnet.rpc.zora.co/" /></label>
21+
<label>ZORA MAINNET <input type="radio" name="network" value="https://rpc.zora.co/" /></label>
22+
</div>
23+
<div>
24+
<strong>OPERATION:</strong>
25+
<label>SIGN <input type="radio" name="operation" value="sign" /></label>
26+
<label>EXECUTE <input type="radio" name="operation" value="execute" /></label>
27+
</div>
28+
<label>
29+
SAFE ADDRESS:
30+
<input type="text" name="safeAddress" />
31+
</label>
32+
<label>
33+
TO ADDRESS:
34+
<input name="to" />
35+
</label>
36+
<label>
37+
VALUE (in ether, such as 0.1):
38+
<input name="value" />
39+
</label>
40+
<label>
41+
DATA (leave blank if not executing a contract):
42+
<input name="data" />
43+
</label>
44+
<input type="submit" />
45+
</form>
46+
47+
<h5>log</h5>
48+
<ul id="log">
49+
50+
</ul>
51+
</main>
52+
</body>
53+
</html>

0 commit comments

Comments
 (0)