-
Notifications
You must be signed in to change notification settings - Fork 149
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e878f0c
commit e2d429c
Showing
15 changed files
with
1,192 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import { WalletManager, Logger } from "@cosmos-kit/core"; | ||
import { useMemo, useState } from 'react' | ||
import { wallets as leapWallets } from "@cosmos-kit/leap"; | ||
import { wallets as stationWallets } from "@cosmos-kit/station"; | ||
import { wallets as coin98Wallets } from "@cosmos-kit/coin98"; | ||
import { wallets as keplrWallets } from "@cosmos-kit/keplr"; | ||
import { assets } from "chain-registry"; | ||
import { Button } from "components/button"; | ||
import { AccountData } from "@cosmjs/proto-signing"; | ||
|
||
|
||
export default () => { | ||
const walletManager = useMemo(() => { | ||
return new WalletManager( | ||
["cosmoshub", "juno", "stargaze"], [keplrWallets[0], leapWallets[0], stationWallets[0], coin98Wallets[0]], new Logger('NONE'), false, | ||
undefined, undefined, assets | ||
); | ||
}, []) | ||
|
||
const [_, forceUpdate] = useState(0) | ||
|
||
return ( | ||
<div> | ||
<pre> | ||
{JSON.stringify({ | ||
activeRepos: walletManager.activeRepos, | ||
|
||
}, null, 2)} | ||
</pre> | ||
<div>Main Wallets</div> | ||
<table > | ||
<tbody> | ||
{walletManager.mainWallets.map(mw => { | ||
return mw.getChainWalletList(false).map(cw => { | ||
cw.callbacks = { | ||
beforeConnect: () => console.log('beforeConnect'), | ||
beforeDisconnect: () => console.log('beforeDisconnect'), | ||
afterConnect: () => forceUpdate(i => i + 1), | ||
afterDisconnect: () => forceUpdate(i => i + 1) | ||
} | ||
|
||
const [account, setAccount] = useState<AccountData[] | undefined>(undefined) | ||
|
||
const getAddress = async () => { | ||
await cw.initOfflineSigner() | ||
const account = await cw.offlineSigner?.getAccounts() | ||
setAccount(account) | ||
} | ||
|
||
return ( | ||
<tr> | ||
<td className='border-gray-500 p-1 border-2'>{mw.walletName}</td> | ||
<td className='border-gray-500 p-1 border-2'>{cw.chainName}</td> | ||
<td className='border-gray-500 p-1 border-2 space-x-1'> | ||
<Button size='sm' onClick={() => { cw.connect(true); forceUpdate(i => i + 1) }}>connect</Button> | ||
<Button size='sm' onClick={() => { cw.disconnect(true); forceUpdate(i => i + 1) }}>disconnect</Button> | ||
<Button size='sm' onClick={getAddress}>get offline signer</Button> | ||
</td> | ||
<td className='border-gray-500 p-1 border-2'>{cw.state}</td> | ||
<td className='border-gray-500 p-1 border-2'>{cw.message}</td> | ||
<td className='border-gray-500 p-1 border-2'>{account?.[0]?.address}</td> | ||
</tr> | ||
) | ||
}) | ||
})} | ||
</tbody> | ||
</table > | ||
<div>Wallet Repo</div> | ||
<table> | ||
<tbody> | ||
{walletManager.walletRepos.map(wr => { | ||
|
||
|
||
|
||
return ( | ||
<> | ||
<tr key={wr.chainName}> | ||
<td className='border-gray-500 p-2 border-2'>current: {wr.current?.walletName}</td> | ||
<td>{'client'}</td> | ||
</tr> | ||
{wr.wallets.map(w => { | ||
|
||
const [account, setAccount] = useState<AccountData[] | undefined>(undefined) | ||
|
||
const getAddress = async () => { | ||
await w.initOfflineSigner() | ||
const account = await w.offlineSigner?.getAccounts() | ||
if (account) { | ||
setAccount(account) | ||
} | ||
} | ||
|
||
|
||
return ( | ||
<tr key={`${wr.chainName}-${w.walletName}`}> | ||
<td className='border-gray-500 p-1 border-2'>{w.chainName}</td> | ||
<td className='border-gray-500 p-1 border-2'>{w.walletName}</td> | ||
<td className='border-gray-500 p-1 border-2 space-x-1'> | ||
<Button size='sm' onClick={() => { w.connect(); forceUpdate(i => i + 1) }}>connect</Button> | ||
<Button size='sm' onClick={() => { w.disconnect(); forceUpdate(i => i + 1) }}>disconnect</Button> | ||
<Button size='sm' onClick={getAddress}>get offline signer</Button> | ||
</td> | ||
<td className='border-gray-500 p-1 border-2'>{w.state}</td> | ||
<td className='border-gray-500 p-1 border-2'>{w.message}</td> | ||
<td className='border-gray-500 p-1 border-2'>{account?.[0]?.address}</td> | ||
</tr > | ||
) | ||
}) | ||
} | ||
</> | ||
) | ||
})} | ||
</tbody> | ||
</table> | ||
</div >) | ||
|
||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { act, renderHook, waitFor, render, fireEvent, screen } from '@testing-library/react'; | ||
import { useChain, useManager } from '../src' | ||
import { customWrapper } from "../test-utils" | ||
import '@testing-library/jest-dom' | ||
import React from 'react' | ||
|
||
const TestComponent = () => { | ||
const chain = useChain('juno') | ||
const manager = useManager() | ||
return <div> | ||
<p>address:{chain.address}</p> | ||
<div className="flex flex-col space-y-2 w-80"> | ||
{manager.getWalletRepo('juno').wallets.map(w => { | ||
return <button key={w.walletName} onClick={() => w.connect(true)}>{w.walletName}</button> | ||
})} | ||
</div> | ||
</div> | ||
} | ||
|
||
describe('useChain', () => { | ||
|
||
const useContextMock = jest.spyOn(React, 'useContext') | ||
|
||
afterEach(() => { | ||
useContextMock.mockRestore() | ||
}) | ||
|
||
it('should throw an error if no modal provided', async () => { | ||
useContextMock.mockReturnValue({ walletManager: {}, modalProvided: undefined } as any) | ||
renderHook(() => { | ||
try { | ||
useChain('juno') | ||
} catch (error) { | ||
expect(error.message).toBe('You have to provide `walletModal` to use `useChain`, or use `useChainWallet` instead.') | ||
} | ||
}, { wrapper: customWrapper }) | ||
}) | ||
|
||
it('should throw an error if used without ChainProvider', async () => { | ||
renderHook(() => { | ||
try { | ||
useChain('juno') | ||
} catch (error) { | ||
expect(error.message).toBe('You have forgot to use ChainProvider.') | ||
} | ||
}) | ||
}) | ||
|
||
it('return undefined if not select a wallet', async () => { | ||
const { result } = renderHook(() => useChain('juno', false), { wrapper: customWrapper }) | ||
await waitFor(() => { | ||
expect(result.current.address).toBeUndefined() | ||
}) | ||
}) | ||
|
||
it('should return address of selected wallet and chain', async () => { | ||
render(<TestComponent />, { wrapper: customWrapper }) | ||
|
||
await act(() => fireEvent.click(screen.getByText('station-extension'))) | ||
|
||
await waitFor(async () => { | ||
expect(await screen.getByText('address:juno-1AddressStation')).toBeInTheDocument() | ||
}) | ||
|
||
await act(() => fireEvent.click(screen.getByText('leap-extension'))) | ||
|
||
await waitFor(async () => { | ||
expect(await screen.getByText('address:juno-1AddressLeap')).toBeInTheDocument() | ||
}) | ||
|
||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { act, renderHook, waitFor } from "@testing-library/react" | ||
import { useChainWallet } from "../src" | ||
import { customWrapper } from "../test-utils" | ||
|
||
describe('useChainWallet', () => { | ||
it('should throw error, if not wrapped in ChainProvider', async () => { | ||
renderHook(() => { | ||
try { | ||
useChainWallet('juno', 'keplr-extension', true) | ||
} catch (error) { | ||
expect(error.message).toBe('You have forgot to use ChainProvider.') | ||
} | ||
}) | ||
}) | ||
it('should return right chain and wallet information', async () => { | ||
const { result } = renderHook(() => useChainWallet('juno', 'leap-extension', true), { wrapper: customWrapper }) | ||
|
||
await act(async () => { | ||
await result.current?.connect() | ||
}) | ||
|
||
await waitFor(() => { | ||
expect(result.current?.chain?.chain_name).toBe('juno') | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { act, fireEvent, render, renderHook, screen, waitFor } from "@testing-library/react" | ||
import { useChains, useManager } from "../src" | ||
import React from 'react' | ||
import { customWrapper } from '../test-utils' | ||
import '@testing-library/jest-dom' | ||
|
||
const TestComponent = () => { | ||
const chains = useChains(['juno', 'stargaze', 'osmosis']); | ||
const manager = useManager() | ||
|
||
const leapWallet = manager.mainWallets.find(w => w.walletName === 'leap-extension') | ||
const stationWallet = manager.mainWallets.find(w => w.walletName === 'station-extension') | ||
|
||
return ( | ||
<div> | ||
<ul> | ||
{Object.entries(chains).map(([name, chain]) => { | ||
return ( | ||
<li key={name}> | ||
<span>{name}:{chain.address}</span> | ||
</li> | ||
) | ||
})} | ||
</ul> | ||
<button onClick={() => leapWallet?.connectAll()}>connect leap</button> | ||
<button onClick={() => leapWallet?.disconnectAll()}>disconnect leap</button> | ||
<button onClick={() => stationWallet?.connectAll()}>connect station</button> | ||
</div> | ||
) | ||
} | ||
|
||
describe('useChains', () => { | ||
|
||
const useContextMock = jest.spyOn(React, 'useContext') | ||
afterEach(() => { | ||
useContextMock.mockRestore() | ||
}) | ||
|
||
it('should throw an error if no modal provided', async () => { | ||
useContextMock.mockReturnValue({ walletManager: {}, modalProvided: undefined } as any) | ||
renderHook(() => { | ||
try { | ||
useChains(['juno', 'stargaze']) | ||
} catch (error) { | ||
expect(error.message).toBe('You have to provide `walletModal` to use `useChains`, or use `useChainWallet` instead.') | ||
} | ||
}, { wrapper: customWrapper }) | ||
}) | ||
|
||
it('should throw an error if used without ChainProvider', async () => { | ||
renderHook(() => { | ||
try { | ||
useChains(['juno', 'stargaze']) | ||
} catch (error) { | ||
expect(error.message).toBe('You have forgotten to use ChainProvider.') | ||
} | ||
}) | ||
}) | ||
|
||
it('should render chains address', async () => { | ||
render(<TestComponent />, { wrapper: customWrapper }) | ||
|
||
await act(async () => { | ||
await fireEvent.click(screen.getByText('connect leap')) | ||
}) | ||
|
||
await waitFor(() => { | ||
expect(screen.getByText('juno:juno-1AddressLeap')).toBeInTheDocument() | ||
expect(screen.getByText('stargaze:stargaze-1AddressLeap')).toBeInTheDocument() | ||
expect(screen.getByText('osmosis:osmosis-1AddressLeap')).toBeInTheDocument() | ||
}) | ||
|
||
await act(() => fireEvent.click(screen.getByText('disconnect leap'))) | ||
|
||
await act(async () => { | ||
await fireEvent.click(screen.getByText('connect station')) | ||
}) | ||
|
||
await waitFor(() => { | ||
expect(screen.getByText('juno:juno-1AddressStation')).toBeInTheDocument() | ||
expect(screen.getByText('stargaze:stargaze-1AddressStation')).toBeInTheDocument() | ||
expect(screen.getByText('osmosis:osmosis-1AddressStation')).toBeInTheDocument() | ||
}) | ||
}) | ||
|
||
|
||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { renderHook, waitFor } from '@testing-library/react' | ||
import { useManager } from '../src' | ||
import { Keplr } from '@keplr-wallet/types' | ||
import { customWrapper } from '../test-utils'; | ||
|
||
describe('useManager', () => { | ||
it('should throw an error if used without ChainProvider', async () => { | ||
renderHook(() => { | ||
try { | ||
useManager() | ||
} catch (error) { | ||
expect(error.message).toBe('You have forgot to use ChainProvider.') | ||
} | ||
}) | ||
}) | ||
|
||
it('should create main wallet according wallets', async () => { | ||
const { result } = renderHook(() => useManager(), { wrapper: customWrapper }) | ||
await waitFor(() => { | ||
expect(result.current.mainWallets).toHaveLength(3) | ||
}) | ||
}) | ||
it('should create wallet repo according chains', async () => { | ||
const { result } = renderHook(() => useManager(), { wrapper: customWrapper }) | ||
await waitFor(() => { | ||
expect(result.current.walletRepos).toHaveLength(4) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { renderHook, waitFor } from "@testing-library/react" | ||
import { customWrapper } from "../test-utils" | ||
import { useNameService } from "../src" | ||
import { Keplr } from '@keplr-wallet/types' | ||
import * as useManagerHook from '../src/hooks/useManager' | ||
|
||
describe('useNameService', () => { | ||
|
||
const getNameServiceMock = jest.fn() | ||
const getNameServiceRegistryFromNameMock = jest.fn() | ||
|
||
|
||
beforeEach(() => { | ||
jest.spyOn(useManagerHook, 'useManager').mockImplementation(() => ({ | ||
defaultNameService: 'icns', | ||
getNameService: getNameServiceMock, | ||
chainRecords: [], | ||
walletRepos: [], | ||
mainWallets: [], | ||
getChainRecord: jest.fn(), | ||
getWalletRepo: jest.fn(), | ||
addChains: jest.fn(), | ||
addEndpoints: jest.fn(), | ||
getChainLogo: jest.fn(), | ||
on: jest.fn(), | ||
off: jest.fn() // Add the missing properties here | ||
})) | ||
|
||
|
||
}) | ||
|
||
it('should throw error, if there is no default name space', () => { | ||
renderHook(() => { | ||
try { | ||
useNameService('notexistnameservice') | ||
} catch (error) { | ||
expect(error.message).toBe('No such name service: notexistnameservice') | ||
} | ||
}) | ||
}) | ||
|
||
|
||
it('should return right name service', async () => { | ||
getNameServiceMock.mockImplementation(() => Promise.resolve('nameservice1')) | ||
|
||
const { result } = renderHook(() => useNameService(), { wrapper: customWrapper }) | ||
await waitFor(() => { | ||
expect(result.current.data).toBe('nameservice1') | ||
}) | ||
}) | ||
|
||
it('should return error message', async () => { | ||
getNameServiceMock.mockImplementation(() => Promise.reject(new Error('error message'))) | ||
|
||
const { result } = renderHook(() => useNameService(), { wrapper: customWrapper }) | ||
await waitFor(() => { | ||
expect(result.current.message).toBe('error message') | ||
}) | ||
}) | ||
|
||
}) |
Oops, something went wrong.