forked from BuidlGuidl/PWA-base
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* BuidlGuidl#1 started creating BurnerConnector. additionally edited some config * BuidlGuidl#1 changing rainbow connectors. extracted connectors to its own folder * BuidlGuidl#1 burner wallet is working * BuidlGuidl#1 preminimnarly autoconnect working. added some temp files to help check. added useBurnerSigner * BuidlGuidl#1 Finished autoconnect and burner wallet * BuidlGuidl#1 Finished autoconnect and burner wallet * BuidlGuidl#1 Finished autoconnect and burner wallet * BuidlGuidl#1 better comments * BuidlGuidl#1 better comments * BuidlGuidl#1 better comments and cleaned up structure * BuidlGuidl#1 simplified options * minor * Remove unrelated/extra stuff * Prettify with exiting rules * We want prettier to fix errors with eol without causing errors. warnings will cause prettier to autofix errors without unecessary issues. * Revert "We want prettier to fix errors with eol without causing errors. warnings will cause prettier to autofix errors without unecessary issues." This reverts commit 1282c22614aeceab6dbe5e0b84841b9ec94e6bfa. * BuidlGuidl#1 We want prettier to fix errors with eol without causing errors. warnings will cause prettier to autofix errors without unecessary issues. * We want vscode to have linting properlly work on all of the workspaces. We also want it to exclude settings files so that search and files are easier to use. * BuidlGuidl#1 fixed issue with eslint * BuidlGuidl#1 fixed nots * BuidlGuidl#1 remove unused variables * BuidlGuidl#1 removed comments * BuidlGuidl#1 fixes for bugs. TODO: write is no longer working with burner, need to find out why signer doesn't work * BuidlGuidl#1 pushed changes to get the signer to work properly * BuidlGuidl#1 removed imports * BuidlGuidl#1 changed how initial save of sk was happening * updated git ignore Co-authored-by: Carlos Sánchez <oceanrdn@gmail.com>
- Loading branch information
1 parent
ab34f5e
commit 7c28a34
Showing
23 changed files
with
700 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,5 @@ node_modules | |
!.yarn/sdks | ||
!.yarn/versions | ||
.eslintcache | ||
.vscode/** | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,12 @@ | ||
{ | ||
"extends": ["next/core-web-vitals", "plugin:prettier/recommended"], | ||
"rules": { | ||
"no-unused-vars": "error" | ||
"no-unused-vars": "error", | ||
"prettier/prettier": [ | ||
"warn", | ||
{ | ||
"endOfLine": "auto" | ||
} | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./useAutoConnect"; | ||
export * from "./useBurnerWallet"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { useEffect } from "react"; | ||
import { Connector, useAccount, useConnect } from "wagmi"; | ||
import { useEffectOnce, useLocalStorage } from "usehooks-ts"; | ||
import { burnerWalletId, defaultBurnerChainId } from "~~/web3/wagmi-burner"; | ||
|
||
export type TAutoConnect = { | ||
/** | ||
* Enable the burner wallet. If this is disabled, burner wallet is entierly disabled | ||
*/ | ||
enableBurnerWallet: boolean; | ||
/** | ||
* Auto connect: | ||
* 1. If the user was connected into a wallet before, on page reload reconnect automatically | ||
* 2. If user is not connected to any wallet: On reload, connect to burner wallet | ||
*/ | ||
autoConnect: boolean; | ||
}; | ||
|
||
const walletIdStorageKey = "scaffoldEth2.wallet"; | ||
|
||
/** | ||
* This function will get the initial connector (if any), the app will connect to | ||
* @param config | ||
* @param previousWalletId | ||
* @param connectors | ||
* @returns | ||
*/ | ||
const getInitialConnector = ( | ||
config: TAutoConnect, | ||
previousWalletId: string, | ||
connectors: Connector<any, any, any>[], | ||
): { connector: Connector | undefined; chainId?: number } | undefined => { | ||
const allowBurner = config.enableBurnerWallet; | ||
|
||
if (!previousWalletId) { | ||
// The user was not connected to a wallet | ||
if (allowBurner && config.autoConnect) { | ||
const connector = connectors.find(f => f.id === burnerWalletId); | ||
return { connector, chainId: defaultBurnerChainId }; | ||
} | ||
} else { | ||
// the user was connected to wallet | ||
if (config.autoConnect) { | ||
const connector = connectors.find(f => f.id === previousWalletId); | ||
return { connector }; | ||
} | ||
} | ||
|
||
return undefined; | ||
}; | ||
|
||
/** | ||
* Automatically connect to a wallet/connector based on config and prior wallet | ||
* @param config | ||
*/ | ||
export const useAutoConnect = (config: TAutoConnect): void => { | ||
const [walletId, setWalletId] = useLocalStorage<string>(walletIdStorageKey, ""); | ||
const connectState = useConnect(); | ||
const accountState = useAccount(); | ||
|
||
useEffect(() => { | ||
if (accountState.isConnected) { | ||
// user is connected, set walletName | ||
setWalletId(accountState.connector?.id ?? ""); | ||
} else { | ||
// user has disconnected, reset walletName | ||
setWalletId(""); | ||
} | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [accountState.isConnected, accountState.connector?.name]); | ||
|
||
useEffectOnce(() => { | ||
const initialConnector = getInitialConnector(config, walletId, connectState.connectors); | ||
|
||
if (initialConnector?.connector) { | ||
connectState.connect({ connector: initialConnector.connector, chainId: initialConnector.chainId }); | ||
} | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
import { BytesLike, ethers, Signer, Wallet } from "ethers"; | ||
import { useEffect, useCallback, useRef } from "react"; | ||
import { useProvider } from "wagmi"; | ||
import { useDebounce } from "use-debounce"; | ||
import { useLocalStorage } from "usehooks-ts"; | ||
|
||
const burnerStorageKey = "scaffoldEth2.burnerWallet.sk"; | ||
|
||
/** | ||
* Is the private key valid | ||
* @internal | ||
* @param pk | ||
* @returns | ||
*/ | ||
const isValidSk = (pk: BytesLike | undefined | null): boolean => { | ||
return pk?.length === 64 || pk?.length === 66; | ||
}; | ||
|
||
/** | ||
* If no burner is found in localstorage, we will use a new default wallet | ||
*/ | ||
const newDefaultWallet = ethers.Wallet.createRandom(); | ||
|
||
/** | ||
* Save the current burner private key from storage | ||
* Can be used outside of react. Used by the burnerConnector. | ||
* @internal | ||
* @returns | ||
*/ | ||
export const saveBurnerSK = (wallet: Wallet): void => { | ||
if (typeof window != "undefined" && window != null) { | ||
window?.localStorage?.setItem(burnerStorageKey, wallet.privateKey); | ||
} | ||
}; | ||
|
||
/** | ||
* Gets the current burner private key from storage | ||
* Can be used outside of react. Used by the burnerConnector. | ||
* @internal | ||
* @returns | ||
*/ | ||
export const loadBurnerSK = (): string => { | ||
let currentSk = ""; | ||
if (typeof window != "undefined" && window != null) { | ||
currentSk = window?.localStorage?.getItem?.(burnerStorageKey)?.replaceAll('"', "") ?? ""; | ||
} | ||
|
||
if (!!currentSk && isValidSk(currentSk)) { | ||
return currentSk; | ||
} else { | ||
saveBurnerSK(newDefaultWallet); | ||
return newDefaultWallet.privateKey; | ||
} | ||
}; | ||
|
||
/** | ||
* #### Summary | ||
* Return type of useBurnerSigner: | ||
* | ||
* ##### ✏️ Notes | ||
* - provides signer | ||
* - methods of interacting with burner signer | ||
* - methods to save and loadd signer from local storage | ||
* | ||
* @category Hooks | ||
*/ | ||
export type TBurnerSigner = { | ||
signer: Signer | undefined; | ||
account: string | undefined; | ||
/** | ||
* create a new burner signer | ||
*/ | ||
generateNewBurner: () => void; | ||
/** | ||
* explictly save burner to storage | ||
*/ | ||
saveBurner: () => void; | ||
}; | ||
|
||
/** | ||
* #### Summary | ||
* A hook that creates a burner signer/address and provides ways of interacting with | ||
* and updating the signer | ||
* | ||
* @category Hooks | ||
* | ||
* @param localProvider localhost provider | ||
* @returns IBurnerSigner | ||
*/ | ||
export const useBurnerWallet = (): TBurnerSigner => { | ||
const [burnerSk, setBurnerSk] = useLocalStorage<BytesLike>(burnerStorageKey, newDefaultWallet.privateKey); | ||
|
||
const provider = useProvider(); | ||
const walletRef = useRef<Wallet>(); | ||
const isCreatingNewBurnerRef = useRef(false); | ||
|
||
const [signer] = useDebounce(walletRef.current, 200, { | ||
trailing: true, | ||
equalityFn: (a, b) => a?.address === b?.address && a != null && b != null, | ||
}); | ||
const account = walletRef.current?.address; | ||
|
||
/** | ||
* callback to save current wallet sk | ||
*/ | ||
const saveBurner = useCallback(() => { | ||
setBurnerSk(walletRef.current?.privateKey ?? ""); | ||
}, [setBurnerSk]); | ||
|
||
/** | ||
* create a new burnerkey | ||
*/ | ||
const generateNewBurner = useCallback(() => { | ||
if (provider && !isCreatingNewBurnerRef.current) { | ||
console.log("🔑 Create new burner wallet..."); | ||
isCreatingNewBurnerRef.current = true; | ||
|
||
const wallet = Wallet.createRandom().connect(provider); | ||
setBurnerSk(() => { | ||
console.log("🔥 ...Save new burner wallet"); | ||
isCreatingNewBurnerRef.current = false; | ||
return wallet.privateKey; | ||
}); | ||
return wallet; | ||
} else { | ||
console.log("⚠ Could not create burner wallet"); | ||
} | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [provider?.network?.chainId]); | ||
|
||
/** | ||
* Load wallet with burnerSk | ||
* connect and set wallet, once we have burnerSk and valid provider | ||
*/ | ||
useEffect(() => { | ||
if (burnerSk && provider.network.chainId) { | ||
let wallet: Wallet | undefined = undefined; | ||
if (isValidSk(burnerSk)) { | ||
wallet = new ethers.Wallet(burnerSk, provider); | ||
} else { | ||
wallet = generateNewBurner?.(); | ||
} | ||
|
||
if (wallet == null) { | ||
throw "Error: Could not create burner wallet"; | ||
} | ||
walletRef.current = wallet; | ||
saveBurner?.(); | ||
} | ||
|
||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [burnerSk, provider?.network?.chainId]); | ||
|
||
return { | ||
signer, | ||
account, | ||
generateNewBurner, | ||
saveBurner, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* eslint-disable no-unused-vars */ | ||
import { useEffect } from "react"; | ||
import { usePrepareContractWrite, useContractWrite, useContractRead, chain } from "wagmi"; | ||
import { tempContract } from "~~/generated/tempContract"; | ||
|
||
// todo remove this, this is until we have contract element | ||
|
||
const testChainId = chain.hardhat.id; | ||
|
||
export const useTempTestContract = () => { | ||
const cRead = useContractRead({ | ||
addressOrName: tempContract.address, | ||
contractInterface: tempContract.abi, | ||
functionName: "purpose", | ||
chainId: testChainId, | ||
watch: true, | ||
cacheOnBlock: false, | ||
}); | ||
|
||
const cWrite = useContractWrite({ | ||
mode: "recklesslyUnprepared", | ||
addressOrName: tempContract.address, | ||
contractInterface: tempContract.abi, | ||
functionName: "setPurpose", | ||
args: "new purpose", | ||
chainId: testChainId, | ||
}); | ||
|
||
useEffect(() => { | ||
if (cRead.isSuccess) { | ||
console.log("read contract: ", cRead.data); | ||
} | ||
}, [cRead.data, cRead.isSuccess]); | ||
|
||
const onClick = () => { | ||
console.log("...attempting to write"); | ||
cWrite.write?.(); | ||
}; | ||
return { onClick }; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// todo remove this, this is until we have contract element | ||
|
||
/** | ||
* This is just for testing. you have to deploy the contract yourself and change the address. | ||
*/ | ||
export const tempContract = { | ||
address: "0x5FbDB2315678afecb367f032d93F642f64180aa3", | ||
abi: [ | ||
{ | ||
inputs: [], | ||
stateMutability: "nonpayable", | ||
type: "constructor", | ||
}, | ||
{ | ||
anonymous: false, | ||
inputs: [ | ||
{ | ||
indexed: false, | ||
internalType: "address", | ||
name: "sender", | ||
type: "address", | ||
}, | ||
{ | ||
indexed: false, | ||
internalType: "string", | ||
name: "purpose", | ||
type: "string", | ||
}, | ||
], | ||
name: "SetPurpose", | ||
type: "event", | ||
}, | ||
{ | ||
inputs: [], | ||
name: "purpose", | ||
outputs: [ | ||
{ | ||
internalType: "string", | ||
name: "", | ||
type: "string", | ||
}, | ||
], | ||
stateMutability: "view", | ||
type: "function", | ||
}, | ||
{ | ||
inputs: [ | ||
{ | ||
internalType: "string", | ||
name: "newPurpose", | ||
type: "string", | ||
}, | ||
], | ||
name: "setPurpose", | ||
outputs: [], | ||
stateMutability: "nonpayable", | ||
type: "function", | ||
}, | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
// @ts-check | ||
|
||
/** @type {import('next').NextConfig} */ | ||
const nextConfig = { | ||
reactStrictMode: true, | ||
|
Oops, something went wrong.