Skip to content

Commit 582cfdb

Browse files
authored
feat: adding use of composite actions for handling VITE_ env vars; adding util for loading env vars (#5)
* refactor: adding env var utils for algo clients * feat: adding usage of shared composite actions for placeholder vars * refactor: getting rid of usage of default algo client credentials * chore: tweaking test template code * refactor: updating name of composite action
1 parent 37eabfb commit 582cfdb

File tree

38 files changed

+416
-182
lines changed

38 files changed

+416
-182
lines changed
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
VITE_ENVIRONMENT=local
22

33
# Algod
4-
VITE_ALGOD_NODE_CONFIG_TOKEN={{ algod_token }}
5-
VITE_ALGOD_NODE_CONFIG_SERVER={{ algod_server }}
6-
VITE_ALGOD_NODE_CONFIG_PORT={{ algod_port }}
4+
VITE_ALGOD_TOKEN={{ algod_token }}
5+
VITE_ALGOD_SERVER={{ algod_server }}
6+
VITE_ALGOD_PORT={{ algod_port }}
7+
# Empty string by default for sandbox otherwise use `betanet`, `testnet` or `mainnet`
8+
VITE_ALGOD_NETWORK=""
79

810
# Indexer
911
VITE_INDEXER_TOKEN={{ indexer_token }}
1012
VITE_INDEXER_SERVER={{ indexer_server }}
1113
VITE_INDEXER_PORT={{ indexer_port }}
1214

13-
# Empty string by default for sandbox otherwise use `betanet`, `testnet` or `mainnet`
14-
VITE_ALGOD_NETWORK=
15+

template_content/src/App.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { useState } from 'react'
44
import ConnectWallet from './components/ConnectWallet'
55
import Transact from './components/Transact'
66
import { useAlgoWallet } from './hooks/useAlgoWalletProvider'
7+
import { getAlgodConfigFromViteEnvironment } from './utils/network/getAlgoClientConfigs'
78

89
export default function App() {
910
const [openWalletModal, setOpenWalletModal] = useState<boolean>(false)
@@ -18,11 +19,13 @@ export default function App() {
1819
setOpenDemoModal(!openDemoModal)
1920
}
2021

22+
const algodConfig = getAlgodConfigFromViteEnvironment()
23+
2124
const walletProviders = useAlgoWallet({
22-
nodeToken: import.meta.env.VITE_ALGOD_NODE_CONFIG_TOKEN,
23-
nodeServer: import.meta.env.VITE_ALGOD_NODE_CONFIG_SERVER,
24-
nodePort: import.meta.env.VITE_ALGOD_NODE_CONFIG_PORT,
25-
network: import.meta.env.VITE_ALGOD_NETWORK,
25+
nodeToken: String(algodConfig.token),
26+
nodeServer: algodConfig.server,
27+
nodePort: String(algodConfig.port),
28+
network: algodConfig.network,
2629
autoConnect: true,
2730
})
2831

template_content/src/components/Account.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
import { useWallet } from '@txnlab/use-wallet'
22
import { ellipseAddress } from '../utils/ellipseAddress'
3+
import { getAlgodConfigFromViteEnvironment } from '../utils/network/getAlgoClientConfigs'
34

45
const Account = () => {
56
const { activeAddress } = useWallet()
7+
const algoConfig = getAlgodConfigFromViteEnvironment()
68
return (
79
<div>
8-
<div className="text-xl">Address: {ellipseAddress(activeAddress)}</div>
10+
<a
11+
className="text-xl"
12+
target="_blank"
13+
href={`https://${algoConfig.network == 'mainnet' ? '' : `${algoConfig.network}.`}algoexplorer.io/address/${activeAddress}`}
14+
>
15+
Address: {ellipseAddress(activeAddress)}
16+
</a>
17+
<div className="text-xl">Network: {algoConfig.network}</div>
918
</div>
1019
)
1120
}

template_content/src/components/Transact.tsx.jinja

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { DEFAULT_NODE_BASEURL, DEFAULT_NODE_PORT, DEFAULT_NODE_TOKEN, useWallet } from '@txnlab/use-wallet'
21
import * as algokit from '@algorandfoundation/algokit-utils'
3-
import { useState } from 'react'
2+
import { useWallet } from '@txnlab/use-wallet'
43
import algosdk from 'algosdk'
54
import { useSnackbar } from 'notistack'
5+
import { useState } from 'react'
6+
import { getAlgodConfigFromViteEnvironment } from '../utils/network/getAlgoClientConfigs'
67

78
interface TransactInterface {
89
openModal: boolean
@@ -13,10 +14,11 @@ const Transact = ({ openModal, setModalState }: TransactInterface) => {
1314
const [loading, setLoading] = useState<boolean>(false)
1415
const [receiverAddress, setReceiverAddress] = useState<string>('')
1516

17+
const algodConfig = getAlgodConfigFromViteEnvironment()
1618
const algodClient = algokit.getAlgoClient({
17-
server: import.meta.env.VITE_ALGOD_NODE_CONFIG_SERVER ?? DEFAULT_NODE_BASEURL,
18-
port: import.meta.env.VITE_ALGOD_NODE_CONFIG_PORT ?? DEFAULT_NODE_PORT,
19-
token: import.meta.env.VITE_ALGOD_NODE_CONFIG_TOKEN ?? DEFAULT_NODE_TOKEN,
19+
server: algodConfig.server,
20+
port: algodConfig.port,
21+
token: algodConfig.token,
2022
})
2123

2224
const { enqueueSnackbar } = useSnackbar()

template_content/src/hooks/useAlgoWalletProvider.ts

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,6 @@
11
import { DeflyWalletConnect } from '@blockshake/defly-connect'
22
import { PeraWalletConnect } from '@perawallet/connect'
3-
import {
4-
AlgodClientOptions,
5-
DEFAULT_NETWORK,
6-
DEFAULT_NODE_BASEURL,
7-
DEFAULT_NODE_PORT,
8-
DEFAULT_NODE_TOKEN,
9-
defly,
10-
exodus,
11-
kmd,
12-
pera,
13-
PROVIDER_ID,
14-
reconnectProviders,
15-
WalletClient,
16-
} from '@txnlab/use-wallet'
3+
import { AlgodClientOptions, defly, exodus, kmd, pera, PROVIDER_ID, reconnectProviders, WalletClient } from '@txnlab/use-wallet'
174
import algosdk from 'algosdk'
185
import { useEffect } from 'react'
196

@@ -37,12 +24,9 @@ if (import.meta.env.VITE_ENVIRONMENT === 'local') {
3724
const walletProviders: SupportedProviders = {}
3825

3926
export function useAlgoWallet(context: { autoConnect: boolean; network: string; nodeServer: string; nodePort: string; nodeToken: string }) {
40-
const algodOptions = [
41-
context.nodeToken ?? DEFAULT_NODE_TOKEN,
42-
context.nodeServer ?? DEFAULT_NODE_BASEURL,
43-
context.nodePort ?? DEFAULT_NODE_PORT,
44-
] as AlgodClientOptions
45-
const network = context.network ?? DEFAULT_NETWORK
27+
const algodOptions = [context.nodeToken, context.nodeServer, context.nodePort] as AlgodClientOptions
28+
29+
const network = context.network
4630

4731
providerIds.forEach((id) => {
4832
if (id in walletProviders) {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { AlgoClientConfig } from '@algorandfoundation/algokit-utils/types/network-client'
2+
import type { TokenHeader } from 'algosdk/dist/types/client/urlTokenBaseHTTPClient'
3+
4+
export interface AlgoViteClientConfig extends AlgoClientConfig {
5+
/** Base URL of the server e.g. http://localhost, https://testnet-api.algonode.cloud/, etc. */
6+
server: string
7+
/** The port to use e.g. 4001, 443, etc. */
8+
port: string | number
9+
/** The token to use for API authentication (or undefined if none needed) - can be a string, or an object with the header key => value */
10+
token: string | TokenHeader
11+
/** String representing current Algorand Network type (testnet/mainnet and etc) */
12+
network: string
13+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { AlgoViteClientConfig } from '../../interfaces/network'
2+
3+
export function getAlgodConfigFromViteEnvironment(): AlgoViteClientConfig {
4+
if (!import.meta.env.VITE_ALGOD_SERVER) {
5+
throw new Error('Attempt to get default algod configuration without specifying VITE_ALGOD_SERVER in the environment variables')
6+
}
7+
8+
return {
9+
server: import.meta.env.VITE_ALGOD_SERVER,
10+
port: import.meta.env.VITE_ALGOD_PORT,
11+
token: import.meta.env.VITE_ALGOD_TOKEN,
12+
network: import.meta.env.VITE_ALGOD_NETWORK,
13+
}
14+
}
15+
16+
export function getIndexerConfigFromVercelEnvironment(): AlgoViteClientConfig {
17+
if (!import.meta.env.VITE_INDEXER_SERVER) {
18+
throw new Error('Attempt to get default algod configuration without specifying VITE_INDEXER_SERVER in the environment variables')
19+
}
20+
21+
return {
22+
server: import.meta.env.VITE_INDEXER_SERVER,
23+
port: import.meta.env.VITE_INDEXER_PORT,
24+
token: import.meta.env.VITE_INDEXER_TOKEN,
25+
network: import.meta.env.VITE_ALGOD_NETWORK,
26+
}
27+
}

template_content/src/vite-env.d.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
interface ImportMetaEnv {
44
readonly VITE_ENVIRONMENT: string
5-
readonly VITE_ALGOD_NODE_CONFIG_TOKEN: string
6-
readonly VITE_ALGOD_NODE_CONFIG_SERVER: string
7-
readonly VITE_ALGOD_NODE_CONFIG_PORT: string
5+
6+
readonly VITE_ALGOD_TOKEN: string
7+
readonly VITE_ALGOD_SERVER: string
8+
readonly VITE_ALGOD_PORT: string
9+
readonly VITE_ALGOD_NETWORK: string
810

911
readonly VITE_INDEXER_TOKEN: string
1012
readonly VITE_INDEXER_SERVER: string
1113
readonly VITE_INDEXER_PORT: string
12-
13-
readonly VITE_ALGOD_NETWORK: string
1414
}
1515

1616
interface ImportMeta {

template_content/{% if use_github_actions %}.github{% endif %}/workflows/checks.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ jobs:
3434
- name: Run unit tests
3535
run: npm run test
3636

37+
- name: Create placeholder .env file
38+
if: ${{ inputs.run-build }}
39+
uses: makerxstudio/shared-config/.github/actions/env-to-placeholders@main
40+
with:
41+
env-output-path: './.env'
42+
env-template-path: './.env.template'
43+
env-variable-prefix: VITE_
44+
3745
- name: Build
3846
if: ${{ inputs.run-build }}
3947
run: npm run build

template_content/{% if use_github_actions %}.github{% endif %}/workflows/{% if cloud_provider != none %}release.yaml{% endif %}.jinja

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,34 @@ jobs:
3838
{% raw %}
3939
- name: Install Vercel CLI
4040
run: npm install --global vercel@latest
41+
4142
- name: Pull Vercel Environment Information
4243
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
44+
45+
- name: Create placeholder .env file
46+
uses: makerxstudio/shared-config/.github/actions/env-to-placeholders@main
47+
with:
48+
env-output-path: './.env'
49+
env-template-path: './.env.template'
50+
env-variable-prefix: VITE_
51+
4352
- name: Build Project Artifacts
4453
run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
54+
55+
- name: Replace template vars
56+
uses: makerxstudio/shared-config/.github/actions/placeholder-transforms@main
57+
with:
58+
app-artifact-path: './.vercel/output'
59+
static-site-transforms: |-
60+
VITE_ALGOD_TOKEN:${{ secrets.VITE_ALGOD_TOKEN }}
61+
VITE_ALGOD_SERVER:${{ vars.VITE_ALGOD_SERVER }}
62+
VITE_ALGOD_PORT:${{ vars.VITE_ALGOD_PORT }}
63+
VITE_ALGOD_NETWORK:${{ vars.VITE_ALGOD_NETWORK }}
64+
VITE_INDEXER_SERVER:${{ vars.VITE_INDEXER_SERVER }}
65+
VITE_INDEXER_PORT:${{ vars.VITE_INDEXER_PORT }}
66+
VITE_INDEXER_TOKEN:${{ secrets.VITE_INDEXER_TOKEN }}
67+
VITE_ENVIRONMENT:${{ vars.VITE_ENVIRONMENT }}
68+
4569
- name: Deploy Project Artifacts to Vercel
4670
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
4771
# Set your vercel project env variables on your site instance on https://vercel.com/dashboard
@@ -54,6 +78,20 @@ jobs:
5478
name: dist
5579
path: dist
5680

81+
- name: Replace template vars
82+
uses: makerxstudio/shared-config/.github/actions/placeholder-transforms@main
83+
with:
84+
app-artifact-path: './dist'
85+
static-site-transforms: |-
86+
VITE_ALGOD_TOKEN:${{ secrets.VITE_ALGOD_TOKEN }}
87+
VITE_ALGOD_SERVER:${{ vars.VITE_ALGOD_SERVER }}
88+
VITE_ALGOD_PORT:${{ vars.VITE_ALGOD_PORT }}
89+
VITE_ALGOD_NETWORK:${{ vars.VITE_ALGOD_NETWORK }}
90+
VITE_INDEXER_SERVER:${{ vars.VITE_INDEXER_SERVER }}
91+
VITE_INDEXER_PORT:${{ vars.VITE_INDEXER_PORT }}
92+
VITE_INDEXER_TOKEN:${{ secrets.VITE_INDEXER_TOKEN }}
93+
VITE_ENVIRONMENT:${{ vars.VITE_ENVIRONMENT }}
94+
5795
- name: Install netlify cli
5896
run: npm i netlify-cli
5997

@@ -62,16 +100,5 @@ jobs:
62100
env:
63101
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
64102
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
65-
66-
# Pass your environment variables here, e.g.,
67-
# VITE_ALGOD_NODE_CONFIG_TOKEN: ${{ secrets.VITE_ALGOD_NODE_CONFIG_TOKEN }}
68-
# VITE_ALGOD_NODE_CONFIG_SERVER: ${{ secrets.VITE_ALGOD_NODE_CONFIG_SERVER }}
69-
# VITE_ALGOD_NODE_CONFIG_PORT: ${{ secrets.VITE_ALGOD_NODE_CONFIG_PORT }}
70-
71-
# VITE_INDEXER_TOKEN: ${{ secrets.VITE_INDEXER_TOKEN }}
72-
# VITE_INDEXER_SERVER: ${{ secrets.VITE_INDEXER_SERVER }}
73-
# VITE_INDEXER_PORT: ${{ secrets.VITE_INDEXER_PORT }}
74-
75-
# VITE_ALGOD_NETWORK: ${{ secrets.VITE_ALGOD_NETWORK }}
76103
{% endraw %}
77104
{%- endif %}

0 commit comments

Comments
 (0)