Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Refactor table forms #878

Draft
wants to merge 29 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
9c1bfcf
Reworks Privy config to allow for eoas without making smart wallets. …
jonathanprozzi Oct 23, 2024
be9cb3f
Testing a poc for detecting smart wallet and configuring appropriate …
jonathanprozzi Oct 23, 2024
06f3e79
Checkpoint: Calls working in playground
jonathanprozzi Oct 23, 2024
fbd26e5
Some cleanup of unused args and imports
jonathanprozzi Oct 23, 2024
0ac882d
Uses sendTransaction now for both
jonathanprozzi Oct 23, 2024
2ff7653
Add useUserWallet hook
0xjojikun Oct 23, 2024
c94ad67
squash
0xjojikun Oct 23, 2024
a26e899
Add hasSmartWallet util
0xjojikun Oct 23, 2024
fd08412
Cleanup environments setup & add chains util
0xjojikun Oct 23, 2024
2da0936
Cleans up playground -- stashing and trying to reset other local issues
jonathanprozzi Oct 23, 2024
a984ad8
Begins adding in the useUserWallet hook to support EOAs and Smart Wal…
jonathanprozzi Oct 23, 2024
4a1e91e
Updates the flow to support EOAs and smart wallets similar to in play…
jonathanprozzi Oct 23, 2024
ae4ad10
Quick update to env example
jonathanprozzi Oct 23, 2024
38b82d1
Updates our env and continues to streamline and also updates the rend…
jonathanprozzi Oct 23, 2024
27dcf68
Updates after running lint --fix at the root
jonathanprozzi Oct 23, 2024
b4de4ea
fix pnpm-lock and linting
0xjojikun Oct 23, 2024
5702a0d
Adds missing env var from the Dockerfile
jonathanprozzi Oct 24, 2024
190fa42
remove dependency @wagmi/core
0xjojikun Oct 24, 2024
4031a95
Bump @privy-io/react-auth to 1.92.2
0xjojikun Oct 24, 2024
a8bf22a
Add walletconnect to noExternal
0xjojikun Oct 24, 2024
684d286
Tests -- adds wagmi and walleconnect package to noExternal in vite co…
jonathanprozzi Oct 24, 2024
0830471
Adds pnpm install back in
jonathanprozzi Oct 24, 2024
95b6af8
Checkpoint -- these changes build
jonathanprozzi Oct 24, 2024
36aaa1b
Moves everything Privy related to client and removes all other instan…
jonathanprozzi Oct 24, 2024
11a92f5
Adds new env vars to dockerfile and render
jonathanprozzi Oct 24, 2024
ed02ae8
Adds playground back in
jonathanprozzi Oct 24, 2024
9a16093
Lint fix and re-adds playground
jonathanprozzi Oct 24, 2024
03ba1ed
Checkpoint
0xjojikun Oct 25, 2024
4e87d5f
Checkpoint
0xjojikun Oct 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 3 additions & 15 deletions apps/data-populator/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,15 @@
PINATA_JWT_KEY=
PINATA_GATEWAY_KEY=
IPFS_GATEWAY=
ATTEST_CONTRACT_ADDRESS=0x430BbF52503Bd4801E51182f4cB9f8F534225DE5 # set to multivault b/c attestoor not working w/ triples
ATTEST_CONTRACT_ADDRESS_DEV=0x1A6950807E33d5bC9975067e6D6b5Ea4cD661665
MULTIVAULT_CONTRACT_ADDRESS=0x430BbF52503Bd4801E51182f4cB9f8F534225DE5
MULTIVAULT_CONTRACT_ADDRESS_DEV=0x1A6950807E33d5bC9975067e6D6b5Ea4cD661665
PRIVATE_KEY=
PRIVATE_KEY_DEV=
EVM_RPC=
EVM_RPC_DEV=
ADDITIONAL_STAKE_ATOM=100000000000 # 1e-7 ether (1^12)
ADDITIONAL_STAKE_TRIPLE=100000000000 # 1e-7 ether (1^12)
# SUPABASE
SUPABASE_URL=
SUPABASE_KEY=
# ENVIRONMENT
ENVIRONMENT=dev
VITE_DEPLOY_ENV=development
# MULTIVAULT ADDRESSES
MULTIVAULT_ADDRESS_BASE_SEPOLIA=
MULTIVAULT_ADDRESS_BASE_MAINNET=
# ALCHEMY API KEYS AND RPC URLS (LOCAL)
ALCHEMY_BASE_SEPOLIA_RPC_URL=
ALCHEMY_BASE_RPC_URL=
# CLOUDINARY
CLOUDINARY_CLOUD_NAME=
CLOUDINARY_API_KEY=
Expand All @@ -32,5 +19,6 @@ CLOUDINARY_API_SECRET=
PRIVY_APP_ID=
PRIVY_AUTH_URL=
PRIVY_APP_SECRET=
ORIGIN_URL=
SESSION_SECRET=
PRIVY_VERIFICATION_KEY=
VITE_ORIGIN_URL=
VITE_ALCHEMY_API_KEY=
36 changes: 10 additions & 26 deletions apps/data-populator/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,46 @@ FROM docker.io/node:lts-alpine as base
ARG PINATA_JWT_KEY
ARG PINATA_GATEWAY_KEY
ARG IPFS_GATEWAY
ARG ATTEST_CONTRACT_ADDRESS
ARG ATTEST_CONTRACT_ADDRESS_DEV
ARG MULTIVAULT_CONTRACT_ADDRESS
ARG MULTIVAULT_CONTRACT_ADDRESS_DEV
ARG PRIVATE_KEY
ARG PRIVATE_KEY_DEV
ARG EVM_RPC
ARG EVM_RPC_DEV
ARG ADDITIONAL_STAKE_ATOM
ARG ADDITIONAL_STAKE_TRIPLE
ARG CLOUDINARY_CLOUD_NAME
ARG CLOUDINARY_API_KEY
ARG CLOUDINARY_API_SECRET
ARG SUPABASE_URL
ARG SUPABASE_KEY
ARG ENVIRONMENT
ARG VITE_DEPLOY_ENV
ARG MULTIVAULT_ADDRESS_BASE_SEPOLIA
ARG MULTIVAULT_ADDRESS_BASE_MAINNET
ARG ALCHEMY_BASE_SEPOLIA_RPC_URL
ARG ALCHEMY_BASE_RPC_URL
ARG SESSION_SECRET
ARG VITE_ALCHEMY_API_KEY
ARG ALCHEMY_API_KEY
ARG VITE_ORIGIN_URL
ARG ORIGIN_URL
ARG PRIVY_APP_ID
ARG PRIVY_AUTH_URL
ARG PRIVY_APP_SECRET
ARG PRIVY_VERIFICATION_KEY

