Merge branch 'wallets'
This commit is contained in:
commit
b38452e02c
@ -11,6 +11,7 @@
|
|||||||
"@walletconnect/client": "experimental",
|
"@walletconnect/client": "experimental",
|
||||||
"@walletconnect/utils": "experimental",
|
"@walletconnect/utils": "experimental",
|
||||||
"@json-rpc-tools/utils": "1.7.6",
|
"@json-rpc-tools/utils": "1.7.6",
|
||||||
|
"@solana/web3.js": "1.36.0",
|
||||||
"@nextui-org/react": "1.0.2-beta.4",
|
"@nextui-org/react": "1.0.2-beta.4",
|
||||||
"mnemonic-keyring": "1.4.0",
|
"mnemonic-keyring": "1.4.0",
|
||||||
"next": "12.1.0",
|
"next": "12.1.0",
|
||||||
@ -18,7 +19,7 @@
|
|||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"react-qr-reader-es6": "2.2.1-2",
|
"react-qr-reader-es6": "2.2.1-2",
|
||||||
"framer-motion": "6.2.8",
|
"framer-motion": "6.2.8",
|
||||||
"ethers": "5.5.4",
|
"ethers": "5.6.0",
|
||||||
"valtio": "1.3.1",
|
"valtio": "1.3.1",
|
||||||
"react-code-blocks": "0.0.9-0",
|
"react-code-blocks": "0.0.9-0",
|
||||||
"@cosmjs/proto-signing": "0.27.1",
|
"@cosmjs/proto-signing": "0.27.1",
|
||||||
@ -28,8 +29,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@walletconnect/types": "experimental",
|
"@walletconnect/types": "experimental",
|
||||||
"@types/node": "17.0.21",
|
"@types/node": "17.0.21",
|
||||||
"@types/react": "17.0.39",
|
"@types/react": "17.0.40",
|
||||||
"eslint": "8.10.0",
|
"eslint": "8.11.0",
|
||||||
"eslint-config-next": "12.1.0",
|
"eslint-config-next": "12.1.0",
|
||||||
"eslint-config-prettier": "8.5.0",
|
"eslint-config-prettier": "8.5.0",
|
||||||
"prettier": "2.5.1",
|
"prettier": "2.5.1",
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
@ -1,6 +1,7 @@
|
|||||||
import SettingsStore from '@/store/SettingsStore'
|
import SettingsStore from '@/store/SettingsStore'
|
||||||
import { cosmosAddresses } from '@/utils/CosmosWalletUtil'
|
import { cosmosAddresses } from '@/utils/CosmosWalletUtil'
|
||||||
import { eip155Addresses } from '@/utils/EIP155WalletUtil'
|
import { eip155Addresses } from '@/utils/EIP155WalletUtil'
|
||||||
|
import { solanaAddresses } from '@/utils/SolanaWalletUtil'
|
||||||
import { useSnapshot } from 'valtio'
|
import { useSnapshot } from 'valtio'
|
||||||
|
|
||||||
export default function AccountPicker() {
|
export default function AccountPicker() {
|
||||||
@ -11,6 +12,7 @@ export default function AccountPicker() {
|
|||||||
SettingsStore.setAccount(account)
|
SettingsStore.setAccount(account)
|
||||||
SettingsStore.setEIP155Address(eip155Addresses[account])
|
SettingsStore.setEIP155Address(eip155Addresses[account])
|
||||||
SettingsStore.setCosmosAddress(cosmosAddresses[account])
|
SettingsStore.setCosmosAddress(cosmosAddresses[account])
|
||||||
|
SettingsStore.setSolanaAddress(solanaAddresses[account])
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -36,7 +36,6 @@ export default function Layout({ children, initialized }: Props) {
|
|||||||
justifyContent: initialized ? 'normal' : 'center',
|
justifyContent: initialized ? 'normal' : 'center',
|
||||||
alignItems: initialized ? 'normal' : 'center',
|
alignItems: initialized ? 'normal' : 'center',
|
||||||
borderRadius: 0,
|
borderRadius: 0,
|
||||||
|
|
||||||
paddingBottom: 5,
|
paddingBottom: 5,
|
||||||
'@xs': {
|
'@xs': {
|
||||||
borderRadius: '$lg',
|
borderRadius: '$lg',
|
||||||
@ -53,7 +52,8 @@ export default function Layout({ children, initialized }: Props) {
|
|||||||
paddingLeft: 2,
|
paddingLeft: 2,
|
||||||
paddingRight: 2,
|
paddingRight: 2,
|
||||||
'@xs': {
|
'@xs': {
|
||||||
padding: '20px'
|
padding: '20px',
|
||||||
|
paddingBottom: '40px'
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -68,6 +68,8 @@ export default function Layout({ children, initialized }: Props) {
|
|||||||
position: 'sticky',
|
position: 'sticky',
|
||||||
justifyContent: 'flex-end',
|
justifyContent: 'flex-end',
|
||||||
alignItems: 'flex-end',
|
alignItems: 'flex-end',
|
||||||
|
boxShadow: '0 -30px 20px #111111',
|
||||||
|
zIndex: 200,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
left: 0
|
left: 0
|
||||||
}}
|
}}
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
import AccountSelectCard from '@/components/AccountSelectCard'
|
||||||
|
import { Col, Divider, Row, Text } from '@nextui-org/react'
|
||||||
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types
|
||||||
|
*/
|
||||||
|
interface IProps {
|
||||||
|
name: string
|
||||||
|
chain: string
|
||||||
|
addresses: string[]
|
||||||
|
selectedAddresses: string[]
|
||||||
|
onSelect: (address: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component
|
||||||
|
*/
|
||||||
|
export default function ProposalSelectSection({
|
||||||
|
name,
|
||||||
|
addresses,
|
||||||
|
selectedAddresses,
|
||||||
|
chain,
|
||||||
|
onSelect
|
||||||
|
}: IProps) {
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<Divider y={2} />
|
||||||
|
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<Text h5>{`Select ${name} Accounts`}</Text>
|
||||||
|
{addresses.map((address, index) => (
|
||||||
|
<AccountSelectCard
|
||||||
|
key={address}
|
||||||
|
address={address}
|
||||||
|
index={index}
|
||||||
|
onSelect={() => onSelect(`${chain}:${address}`)}
|
||||||
|
selected={selectedAddresses.includes(`${chain}:${address}`)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import { COSMOS_MAINNET_CHAINS, TCosmosChain } from '@/data/COSMOSData'
|
import { COSMOS_MAINNET_CHAINS, TCosmosChain } from '@/data/COSMOSData'
|
||||||
import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data'
|
import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data'
|
||||||
|
import { SOLANA_CHAINS, TSolanaChain } from '@/data/SolanaData'
|
||||||
import { Col, Divider, Row, Text } from '@nextui-org/react'
|
import { Col, Divider, Row, Text } from '@nextui-org/react'
|
||||||
import { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ export default function RequesDetailsCard({ chains, protocol }: IProps) {
|
|||||||
chain =>
|
chain =>
|
||||||
EIP155_CHAINS[chain as TEIP155Chain]?.name ??
|
EIP155_CHAINS[chain as TEIP155Chain]?.name ??
|
||||||
COSMOS_MAINNET_CHAINS[chain as TCosmosChain]?.name ??
|
COSMOS_MAINNET_CHAINS[chain as TCosmosChain]?.name ??
|
||||||
|
SOLANA_CHAINS[chain as TSolanaChain]?.name ??
|
||||||
chain
|
chain
|
||||||
)
|
)
|
||||||
.join(', ')}
|
.join(', ')}
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
import AccountSelectCard from '@/components/AccountSelectCard'
|
||||||
|
import { Col, Divider, Row, Text } from '@nextui-org/react'
|
||||||
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types
|
||||||
|
*/
|
||||||
|
interface IProps {
|
||||||
|
name: string
|
||||||
|
chain: string
|
||||||
|
addresses: string[]
|
||||||
|
selectedAddresses: string[]
|
||||||
|
onDelete: (address: string) => void
|
||||||
|
onAdd: (address: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component
|
||||||
|
*/
|
||||||
|
export default function SessionSelectSection({
|
||||||
|
name,
|
||||||
|
addresses,
|
||||||
|
chain,
|
||||||
|
selectedAddresses,
|
||||||
|
onDelete,
|
||||||
|
onAdd
|
||||||
|
}: IProps) {
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<Divider y={2} />
|
||||||
|
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<Text h5>{`${name} Accounts`}</Text>
|
||||||
|
{addresses.map((address, index) => {
|
||||||
|
const fullAddress = `${chain}:${address}`
|
||||||
|
const selected = selectedAddresses.includes(fullAddress)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AccountSelectCard
|
||||||
|
key={address}
|
||||||
|
address={address}
|
||||||
|
index={index}
|
||||||
|
onSelect={() => (selected ? onDelete(fullAddress) : onAdd(fullAddress))}
|
||||||
|
selected={selected}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
}
|
37
wallets/react-wallet-v2/src/data/SolanaData.ts
Normal file
37
wallets/react-wallet-v2/src/data/SolanaData.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Types
|
||||||
|
*/
|
||||||
|
export type TSolanaChain = keyof typeof SOLANA_MAINNET_CHAINS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chains
|
||||||
|
*/
|
||||||
|
export const SOLANA_MAINNET_CHAINS = {
|
||||||
|
'solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ': {
|
||||||
|
chainId: '4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ',
|
||||||
|
name: 'Solana',
|
||||||
|
logo: '/chain-logos/solana-4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ.png',
|
||||||
|
rgb: '30, 240, 166',
|
||||||
|
rpc: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SOLANA_TEST_CHAINS = {
|
||||||
|
'solana:8E9rvCKLFQia2Y35HXjjpWzj8weVo44K': {
|
||||||
|
chainId: '8E9rvCKLFQia2Y35HXjjpWzj8weVo44K',
|
||||||
|
name: 'Solana Devnet',
|
||||||
|
logo: '/chain-logos/solana-4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ.png',
|
||||||
|
rgb: '30, 240, 166',
|
||||||
|
rpc: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SOLANA_CHAINS = { ...SOLANA_MAINNET_CHAINS, ...SOLANA_TEST_CHAINS }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methods
|
||||||
|
*/
|
||||||
|
export const SOLANA_SIGNING_METHODS = {
|
||||||
|
SOLANA_SIGN_TRANSACTION: 'solana_signTransaction',
|
||||||
|
SOLANA_SIGN_MESSAGE: 'solana_signMessage'
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
import SettingsStore from '@/store/SettingsStore'
|
import SettingsStore from '@/store/SettingsStore'
|
||||||
import { createOrRestoreCosmosWallet } from '@/utils/CosmosWalletUtil'
|
import { createOrRestoreCosmosWallet } from '@/utils/CosmosWalletUtil'
|
||||||
import { createOrRestoreEIP155Wallet } from '@/utils/EIP155WalletUtil'
|
import { createOrRestoreEIP155Wallet } from '@/utils/EIP155WalletUtil'
|
||||||
|
import { createOrRestoreSolanaWallet } from '@/utils/SolanaWalletUtil'
|
||||||
import { createWalletConnectClient } from '@/utils/WalletConnectUtil'
|
import { createWalletConnectClient } from '@/utils/WalletConnectUtil'
|
||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
|
|
||||||
@ -11,9 +12,11 @@ export default function useInitialization() {
|
|||||||
try {
|
try {
|
||||||
const { eip155Addresses } = createOrRestoreEIP155Wallet()
|
const { eip155Addresses } = createOrRestoreEIP155Wallet()
|
||||||
const { cosmosAddresses } = await createOrRestoreCosmosWallet()
|
const { cosmosAddresses } = await createOrRestoreCosmosWallet()
|
||||||
|
const { solanaAddresses } = await createOrRestoreSolanaWallet()
|
||||||
|
|
||||||
SettingsStore.setEIP155Address(eip155Addresses[0])
|
SettingsStore.setEIP155Address(eip155Addresses[0])
|
||||||
SettingsStore.setCosmosAddress(cosmosAddresses[0])
|
SettingsStore.setCosmosAddress(cosmosAddresses[0])
|
||||||
|
SettingsStore.setSolanaAddress(solanaAddresses[0])
|
||||||
|
|
||||||
await createWalletConnectClient()
|
await createWalletConnectClient()
|
||||||
|
|
||||||
|
19
wallets/react-wallet-v2/src/lib/Solana.ts
Normal file
19
wallets/react-wallet-v2/src/lib/Solana.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { Keypair } from '@solana/web3.js'
|
||||||
|
|
||||||
|
export class Solana {
|
||||||
|
keypair: Keypair
|
||||||
|
|
||||||
|
constructor(keypair: Keypair) {
|
||||||
|
this.keypair = keypair
|
||||||
|
}
|
||||||
|
|
||||||
|
static init(secretKey?: Uint8Array) {
|
||||||
|
const keypair = secretKey ? Keypair.fromSecretKey(secretKey) : Keypair.generate()
|
||||||
|
|
||||||
|
return new Solana(keypair)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getAccount() {
|
||||||
|
return await this.keypair.publicKey.toBase58()
|
||||||
|
}
|
||||||
|
}
|
@ -3,13 +3,14 @@ import AccountPicker from '@/components/AccountPicker'
|
|||||||
import PageHeader from '@/components/PageHeader'
|
import PageHeader from '@/components/PageHeader'
|
||||||
import { COSMOS_MAINNET_CHAINS } from '@/data/COSMOSData'
|
import { COSMOS_MAINNET_CHAINS } from '@/data/COSMOSData'
|
||||||
import { EIP155_MAINNET_CHAINS, EIP155_TEST_CHAINS } from '@/data/EIP155Data'
|
import { EIP155_MAINNET_CHAINS, EIP155_TEST_CHAINS } from '@/data/EIP155Data'
|
||||||
|
import { SOLANA_MAINNET_CHAINS, SOLANA_TEST_CHAINS } from '@/data/SolanaData'
|
||||||
import SettingsStore from '@/store/SettingsStore'
|
import SettingsStore from '@/store/SettingsStore'
|
||||||
import { Text } from '@nextui-org/react'
|
import { Text } from '@nextui-org/react'
|
||||||
import { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
import { useSnapshot } from 'valtio'
|
import { useSnapshot } from 'valtio'
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
const { testNets, eip155Address, cosmosAddress } = useSnapshot(SettingsStore.state)
|
const { testNets, eip155Address, cosmosAddress, solanaAddress } = useSnapshot(SettingsStore.state)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
@ -25,6 +26,9 @@ export default function HomePage() {
|
|||||||
{Object.values(COSMOS_MAINNET_CHAINS).map(({ name, logo, rgb }) => (
|
{Object.values(COSMOS_MAINNET_CHAINS).map(({ name, logo, rgb }) => (
|
||||||
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={cosmosAddress} />
|
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={cosmosAddress} />
|
||||||
))}
|
))}
|
||||||
|
{Object.values(SOLANA_MAINNET_CHAINS).map(({ name, logo, rgb }) => (
|
||||||
|
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={solanaAddress} />
|
||||||
|
))}
|
||||||
|
|
||||||
{testNets ? (
|
{testNets ? (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
@ -34,6 +38,9 @@ export default function HomePage() {
|
|||||||
{Object.values(EIP155_TEST_CHAINS).map(({ name, logo, rgb }) => (
|
{Object.values(EIP155_TEST_CHAINS).map(({ name, logo, rgb }) => (
|
||||||
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={eip155Address} />
|
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={eip155Address} />
|
||||||
))}
|
))}
|
||||||
|
{Object.values(SOLANA_TEST_CHAINS).map(({ name, logo, rgb }) => (
|
||||||
|
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={solanaAddress} />
|
||||||
|
))}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
) : null}
|
) : null}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import AccountSelectCard from '@/components/AccountSelectCard'
|
|
||||||
import PageHeader from '@/components/PageHeader'
|
import PageHeader from '@/components/PageHeader'
|
||||||
import ProjectInfoCard from '@/components/ProjectInfoCard'
|
import ProjectInfoCard from '@/components/ProjectInfoCard'
|
||||||
|
import SessionSelectSection from '@/components/SessionSelectSection'
|
||||||
import { COSMOS_MAINNET_CHAINS, TCosmosChain } from '@/data/COSMOSData'
|
import { COSMOS_MAINNET_CHAINS, TCosmosChain } from '@/data/COSMOSData'
|
||||||
import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data'
|
import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data'
|
||||||
|
import { SOLANA_CHAINS, TSolanaChain } from '@/data/SolanaData'
|
||||||
import { cosmosAddresses } from '@/utils/CosmosWalletUtil'
|
import { cosmosAddresses } from '@/utils/CosmosWalletUtil'
|
||||||
import { eip155Addresses } from '@/utils/EIP155WalletUtil'
|
import { eip155Addresses } from '@/utils/EIP155WalletUtil'
|
||||||
import { isCosmosChain, isEIP155Chain } from '@/utils/HelperUtil'
|
import { isCosmosChain, isEIP155Chain, isSolanaChain } from '@/utils/HelperUtil'
|
||||||
|
import { solanaAddresses } from '@/utils/SolanaWalletUtil'
|
||||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||||
import { Button, Col, Divider, Row, Text } from '@nextui-org/react'
|
import { Button, Col, Divider, Row, Text } from '@nextui-org/react'
|
||||||
import { ERROR } from '@walletconnect/utils'
|
import { ERROR } from '@walletconnect/utils'
|
||||||
@ -79,59 +81,39 @@ export default function SessionPage() {
|
|||||||
{chains.map(chain => {
|
{chains.map(chain => {
|
||||||
if (isEIP155Chain(chain)) {
|
if (isEIP155Chain(chain)) {
|
||||||
return (
|
return (
|
||||||
<Fragment key={chain}>
|
<SessionSelectSection
|
||||||
<Divider y={2} />
|
key={chain}
|
||||||
|
chain={chain}
|
||||||
<Row>
|
name={EIP155_CHAINS[chain as TEIP155Chain]?.name}
|
||||||
<Col>
|
addresses={eip155Addresses}
|
||||||
<Text h5>{`${EIP155_CHAINS[chain as TEIP155Chain].name} Accounts`}</Text>
|
selectedAddresses={accounts}
|
||||||
{eip155Addresses.map((address, index) => {
|
onDelete={onDeleteAccount}
|
||||||
const fullAddress = `${chain}:${address}`
|
onAdd={onAddAccount}
|
||||||
const selected = accounts.includes(fullAddress)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AccountSelectCard
|
|
||||||
key={address}
|
|
||||||
address={address}
|
|
||||||
index={index}
|
|
||||||
onSelect={() =>
|
|
||||||
selected ? onDeleteAccount(fullAddress) : onAddAccount(fullAddress)
|
|
||||||
}
|
|
||||||
selected={selected}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Fragment>
|
|
||||||
)
|
|
||||||
} else if (isCosmosChain(chain)) {
|
} else if (isCosmosChain(chain)) {
|
||||||
return (
|
return (
|
||||||
<Fragment key={chain}>
|
<SessionSelectSection
|
||||||
<Divider y={2} />
|
key={chain}
|
||||||
|
chain={chain}
|
||||||
<Row>
|
name={COSMOS_MAINNET_CHAINS[chain as TCosmosChain]?.name}
|
||||||
<Col>
|
addresses={cosmosAddresses}
|
||||||
<Text h5>{`${COSMOS_MAINNET_CHAINS[chain as TCosmosChain].name} Accounts`}</Text>
|
selectedAddresses={accounts}
|
||||||
{cosmosAddresses.map((address, index) => {
|
onDelete={onDeleteAccount}
|
||||||
const fullAddress = `${chain}:${address}`
|
onAdd={onAddAccount}
|
||||||
const selected = accounts.includes(fullAddress)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AccountSelectCard
|
|
||||||
key={address}
|
|
||||||
address={address}
|
|
||||||
index={index}
|
|
||||||
onSelect={() =>
|
|
||||||
selected ? onDeleteAccount(fullAddress) : onAddAccount(fullAddress)
|
|
||||||
}
|
|
||||||
selected={selected}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
} else if (isSolanaChain(chain)) {
|
||||||
</Col>
|
return (
|
||||||
</Row>
|
<SessionSelectSection
|
||||||
</Fragment>
|
key={chain}
|
||||||
|
chain={chain}
|
||||||
|
name={SOLANA_CHAINS[chain as TSolanaChain]?.name}
|
||||||
|
addresses={solanaAddresses}
|
||||||
|
selectedAddresses={accounts}
|
||||||
|
onDelete={onDeleteAccount}
|
||||||
|
onAdd={onAddAccount}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
|
@ -32,6 +32,7 @@ export default function WalletConnectPage() {
|
|||||||
|
|
||||||
<Input
|
<Input
|
||||||
bordered
|
bordered
|
||||||
|
aria-label="wc url connect input"
|
||||||
placeholder="e.g. wc:a281567bb3e4..."
|
placeholder="e.g. wc:a281567bb3e4..."
|
||||||
onChange={e => setUri(e.target.value)}
|
onChange={e => setUri(e.target.value)}
|
||||||
value={uri}
|
value={uri}
|
||||||
|
@ -8,6 +8,7 @@ interface State {
|
|||||||
account: number
|
account: number
|
||||||
eip155Address: string
|
eip155Address: string
|
||||||
cosmosAddress: string
|
cosmosAddress: string
|
||||||
|
solanaAddress: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,7 +18,8 @@ const state = proxy<State>({
|
|||||||
testNets: typeof localStorage !== 'undefined' ? Boolean(localStorage.getItem('TEST_NETS')) : true,
|
testNets: typeof localStorage !== 'undefined' ? Boolean(localStorage.getItem('TEST_NETS')) : true,
|
||||||
account: 0,
|
account: 0,
|
||||||
eip155Address: '',
|
eip155Address: '',
|
||||||
cosmosAddress: ''
|
cosmosAddress: '',
|
||||||
|
solanaAddress: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,6 +40,10 @@ const SettingsStore = {
|
|||||||
state.cosmosAddress = cosmosAddresses
|
state.cosmosAddress = cosmosAddresses
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setSolanaAddress(solanaAddress: string) {
|
||||||
|
state.solanaAddress = solanaAddress
|
||||||
|
},
|
||||||
|
|
||||||
toggleTestNets() {
|
toggleTestNets() {
|
||||||
state.testNets = !state.testNets
|
state.testNets = !state.testNets
|
||||||
if (state.testNets) {
|
if (state.testNets) {
|
||||||
|
@ -83,3 +83,10 @@ export function isEIP155Chain(chain: string) {
|
|||||||
export function isCosmosChain(chain: string) {
|
export function isCosmosChain(chain: string) {
|
||||||
return chain.includes('cosmos')
|
return chain.includes('cosmos')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if chain is part of SOLANA standard
|
||||||
|
*/
|
||||||
|
export function isSolanaChain(chain: string) {
|
||||||
|
return chain.includes('solana')
|
||||||
|
}
|
||||||
|
52
wallets/react-wallet-v2/src/utils/SolanaWalletUtil.ts
Normal file
52
wallets/react-wallet-v2/src/utils/SolanaWalletUtil.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import { Solana } from '@/lib/Solana'
|
||||||
|
|
||||||
|
export let wallet1: Solana
|
||||||
|
export let wallet2: Solana
|
||||||
|
export let solanaWallets: Record<string, Solana>
|
||||||
|
export let solanaAddresses: string[]
|
||||||
|
|
||||||
|
let address1: string
|
||||||
|
let address2: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilities
|
||||||
|
*/
|
||||||
|
export async function createOrRestoreSolanaWallet() {
|
||||||
|
const secretKey1 = localStorage.getItem('SOLANA_SECRET_KEY_1')
|
||||||
|
const secretKey2 = localStorage.getItem('SOLANA_SECRET_KEY_2')
|
||||||
|
|
||||||
|
if (secretKey1 && secretKey2) {
|
||||||
|
const secretArray1: number[] = Object.values(JSON.parse(secretKey1))
|
||||||
|
const secretArray2: number[] = Object.values(JSON.parse(secretKey2))
|
||||||
|
|
||||||
|
wallet1 = Solana.init(Uint8Array.from(secretArray1))
|
||||||
|
wallet2 = Solana.init(Uint8Array.from(secretArray2))
|
||||||
|
address1 = await wallet1.getAccount()
|
||||||
|
address2 = await wallet2.getAccount()
|
||||||
|
} else {
|
||||||
|
wallet1 = Solana.init()
|
||||||
|
wallet2 = Solana.init()
|
||||||
|
address1 = await wallet1.getAccount()
|
||||||
|
address2 = await wallet2.getAccount()
|
||||||
|
// Don't store secretKey in local storage in a production project!
|
||||||
|
localStorage.setItem(
|
||||||
|
'SOLANA_SECRET_KEY_1',
|
||||||
|
JSON.stringify(Array.from(wallet1.keypair.secretKey))
|
||||||
|
)
|
||||||
|
localStorage.setItem(
|
||||||
|
'SOLANA_SECRET_KEY_2',
|
||||||
|
JSON.stringify(Array.from(wallet2.keypair.secretKey))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
solanaWallets = {
|
||||||
|
[address1]: wallet1,
|
||||||
|
[address2]: wallet2
|
||||||
|
}
|
||||||
|
solanaAddresses = Object.keys(solanaWallets)
|
||||||
|
|
||||||
|
return {
|
||||||
|
solanaWallets,
|
||||||
|
solanaAddresses
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,25 @@
|
|||||||
import AccountSelectCard from '@/components/AccountSelectCard'
|
|
||||||
import ProjectInfoCard from '@/components/ProjectInfoCard'
|
import ProjectInfoCard from '@/components/ProjectInfoCard'
|
||||||
|
import ProposalSelectSection from '@/components/ProposalSelectSection'
|
||||||
import RequesDetailsCard from '@/components/RequestDetalilsCard'
|
import RequesDetailsCard from '@/components/RequestDetalilsCard'
|
||||||
import RequestMethodCard from '@/components/RequestMethodCard'
|
import RequestMethodCard from '@/components/RequestMethodCard'
|
||||||
import RequestModalContainer from '@/components/RequestModalContainer'
|
import RequestModalContainer from '@/components/RequestModalContainer'
|
||||||
import { COSMOS_MAINNET_CHAINS, TCosmosChain } from '@/data/COSMOSData'
|
import { COSMOS_MAINNET_CHAINS, TCosmosChain } from '@/data/COSMOSData'
|
||||||
import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data'
|
import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data'
|
||||||
|
import { SOLANA_CHAINS, TSolanaChain } from '@/data/SolanaData'
|
||||||
import ModalStore from '@/store/ModalStore'
|
import ModalStore from '@/store/ModalStore'
|
||||||
import { cosmosAddresses } from '@/utils/CosmosWalletUtil'
|
import { cosmosAddresses } from '@/utils/CosmosWalletUtil'
|
||||||
import { eip155Addresses } from '@/utils/EIP155WalletUtil'
|
import { eip155Addresses } from '@/utils/EIP155WalletUtil'
|
||||||
import { isCosmosChain, isEIP155Chain } from '@/utils/HelperUtil'
|
import { isCosmosChain, isEIP155Chain, isSolanaChain } from '@/utils/HelperUtil'
|
||||||
|
import { solanaAddresses } from '@/utils/SolanaWalletUtil'
|
||||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||||
import { Button, Col, Divider, Modal, Row, Text } from '@nextui-org/react'
|
import { Button, Divider, Modal, Text } from '@nextui-org/react'
|
||||||
import { Fragment, useState } from 'react'
|
import { Fragment, useState } from 'react'
|
||||||
|
|
||||||
export default function SessionProposalModal() {
|
export default function SessionProposalModal() {
|
||||||
const [selectedEIP155, setSelectedEip155] = useState<string[]>([])
|
const [selectedEIP155, setSelectedEip155] = useState<string[]>([])
|
||||||
const [selectedCosmos, setSelectedCosmos] = useState<string[]>([])
|
const [selectedCosmos, setSelectedCosmos] = useState<string[]>([])
|
||||||
|
const [selectedSolana, setSelectedSolana] = useState<string[]>([])
|
||||||
|
const allSelected = [...selectedEIP155, ...selectedCosmos, ...selectedSolana]
|
||||||
|
|
||||||
// Get proposal data and wallet address from store
|
// Get proposal data and wallet address from store
|
||||||
const proposal = ModalStore.state.data?.proposal
|
const proposal = ModalStore.state.data?.proposal
|
||||||
@ -50,10 +54,20 @@ export default function SessionProposalModal() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add / remove address from Solana selection
|
||||||
|
function onSelectSolana(address: string) {
|
||||||
|
if (selectedSolana.includes(address)) {
|
||||||
|
const newAddresses = selectedSolana.filter(a => a !== address)
|
||||||
|
setSelectedSolana(newAddresses)
|
||||||
|
} else {
|
||||||
|
setSelectedSolana([...selectedSolana, address])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Hanlde approve action
|
// Hanlde approve action
|
||||||
async function onApprove() {
|
async function onApprove() {
|
||||||
if (proposal) {
|
if (proposal) {
|
||||||
const accounts = [...selectedEIP155, ...selectedCosmos]
|
const accounts = allSelected
|
||||||
const response = {
|
const response = {
|
||||||
state: {
|
state: {
|
||||||
accounts
|
accounts
|
||||||
@ -88,47 +102,33 @@ export default function SessionProposalModal() {
|
|||||||
{chains.map(chain => {
|
{chains.map(chain => {
|
||||||
if (isEIP155Chain(chain)) {
|
if (isEIP155Chain(chain)) {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<ProposalSelectSection
|
||||||
<Divider y={2} />
|
name={EIP155_CHAINS[chain as TEIP155Chain]?.name}
|
||||||
|
addresses={eip155Addresses}
|
||||||
<Row>
|
selectedAddresses={selectedEIP155}
|
||||||
<Col>
|
onSelect={onSelectEIP155}
|
||||||
<Text h5>{`Select ${EIP155_CHAINS[chain as TEIP155Chain].name} Accounts`}</Text>
|
chain={chain}
|
||||||
{eip155Addresses.map((address, index) => (
|
|
||||||
<AccountSelectCard
|
|
||||||
key={address}
|
|
||||||
address={address}
|
|
||||||
index={index}
|
|
||||||
onSelect={() => onSelectEIP155(`${chain}:${address}`)}
|
|
||||||
selected={selectedEIP155.includes(`${chain}:${address}`)}
|
|
||||||
/>
|
/>
|
||||||
))}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Fragment>
|
|
||||||
)
|
)
|
||||||
} else if (isCosmosChain(chain)) {
|
} else if (isCosmosChain(chain)) {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<ProposalSelectSection
|
||||||
<Divider y={2} />
|
name={COSMOS_MAINNET_CHAINS[chain as TCosmosChain]?.name}
|
||||||
|
addresses={cosmosAddresses}
|
||||||
<Row>
|
selectedAddresses={selectedCosmos}
|
||||||
<Col>
|
onSelect={onSelectCosmos}
|
||||||
<Text h5>
|
chain={chain}
|
||||||
{`Select ${COSMOS_MAINNET_CHAINS[chain as TCosmosChain].name} Accounts`}
|
/>
|
||||||
</Text>
|
)
|
||||||
{cosmosAddresses.map((address, index) => (
|
} else if (isSolanaChain(chain)) {
|
||||||
<AccountSelectCard
|
return (
|
||||||
key={address}
|
<ProposalSelectSection
|
||||||
address={address}
|
name={SOLANA_CHAINS[chain as TSolanaChain]?.name}
|
||||||
index={index}
|
addresses={solanaAddresses}
|
||||||
onSelect={() => onSelectCosmos(`${chain}:${address}`)}
|
selectedAddresses={selectedSolana}
|
||||||
selected={selectedCosmos.includes(`${chain}:${address}`)}
|
onSelect={onSelectSolana}
|
||||||
|
chain={chain}
|
||||||
/>
|
/>
|
||||||
))}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Fragment>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
@ -144,8 +144,10 @@ export default function SessionProposalModal() {
|
|||||||
flat
|
flat
|
||||||
color="success"
|
color="success"
|
||||||
onClick={onApprove}
|
onClick={onApprove}
|
||||||
disabled={![...selectedEIP155, ...selectedCosmos].length}
|
disabled={!allSelected.length}
|
||||||
css={{ opacity: [...selectedEIP155, ...selectedCosmos].length ? 1 : 0.4 }}
|
css={{
|
||||||
|
opacity: allSelected.length ? 1 : 0.4
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Approve
|
Approve
|
||||||
</Button>
|
</Button>
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user