Skip to content
This repository has been archived by the owner on Jun 15, 2024. It is now read-only.

Commit

Permalink
Solid reactivity work
Browse files Browse the repository at this point in the history
  • Loading branch information
SilentRhetoric committed Jan 21, 2024
1 parent 82f2f10 commit 0edc89d
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 29 deletions.
2 changes: 1 addition & 1 deletion examples/solid-ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"@txnlab/use-wallet-solid": "workspace:*",
"@walletconnect/modal": "^2.6.2",
"@walletconnect/sign-client": "^2.10.2",
"algosdk": "^2.6.0",
"algosdk": "^2.7.0",
"solid-js": "^1.8.7"
},
"devDependencies": {
Expand Down
38 changes: 34 additions & 4 deletions examples/solid-ts/src/Connect.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
import { NetworkId } from '@txnlab/use-wallet-js'
import { useWallet } from '@txnlab/use-wallet-solid'
import { For, Show } from 'solid-js'
import encoding from 'algosdk'

export function Connect() {
const { wallets } = useWallet()
const {
wallets,
activeNetwork,
setActiveNetwork,
activeWallet,
activeWalletId,
walletStateMap,
activeWalletAccounts,
activeWalletAddresses,
activeAccount,
activeAddress,
algodClient,
manager
} = useWallet()

return (
<div>
Expand All @@ -11,7 +26,7 @@ export function Connect() {
<div>
<h4>
{wallet.metadata.name}{' '}
<Show when={wallet.isActive} fallback="">
<Show when={wallet.isActive()} fallback="">
[active]
</Show>
</h4>
Expand All @@ -29,13 +44,13 @@ export function Connect() {
<button
type="button"
onClick={() => wallet.setActive()}
disabled={!wallet.isConnected || wallet.isActive}
disabled={!wallet.isConnected || wallet.isActive()}
>
Set Active
</button>
</div>

<Show when={wallet.isActive && wallet.accounts.length > 0}>
<Show when={wallet.isActive() && wallet.accounts.length > 0}>
<div>
<select
onChange={(event) => {
Expand All @@ -52,6 +67,21 @@ export function Connect() {
</div>
)}
</For>
<button onClick={() => setActiveNetwork(NetworkId.MAINNET)}>Set Mainnet</button>
<button onClick={() => setActiveNetwork(NetworkId.TESTNET)}>Set Testnet</button>
<p>activeNetwork: {activeNetwork()().toString()}</p>
<p>activeWalletId: {activeWalletId()}</p>
<p>activeWallet: {activeWallet()?.metadata.name}</p>
<p>activeWalletAccounts: {JSON.stringify(activeWalletAccounts())}</p>
<p>activeWalletAddresses: {activeWalletAddresses()?.join(', ')}</p>
<p>activeAccount: {JSON.stringify(activeAccount())}</p>
<p>activeAddress: {activeAddress()}</p>
<p>algodClient int encoding: {algodClient().getIntEncoding()}</p>
<button onClick={() => algodClient().setIntEncoding(encoding.IntDecoding.SAFE)}>
Set Int encoding
</button>
<p>walletStateMap: {JSON.stringify(walletStateMap())}</p>
<pre>manager: {JSON.stringify(manager(), null, 2)}</pre>
</div>
)
}
67 changes: 44 additions & 23 deletions packages/use-wallet-solid/src/useWallet.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useStore } from '@tanstack/solid-store'
import { createMemo } from 'solid-js'
import { useWalletManager } from './WalletProvider'
import type { WalletAccount, WalletId, WalletMetadata } from '@txnlab/use-wallet-js'
import type { NetworkId, WalletAccount, WalletId, WalletMetadata } from '@txnlab/use-wallet-js'
import type algosdk from 'algosdk'

export interface Wallet {
Expand All @@ -10,42 +10,46 @@ export interface Wallet {
accounts: WalletAccount[]
activeAccount: WalletAccount | null
isConnected: boolean
isActive: boolean
isActive: () => boolean
connect: () => Promise<WalletAccount[]>
disconnect: () => Promise<void>
setActive: () => void
setActiveAccount: (address: string) => void
}

export function useWallet() {
const manager = useWalletManager()
// Good
const manager = createMemo(() => useWalletManager())

const algodClient: algosdk.Algodv2 = manager.algodClient
// TODO: Not reactive when intDecoding is changed
const algodClient = createMemo(() => manager().algodClient)

const walletStateMap = useStore(manager.store, (state) => {
// Good
const walletStateMap = useStore(manager().store, (state) => {
console.log('Running walletStateMap callback...', state.wallets)
return state.wallets
})
const activeWalletId = useStore(manager.store, (state) => {

// Good
const activeWalletId = useStore(manager().store, (state) => {
console.log('Running activeWalletId callback...', state.activeWallet)
return state.activeWallet
})

// Showing promise but needs more testing
const wallets = createMemo(() => {
console.log('Recomputing wallets...')
const walletsMap = walletStateMap()
const activeId = activeWalletId()

return [...manager.wallets.values()].map((wallet): Wallet => {
const walletState = walletsMap[wallet.id]
return [...manager().wallets.values()].map((wallet) => {
const walletState = walletStateMap()[wallet.id]

const walletObject: Wallet = {
id: wallet.id,
metadata: wallet.metadata,
accounts: walletState?.accounts ?? [],
activeAccount: walletState?.activeAccount ?? null,
isConnected: !!walletState,
isActive: wallet.id === activeId,
isActive: () => wallet.id === activeWalletId(),
connect: () => wallet.connect(),
disconnect: () => wallet.disconnect(),
setActive: () => wallet.setActive(),
Expand All @@ -56,20 +60,33 @@ export function useWallet() {
})
})

const activeWallet =
activeWalletId() !== null ? manager.getWallet(activeWalletId() as WalletId) || null : null
// Good
const activeWallet = () =>
activeWalletId() !== null ? manager().getWallet(activeWalletId() as WalletId) || null : null

const activeWalletState =
const activeWalletState = () =>
activeWalletId() !== null ? walletStateMap()[activeWalletId() as WalletId] || null : null

const activeWalletAccounts = activeWalletState?.accounts ?? null
const activeWalletAddresses = activeWalletAccounts?.map((account) => account.address) ?? null
const activeAccount = activeWalletState?.activeAccount ?? null
const activeAddress = activeAccount?.address ?? null
// Good
const activeWalletAccounts = () => activeWalletState()?.accounts ?? null

// Good
const activeWalletAddresses = () =>
activeWalletAccounts()?.map((account) => account.address) ?? null

// Good
const activeAccount = () => activeWalletState()?.activeAccount ?? null

// Good
const activeAddress = () => activeAccount()?.address ?? null

// Good
const activeNetwork = () => useStore(manager().store, (state) => state.activeNetwork) // Check if this needs to be wrapped in a function so it doesn't have to called twice ()()

const activeNetwork = useStore(manager.store, (state) => state.activeNetwork)
const setActiveNetwork = manager.setActiveNetwork
// Good
const setActiveNetwork = (network: NetworkId) => manager().setActiveNetwork(network)

// TODO
const signTransactions = (
txnGroup: algosdk.Transaction[] | algosdk.Transaction[][] | Uint8Array[] | Uint8Array[][],
indexesToSign?: number[],
Expand All @@ -78,17 +95,20 @@ export function useWallet() {
if (!activeWallet) {
throw new Error('No active wallet')
}
return activeWallet.signTransactions(txnGroup, indexesToSign, returnGroup)
return activeWallet()?.signTransactions(txnGroup, indexesToSign, returnGroup)
}

// TODO
const transactionSigner = (txnGroup: algosdk.Transaction[], indexesToSign: number[]) => {
if (!activeWallet) {
throw new Error('No active wallet')
}
return activeWallet.transactionSigner(txnGroup, indexesToSign)
return activeWallet()?.transactionSigner(txnGroup, indexesToSign)
}

return {
activeWalletId,
walletStateMap,
wallets,
algodClient,
activeNetwork,
Expand All @@ -99,6 +119,7 @@ export function useWallet() {
activeAddress,
setActiveNetwork,
signTransactions,
transactionSigner
transactionSigner,
manager
}
}
2 changes: 1 addition & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0edc89d

Please sign in to comment.