ENV PINATA_JWT_KEY=${PINATA_JWT_KEY}
ENV PINATA_GATEWAY_KEY=${PINATA_GATEWAY_KEY}
ENV IPFS_GATEWAY=${IPFS_GATEWAY}
ENV ATTEST_CONTRACT_ADDRESS=${ATTEST_CONTRACT_ADDRESS}
ENV ATTEST_CONTRACT_ADDRESS_DEV=${ATTEST_CONTRACT_ADDRESS_DEV}
ENV MULTIVAULT_CONTRACT_ADDRESS=${MULTIVAULT_CONTRACT_ADDRESS}
ENV MULTIVAULT_CONTRACT_ADDRESS_DEV=${MULTIVAULT_CONTRACT_ADDRESS_DEV}
ENV PRIVATE_KEY=${PRIVATE_KEY}
ENV PRIVATE_KEY_DEV=${PRIVATE_KEY_DEV}
ENV EVM_RPC=${EVM_RPC}
ENV EVM_RPC_DEV=${EVM_RPC_DEV}
ENV ADDITIONAL_STAKE_ATOM=${ADDITIONAL_STAKE_ATOM}
ENV ADDITIONAL_STAKE_TRIPLE=${ADDITIONAL_STAKE_TRIPLE}
ENV CLOUDINARY_CLOUD_NAME=${CLOUDINARY_CLOUD_NAME}
ENV CLOUDINARY_API_KEY=${CLOUDINARY_API_KEY}
ENV CLOUDINARY_API_SECRET=${CLOUDINARY_API_SECRET}
ENV SUPABASE_URL=${SUPABASE_URL}
ENV SUPABASE_KEY=${SUPABASE_KEY}
ENV ENVIRONMENT=${ENVIRONMENT}
ENV VITE_DEPLOY_ENV=${VITE_DEPLOY_ENV}
ENV MULTIVAULT_ADDRESS_BASE_SEPOLIA=${MULTIVAULT_ADDRESS_BASE_SEPOLIA}
ENV MULTIVAULT_ADDRESS_BASE_MAINNET=${MULTIVAULT_ADDRESS_BASE_MAINNET}
ENV ALCHEMY_BASE_SEPOLIA_RPC_URL=${ALCHEMY_BASE_SEPOLIA_RPC_URL}
ENV ALCHEMY_BASE_RPC_URL=${ALCHEMY_BASE_RPC_URL}
ENV SESSION_SECRET=${SESSION_SECRET}
ENV VITE_ALCHEMY_API_KEY=${VITE_ALCHEMY_API_KEY}
ENV ALCHEMY_API_KEY=${ALCHEMY_API_KEY}
ENV VITE_ORIGIN_URL=${VITE_ORIGIN_URL}
ENV ORIGIN_URL=${ORIGIN_URL}
ENV PRIVY_APP_ID=${PRIVY_APP_ID}
ENV PRIVY_AUTH_URL=${PRIVY_AUTH_URL}
ENV PRIVY_APP_SECRET=${PRIVY_APP_SECRET}
ENV PRIVY_AUTH_URL=${PRIVY_AUTH_URL}
ENV PRIVY_VERIFICATION_KEY=${PRIVY_VERIFICATION_KEY}

