Skip to content

Commit

Permalink
refactor: improving integration (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
aorumbayev authored Dec 5, 2023
1 parent ffcc6ea commit 6a38c19
Show file tree
Hide file tree
Showing 14 changed files with 364 additions and 251 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@
<a href="https://github.com/algorandfoundation/algokit-cli"><img src="https://img.shields.io/badge/Powered by-AlgoKit-black.svg" /></a>
</p>

<!-- <br />
<pre>npm i <a href="https://www.npmjs.com/package/react-use">react-use</a></pre>
<br /> -->

---

This template is a starter template for building an Algorand based dApp on React with [`subtopia-js-sdk`](https://github.com/subtopia-algo/subtopia-js) integration. The template is based on the official [`algokit-react-template`](https://github.com/algorandfoundation/algokit-react-frontend-template).

## Features

The template offers two presets, the recommended preset includes all of the above, a custom preset allows you to select which features you want to include in your project.
The template offers two presets, the recommended preset includes all of the features included in the official [algokit-react-frontend-template](https://github.com/algorandfoundation/algokit-react-frontend-template), a custom preset allows you to select which features you want to include in your project.

The full list of features includes the following:

Expand Down
6 changes: 5 additions & 1 deletion template_content/README.md.jinja
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# {{ project_name }}

This starter React project has been generated using AlgoKit. See below for default getting started instructions.
This starter Subtopia integrated dApp project has been generated using AlgoKit. See below for default getting started instructions.

- For detailed documentation on Subtopia platform refer to [Subtopia documentation](https://docs.subtopia.io).
- To learn more about Subtopia JavaScript SDK refer to [SDK documentation](https://docs.subtopia.io/integrations/javascript-sdk).
- To see other more generic examples in Next.js, React, Vue.js and Svelte refer to [Subtopia examples](https://github.com/subtopia-algo/subtopia-js-examples)

# Setup

Expand Down
36 changes: 19 additions & 17 deletions template_content/package.json.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,37 @@
"node": ">=18.0"
},
"devDependencies": {
"@types/node": "18.17.14",
"@types/react": "18.2.11",
"@types/react-dom": "18.2.4",
"@vitejs/plugin-react-swc": "3.3.2",
"autoprefixer": "10.4.14",
"@types/node": "^18.17.14",
"@types/react": "^18.2.11",
"@types/react-dom": "^18.2.4",
"@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.14",
{% if use_eslint_prettier -%}
"eslint": "8.42.0",
"eslint-config-prettier": "8.8.0",
"eslint-plugin-prettier": "5.0.0",
"@typescript-eslint/eslint-plugin": "6.5.0",
"@typescript-eslint/parser": "6.5.0",
"eslint": "^8.42.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^5.0.0",
"@typescript-eslint/eslint-plugin": "^6.5.0",
"@typescript-eslint/parser": "^6.5.0",
{% endif -%}
{% if use_tailwind -%}
"postcss": "^8.4.24",
"tailwindcss": "3.3.2",
"tailwindcss": "^3.3.2",
{% endif -%}
{% if use_jest -%}
"ts-jest": "^29.1.1",
"@types/jest": "29.5.2",
"@types/jest": "^29.5.2",
{% endif -%}
"ts-node": "10.9.1",
"typescript": "5.1.6",
"ts-node": "^10.9.1",
"typescript": "^5.1.6",
{% if use_playwright -%}
"@playwright/test": "^1.35.0",
"playwright": "^1.35.0",
{% endif -%}
"vite": "4.4.9"
"vite": "^5.0.5"
},
"dependencies": {
"@walletconnect/modal-sign-html": "^2.6.1",
"@algorandfoundation/algokit-utils": "^4.1.0",
"@algorandfoundation/algokit-utils": "^5.0.1",
"@blockshake/defly-connect": "^1.1.6",
"@daffiwallet/connect": "^1.0.3",
"@perawallet/connect": "^1.3.1",
Expand All @@ -51,7 +51,9 @@
{% endif -%}
"notistack": "^3.0.1",
"react": "^18.2.0",
"react-dom": "18.2.0",
"react-dom": "^18.2.0",
"react-use": "^17.4.2",
"subtopia-js-sdk": "^1.0.0",
"tslib": "^2.6.2"
},
"scripts": {
Expand Down
22 changes: 11 additions & 11 deletions template_content/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import algosdk from 'algosdk'
import { SnackbarProvider } from 'notistack'
import { useState } from 'react'
import ConnectWallet from './components/ConnectWallet'
import Transact from './components/Transact'
import Transact from './components/Demo'
import { getAlgodConfigFromViteEnvironment, getKmdConfigFromViteEnvironment } from './utils/network/getAlgoClientConfigs'

let providersArray: ProvidersArray
Expand Down Expand Up @@ -64,34 +64,34 @@ export default function App() {
return (
<SnackbarProvider maxSnack={3}>
<WalletProvider value={walletProviders}>
<div className="hero min-h-screen bg-teal-400">
<div className="hero-content text-center rounded-lg p-6 max-w-md bg-white mx-auto">
<div className="max-w-md">
<div className="hero min-h-screen">
<div className="hero-content text-center rounded-lg p-6 max-w-md mx-auto bg-neutral">
<div className="max-w-md ">
<h1 className="text-4xl">
Welcome to <div className="font-bold">AlgoKit 🙂</div>
Welcome to <div className="font-bold text-cyan-400">Subtopia.io</div> AlgoKit example
</h1>
<p className="py-6">
This starter has been generated using official AlgoKit React template. Refer to the resource below for next steps.
This starter has been generated using Subtopia AlgoKit template. Refer to the resources below for next steps.
</p>

<div className="grid">
<a
data-test-id="getting-started"
className="btn btn-primary m-2"
className="btn btn-primary bg-teal-800 hover:bg-teal-900 border-teal-800 m-2"
target="_blank"
href="https://github.com/algorandfoundation/algokit-cli"
href="https://github.com/subtopia-algo/subtopia-js-sdk"
>
Getting started
</a>

<div className="divider" />
<button data-test-id="connect-wallet" className="btn m-2" onClick={toggleWalletModal}>
<button data-test-id="connect-wallet" className="btn m-2 " onClick={toggleWalletModal}>
Wallet Connection
</button>

{activeAddress && (
<button data-test-id="transactions-demo" className="btn m-2" onClick={toggleDemoModal}>
Transactions Demo
<button data-test-id="transactions-demo" className="btn m-2 " onClick={toggleDemoModal}>
Subscription Integration Demo
</button>
)}
</div>
Expand Down
143 changes: 143 additions & 0 deletions template_content/src/components/Demo.tsx.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import * as algokit from '@algorandfoundation/algokit-utils'
import { useWallet } from '@txnlab/use-wallet'
import { useSnackbar } from 'notistack'
import { useEffect, useState } from 'react'
import { useAsyncRetry } from 'react-use'
import { ChainType, Duration, ProductState, SUBTOPIA_REGISTRY_ID, SubtopiaClient } from 'subtopia-js-sdk'
import { getAlgodConfigFromViteEnvironment } from '../utils/network/getAlgoClientConfigs'

interface DemoInterface {
openModal: boolean
setModalState: (value: boolean) => void
}

const DUMMY_SMI_ID = 481312144

const Demo = ({ openModal, setModalState }: DemoInterface) => {
const [loading, setLoading] = useState<boolean>(false)

const algodConfig = getAlgodConfigFromViteEnvironment()
const algodClient = algokit.getAlgoClient({
server: algodConfig.server,
port: algodConfig.port,
token: algodConfig.token,
})

const { enqueueSnackbar } = useSnackbar()
const { signer, activeAddress } = useWallet()
const [subtopiaClient, setSubtopiaClient] = useState<SubtopiaClient | null>()

const subscriptionResponse = useAsyncRetry(async () => {
if (!activeAddress || !subtopiaClient) {
return undefined
}

return await subtopiaClient.getSubscription({
algodClient: algodClient,
subscriberAddress: activeAddress,
})
}, [activeAddress])

const [subscriptionState, setSubscriptionState] = useState<ProductState | undefined>(undefined)

const handleSubscribe = async () => {
setLoading(true)

if (!signer || !activeAddress || !subtopiaClient) {
enqueueSnackbar('Please connect wallet first', { variant: 'warning' })
return
}

try {
enqueueSnackbar('Sending transaction...', { variant: 'info' })
const response = await subtopiaClient
.createSubscription({
subscriber: {
addr: activeAddress,
signer: signer,
},
duration: Duration.MONTH,
})
.catch(() => {
setLoading(false)
})

if (!response) {
throw new Error('Failed to send transaction')
}

subscriptionResponse.retry()
enqueueSnackbar(`Transaction sent: ${response.txID}`, { variant: 'success' })
} catch (e) {
enqueueSnackbar('Failed to send transaction', { variant: 'error' })
}

setLoading(false)
}

useEffect(() => {
// async method to init and set subtopia
const initSubtopiaClient = async () => {
if (!activeAddress || !signer) {
return
}

const client = await SubtopiaClient.init({
algodClient: algodClient,
productID: DUMMY_SMI_ID,
chainType: ChainType.TESTNET,
registryID: SUBTOPIA_REGISTRY_ID(ChainType.TESTNET),
creator: {
addr: activeAddress,
signer: signer,
},
})

const state = await client.getAppState()
setSubscriptionState(state)
setSubtopiaClient(client)
subscriptionResponse.retry()
}

if (!subtopiaClient) {
initSubtopiaClient()
}
})

return (
<dialog id="transact_modal" className={`modal ${openModal ? 'modal-open' : ''} bg-slate-200`}>
<form method="dialog" className="modal-box">
<h3 className="font-bold text-lg">Subscription status</h3>
<br />
{subscriptionState && (
<>
<p>{`Title: ${subscriptionState.productName} - ${subscriptionState.subscriptionName}`}</p>
<p>{`Subscription type: ${subscriptionState.subType === 0 ? 'Unlimited' : 'Time Based'}`}</p>
<p>{`Created at: ${new Date(subscriptionState.createdAt * 1000).toLocaleString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
hour: 'numeric',
minute: 'numeric',
timeZone: 'UTC',
})}`}</p>
</>
)}
<>
<p>{subscriptionResponse.value ? `Status: Subscribed` : 'Status: Not subscribed'}</p>
</>

<div className="modal-action ">
<button className="btn" onClick={() => setModalState(!openModal)}>
Close
</button>
<button data-test-id="send-algo" className={`btn lo`} onClick={handleSubscribe}>
{loading ? <span className="loading loading-spinner" /> : 'Subscribe'}
</button>
</div>
</form>
</dialog>
)
}

export default Demo
95 changes: 0 additions & 95 deletions template_content/src/components/Transact.tsx.jinja

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
},
{% if use_daisy_ui -%}
daisyui: {
themes: ['lofi'],
themes: ['dark'],
},
plugins: [require('daisyui')],
{% endif -%}
Expand Down
Loading

0 comments on commit 6a38c19

Please sign in to comment.