Skip to content

Commit

Permalink
Merge pull request #118 from onflow/feature/update-config-field
Browse files Browse the repository at this point in the history
Update dev wallet to pull configs from the flow-cli at runtime
  • Loading branch information
Greg Santos authored Jun 30, 2022
2 parents 31797fd + 50b9e98 commit 791e066
Show file tree
Hide file tree
Showing 18 changed files with 172 additions and 159 deletions.
Binary file modified bundle.zip
Binary file not shown.
14 changes: 10 additions & 4 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ import (

func main() {
srv, err := wallet.NewHTTPServer(8701, &wallet.Config{
Address: "0xf8d6e0586b0a20c7",
PrivateKey: "f8e188e8af0b8b414be59c4a1a15cc666c898fb34d94156e9b51e18bfde754a5",
PublicKey: "6e70492cb4ec2a6013e916114bc8bf6496f3335562f315e18b085c19da659bdfd88979a5904ae8bd9b4fd52a07fc759bad9551c04f289210784e7b08980516d2",
AccessNode: "http://localhost:8080",
Address: "0xf8d6e0586b0a20c7",
PrivateKey: "f8e188e8af0b8b414be59c4a1a15cc666c898fb34d94156e9b51e18bfde754a5",
PublicKey: "6e70492cb4ec2a6013e916114bc8bf6496f3335562f315e18b085c19da659bdfd88979a5904ae8bd9b4fd52a07fc759bad9551c04f289210784e7b08980516d2",
AccountKeyId: "0",
AccessNode: "http://localhost:8888",
BaseUrl: "http://localhost:8701",
ContractFungibleToken: "0xee82856bf20e2aa6",
ContractFlowToken: "0x0ae53cb6e3f42a79",
ContractFUSD: "0xf8d6e0586b0a20c7",
ContractFCLCrypto: "0xf8d6e0586b0a20c7",
})
if err != nil {
panic(err)
Expand Down
4 changes: 3 additions & 1 deletion components/AccountBalances.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import useFUSDBalance from "hooks/useFUSDBalance"
import {fundAccount} from "src/accounts"
import {formattedBalance} from "src/balance"
import {FLOW_TYPE, FUSD_TYPE, TokenTypes} from "src/constants"
import useConfig from "hooks/useConfig"
import {Label, Themed} from "theme-ui"
import {SXStyles} from "types"
import AccountSectionHeading from "./AccountSectionHeading"
Expand Down Expand Up @@ -43,12 +44,13 @@ export default function AccountBalances({
}) {
const {data: fusdBalance, refresh: refreshFUSD} = useFUSDBalance(address)
const {data: account, refresh: refreshAccount} = useAccount(address)
const config = useConfig()

const isServiceAccount =
fcl.withPrefix(address) === fcl.withPrefix(flowAccountAddress)

const fund = async (token: TokenTypes) => {
await fundAccount(address, token)
await fundAccount(config, address, token)
refreshAccount()
refreshFUSD()
}
Expand Down
6 changes: 4 additions & 2 deletions components/AccountForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import FormErrors from "components/FormErrors"
import {Field, Form, Formik} from "formik"
import {useState} from "react"
import {Account, NewAccount, newAccount, updateAccount} from "src/accounts"
import useConfig from "hooks/useConfig"
import {updateAccountSchemaClient} from "src/validate"
import {Box} from "theme-ui"
import {SXStyles} from "types"
Expand Down Expand Up @@ -44,6 +45,7 @@ export default function AccountForm({
avatarUrl: string
}) {
const [errors, setErrors] = useState<string[]>([])
const config = useConfig()

return (
<Formik
Expand All @@ -59,12 +61,12 @@ export default function AccountForm({

try {
if (account.address) {
await updateAccount(account.address, label!, scopesList)
await updateAccount(config, account.address, label!, scopesList)

setSubmitting(false)
onSubmitComplete(undefined)
} else {
const address = await newAccount(label!, scopesList)
const address = await newAccount(config, label!, scopesList)

setSubmitting(false)
onSubmitComplete(address)
Expand Down
3 changes: 3 additions & 0 deletions components/AccountsListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {chooseAccount} from "src/accountAuth"
import {formattedBalance} from "src/balance"
import {Flex, Themed} from "theme-ui"
import {SXStyles} from "types"
import useConfig from "hooks/useConfig"

const styles: SXStyles = {
accountListItem: {
Expand Down Expand Up @@ -106,6 +107,7 @@ export default function AccountsListItem({
app: {title},
},
} = connectedAppConfig
const {baseUrl} = useConfig()

const [scopes, setScopes] = useState<Set<string>>(new Set(account.scopes))
const {data: accountData} = useAccount(account.address)
Expand All @@ -116,6 +118,7 @@ export default function AccountsListItem({

const handleSelect = () => {
chooseAccount(
baseUrl,
flowAccountPrivateKey,
account,
scopes,
Expand Down
4 changes: 3 additions & 1 deletion contexts/AuthnContext.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import useConfig from "hooks/useConfig"
import useConnectedAppConfig, {
ConnectedAppConfig,
} from "hooks/useConnectedAppConfig"
Expand All @@ -20,11 +21,12 @@ export function AuthnContextProvider({children}: {children: React.ReactNode}) {
const [isInitialized, setIsInitialized] = useState<boolean>(false)
const [error, setError] = useState<string | null>(null)
const {connectedAppConfig, appScopes} = useConnectedAppConfig()
const config = useConfig()

useEffect(() => {
async function initialize() {
try {
await initializeWallet()
await initializeWallet(config)
setIsInitialized(true)
} catch (error) {
setError(`Dev wallet initialization failed: ${error}`)
Expand Down
66 changes: 55 additions & 11 deletions contexts/ConfigContext.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,57 @@
import React, {createContext, useEffect, useState} from "react"
import getConfig from "next/config"
import fclConfig from "src/fclConfig"

interface RuntimeConfig {
baseUrl: string
contractFungibleToken: string
contractFlowToken: string
contractFUSD: string
contractFCLCrypto: string
flowAccountAddress: string
flowAccountPrivateKey: string
flowAccountPublicKey: string
flowAccountKeyId: string
flowAccessNode: string
}

const {publicRuntimeConfig} = getConfig()
interface StaticConfig {
avatarUrl: string
flowInitAccountsNo: number
tokenAmountFLOW: string
tokenAmountFUSD: string
}

const defaultConfig = {
flowAccountAddress: publicRuntimeConfig.flowAccountAddress || "",
flowAccountPrivateKey: publicRuntimeConfig.flowAccountPrivateKey || "",
flowAccountPublicKey: publicRuntimeConfig.flowAccountPublicKey || "",
flowAccountKeyId: publicRuntimeConfig.flowAccountKeyId || "",
flowAccessNode: publicRuntimeConfig.flowAccessNode || "",
baseUrl: process.env.baseUrl || "",
contractFungibleToken: process.env.contractFungibleToken || "",
contractFlowToken: process.env.contractFlowToken || "",
contractFUSD: process.env.contractFUSD || "",
contractFCLCrypto: process.env.contractFCLCrypto || "",
flowAccountAddress: process.env.flowAccountAddress || "",
flowAccountPrivateKey: process.env.flowAccountPrivateKey || "",
flowAccountPublicKey: process.env.flowAccountPublicKey || "",
flowAccountKeyId: process.env.flowAccountKeyId || "",
flowAccessNode: process.env.flowAccessNode || "",
}

export const ConfigContext = createContext<RuntimeConfig>(defaultConfig)

export async function fetchConfigFromAPI(): Promise<RuntimeConfig> {
if (publicRuntimeConfig.isLocal) {
export function getStaticConfig(): StaticConfig {
// Should we set sensible defaults here?
return {
avatarUrl: process.env.avatarUrl || "",
flowInitAccountsNo: parseInt(process.env.flowInitAccountsNo || "0") || 0,
tokenAmountFLOW: process.env.tokenAmountFLOW || "",
tokenAmountFUSD: process.env.tokenAmountFUSD || "",
}
}

async function getConfig(): Promise<RuntimeConfig> {
if (process.env.isLocal) {
return defaultConfig
}

return fetch("http://localhost:8701/api/")
const result = await fetch("http://localhost:8701/api/")
.then(res => res.json())
.catch(e => {
console.log(
Expand All @@ -38,14 +63,33 @@ export async function fetchConfigFromAPI(): Promise<RuntimeConfig> {
)
return defaultConfig
})

return result
}

export function ConfigContextProvider({children}: {children: React.ReactNode}) {
const [config, setConfig] = useState<RuntimeConfig>()

useEffect(() => {
async function fetchConfig() {
const config = await fetchConfigFromAPI()
const config = await getConfig()

const {
flowAccessNode,
flowAccountAddress,
contractFungibleToken,
contractFlowToken,
contractFUSD,
} = config

fclConfig(
flowAccessNode,
flowAccountAddress,
contractFungibleToken,
contractFlowToken,
contractFUSD
)

setConfig(config)
}

Expand Down
8 changes: 4 additions & 4 deletions hooks/useAccount.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {useEffect, useState} from "react"
import {useCallback, useEffect, useState} from "react"
import {Account, getAccount} from "src/accounts"

export default function useAccount(address: string) {
const [account, setAccount] = useState<Account | null>(null)
const [error, setError] = useState(null)
const [isLoading, setIsLoading] = useState(true)

function fetchAccount() {
const fetchAccount = useCallback(() => {
getAccount(address)
.then(account => {
setAccount(account)
Expand All @@ -15,11 +15,11 @@ export default function useAccount(address: string) {
setError(error)
})
.finally(() => setIsLoading(false))
}
}, [address])

useEffect(() => {
fetchAccount()
}, [])
}, [fetchAccount])

return {
data: account,
Expand Down
12 changes: 7 additions & 5 deletions hooks/useAccounts.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import {useEffect, useState} from "react"
import {useCallback, useEffect, useState} from "react"
import {Account, getAccounts} from "src/accounts"
import useConfig from "hooks/useConfig"

export default function useAccounts() {
const [accounts, setAccounts] = useState<Array<Account>>([])
const [error, setError] = useState<any>(null)
const [isLoading, setIsLoading] = useState(true)
const {flowAccountAddress} = useConfig()

function fetchAccounts() {
getAccounts()
const fetchAccounts = useCallback(() => {
getAccounts({flowAccountAddress})
.then(accounts => {
setAccounts(accounts)
})
.catch(error => {
setError(error)
})
.finally(() => setIsLoading(false))
}
}, [flowAccountAddress])

useEffect(() => {
fetchAccounts()
}, [])
}, [fetchAccounts])

return {
data: accounts,
Expand Down
8 changes: 4 additions & 4 deletions hooks/useFUSDBalance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useEffect, useState} from "react"
import {useCallback, useEffect, useState} from "react"
import {getAccountFUSDBalance} from "src/accounts"

export function compFUSDBalanceKey(address: string) {
Expand All @@ -16,7 +16,7 @@ export default function useFUSDBalance(address: string) {
const [error, setError] = useState(null)
const [isLoading, setIsLoading] = useState(true)

function fetchFUSDBalance() {
const fetchFUSDBalance = useCallback(() => {
getAccountFUSDBalance(address)
.then(balance => {
setBalance(balance)
Expand All @@ -25,11 +25,11 @@ export default function useFUSDBalance(address: string) {
setError(error)
})
.finally(() => setIsLoading(false))
}
}, [address])

useEffect(() => {
fetchFUSDBalance()
}, [])
}, [fetchFUSDBalance])

return {
data: balance,
Expand Down
2 changes: 1 addition & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = {
})
return config
},
publicRuntimeConfig: {
env: {
isLocal: process.env.APP_ENV === "local",
flowInitAccountsNo: process.env.FLOW_INIT_ACCOUNTS,
flowAccountKeyId: process.env.FLOW_ACCOUNT_KEY_ID,
Expand Down
26 changes: 6 additions & 20 deletions pages/fcl/authn-refresh.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@ import {AuthnRefreshContextProvider} from "contexts/AuthnRefreshContext"
import useAuthnRefreshContext from "hooks/useAuthnRefreshContext"
import {refreshAuthn} from "src/accountAuth"
import Dialog from "components/Dialog"
import {fetchConfigFromAPI} from "contexts/ConfigContext"
import useConfig from "hooks/useConfig"

function AuthnRefreshDialog({
flowAccountPrivateKey,
}: {
flowAccountPrivateKey: string
}) {
function AuthnRefreshDialog() {
const data = useAuthnRefreshContext()
const {baseUrl, flowAccountPrivateKey} = useConfig()

if (data) {
const {address, keyId, scopes, nonce, appIdentifier} = data

refreshAuthn(
baseUrl,
flowAccountPrivateKey,
address,
keyId,
Expand All @@ -31,24 +29,12 @@ function AuthnRefreshDialog({
return <Dialog root={true}>Refreshing...</Dialog>
}

function AuthnRefresh({
flowAccountPrivateKey,
}: {
flowAccountPrivateKey: string
}) {
function AuthnRefresh() {
return (
<AuthnRefreshContextProvider>
<AuthnRefreshDialog flowAccountPrivateKey={flowAccountPrivateKey} />
<AuthnRefreshDialog />
</AuthnRefreshContextProvider>
)
}

AuthnRefresh.getInitialProps = async () => {
const {flowAccountPrivateKey} = await fetchConfigFromAPI()

return {
flowAccountPrivateKey: flowAccountPrivateKey,
}
}

export default AuthnRefresh
Loading

0 comments on commit 791e066

Please sign in to comment.