WORKDIR /app

Expand Down Expand Up @@ -90,7 +74,7 @@ FROM base as build
RUN npm install -g nx@latest

# Install dependencies
RUN pnpm install --no-frozen-lockfile
RUN pnpm install

# Build the data-populator app
RUN pnpm run data-populator:build
Expand Down
25 changes: 13 additions & 12 deletions apps/data-populator/app/.client/providers.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
import { alchemyRpcUrlMap } from '@lib/utils/chains'
import { wagmiConfig } from '@lib/utils/wagmi'
import type { PrivyClientConfig } from '@privy-io/react-auth'
import { addRpcUrlOverrideToChain, PrivyProvider } from '@privy-io/react-auth'
import { SmartWalletsProvider } from '@privy-io/react-auth/smart-wallets'
import { WagmiProvider } from '@privy-io/wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { baseSepolia } from 'viem/chains'
import { base, baseSepolia } from 'viem/chains'

const queryClient = new QueryClient()

// uses pattern to ensure this is set. we'll need this for the base override as well
const alchemyBaseSepoliaRpcUrl =
typeof window !== 'undefined'
? window.ENV?.ALCHEMY_BASE_SEPOLIA_RPC_URL
: process.env.ALCHEMY_BASE_SEPOLIA_RPC_URL

const baseSepoliaOverride = addRpcUrlOverrideToChain(
baseSepolia,
alchemyBaseSepoliaRpcUrl,
alchemyRpcUrlMap(baseSepolia.id),
)

const baseMainnetOverride = addRpcUrlOverrideToChain(
base,
alchemyRpcUrlMap(base.id),
)

const privyConfig: PrivyClientConfig = {
embeddedWallets: {
createOnLogin: 'all-users',
createOnLogin: 'users-without-wallets',
requireUserPasswordOnCreate: false,
noPromptOnSignature: false,
},
loginMethods: ['wallet', 'email', 'sms', 'discord', 'twitter', 'github'],
loginMethods: ['wallet', 'email', 'sms', 'github'],
appearance: {
theme: 'dark',
showWalletLoginFirst: true,
},
defaultChain: baseSepolia,
supportedChains: [baseSepoliaOverride],
defaultChain:
import.meta.env.VITE_DEPLOY_ENV === 'development' ? baseSepolia : base,
supportedChains: [baseSepoliaOverride, baseMainnetOverride],
}

export default function Providers({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import { toast } from '@0xintuition/1ui'

import type { BatchAtomsRequest, PinDataResult } from '@lib/services/populate'
import logger from '@lib/utils/logger'
import { useSmartWallets } from '@privy-io/react-auth/smart-wallets'
import { useFetcher } from '@remix-run/react'
import {
InitiateActionData,
LogTxActionData,
PublishActionData,
} from '@routes/app+'
import { Thing, WithContext } from 'schema-dts'
import { useSendTransaction } from 'wagmi'

import { useUserClient } from './useUserWallet'

type State = {
requestHash: string
Expand Down Expand Up @@ -114,7 +116,10 @@ export function useBatchCreateAtom() {
const publishFetcher = useFetcher({ key: 'publish-atoms' })
const logTxFetcher = useFetcher({ key: 'log-tx-hash-and-verify-atoms' })

const { client } = useSmartWallets()
const { smartWalletClient, publicClient, address, isSmartWalletUser, ready } =
useUserClient()

const { sendTransaction } = useSendTransaction()

const initiateBatchRequest = useCallback(
(selectedRows: number[], csvData: string[][]) => {
Expand All @@ -129,6 +134,7 @@ export function useBatchCreateAtom() {
console.error('Invalid or empty csvData')
return
}

console.log('Initiating batch request')
console.log('Selected Rows:', selectedRows)
console.log('CSV Data:', csvData)
Expand All @@ -151,7 +157,6 @@ export function useBatchCreateAtom() {
return
}
console.log('Publishing atoms')
console.log('msgSender', client?.account)

setIsProcessing(true)
publishFetcher.submit(
Expand All @@ -165,26 +170,73 @@ export function useBatchCreateAtom() {
}, [publishFetcher, state.requestHash, state.calls])

const sendBatchTx = useCallback(async () => {
if (!client || !state.calls.length || isProcessing) {
return
}
console.log('Sending batch transaction')
dispatch({ type: 'SET_STEP', payload: 'sending' })
setIsProcessing(true)

if (!ready) {
console.error('No active client or address found')
return
}

try {
const hash = await client.sendTransaction({
account: client.account,
calls: state.calls.map((call) => ({
to: call.to as `0x${string}`,
data: call.data as `0x${string}`,
value: BigInt(call.value),
})),
})
dispatch({ type: 'SET_TX_HASH', payload: hash })
let txHash
if (isSmartWalletUser) {
logger('[start] smart wallet sending batch tx')
txHash = await smartWalletClient.sendTransaction({
account: smartWalletClient.account,
calls: state.calls.map((call) => ({
to: call.to as `0x${string}`,
data: call.data as `0x${string}`,
value: BigInt(call.value),
})),
})
logger('[end] smart wallet batch txHash', txHash)
} else {
logger('isSmartWalletUser', isSmartWalletUser)
logger('[start] non-smart wallet atom tx calls', state.calls)

const confirmedHashes: `0x${string}`[] = []

for (const tx of state.calls) {
await new Promise<void>((resolve, reject) => {
sendTransaction(
{
to: tx.to as `0x${string}`,
data: tx.data as `0x${string}`,
value: BigInt(tx.value),
},
{
onSuccess: async (hash) => {
try {
const receipt =
await publicClient?.waitForTransactionReceipt({ hash })
confirmedHashes.push(receipt?.transactionHash ?? hash)
logger(
`Transaction confirmed: ${receipt?.transactionHash ?? hash}`,
)
resolve()
} catch (confirmError) {
console.error('Error confirming transaction:', confirmError)
reject(confirmError)
}
},
onError: (error) => {
console.error('Error sending transaction:', error)
reject(error)
},
},
)
})
}
// Use the last transaction hash as the overall txHash
txHash = confirmedHashes[confirmedHashes.length - 1]
}

dispatch({ type: 'SET_TX_HASH', payload: txHash })
dispatch({ type: 'SET_STEP', payload: 'logging' })
logger('txHash', hash)
return hash
logger('txHash', txHash)
return txHash
} catch (error) {
console.error('Error sending batch transaction:', error)
dispatch({ type: 'SET_STEP', payload: 'idle' })
Expand All @@ -195,13 +247,20 @@ export function useBatchCreateAtom() {

dispatch({
type: 'SET_ERROR',
error: error instanceof Error ? error.message : String(error),
error: errorMessage,
})
dispatch({ type: 'SET_STEP', payload: 'error' })
toast.error(errorMessage)
} finally {
setIsProcessing(false)
}
}, [client, state.calls, isProcessing])
}, [
smartWalletClient,
publicClient,
isSmartWalletUser,
state.calls,
sendTransaction,
])

const logTxHash = useCallback(() => {
if (!state.txHash || !state.requestHash || isProcessing) {
Expand All @@ -218,12 +277,22 @@ export function useBatchCreateAtom() {
requestHash: state.requestHash,
filteredCIDs: JSON.stringify(state.newCIDs),
filteredData: JSON.stringify(state.filteredData),
msgSender: client?.account.address as `0x${string}`,
msgSender: isSmartWalletUser
? (smartWalletClient?.account.address as `0x${string}`)
: (address as `0x${string}`),
oldAtomCIDs: JSON.stringify(state.existingCIDs),
},
{ method: 'post' },
)
}, [logTxFetcher, state.txHash, state.requestHash])
}, [
logTxFetcher,
state.txHash,
state.requestHash,
isSmartWalletUser,
smartWalletClient,
address,
isProcessing,
])

useEffect(() => {
if (
Expand Down Expand Up @@ -364,6 +433,9 @@ export function useBatchCreateAtom() {
return {
...state,
initiateBatchRequest,
publishAtoms,
sendBatchTx,
logTxHash,
isLoading:
state.step !== 'idle' &&
state.step !== 'complete' &&
Expand Down
Loading
Loading