diff --git a/src/ada/available-wallets.ts b/src/ada/available-wallets.ts deleted file mode 100644 index 283e492..0000000 --- a/src/ada/available-wallets.ts +++ /dev/null @@ -1,8 +0,0 @@ -// TODO: Add klever mobile app source name -export const availableWallets = ['nami'] as const - -export type AvailableWallet = typeof availableWallets[number] - -export enum CardanoWallet { - NAMI = 'nami', -} diff --git a/src/ada/types.ts b/src/ada/types.ts deleted file mode 100644 index dc7ed8b..0000000 --- a/src/ada/types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { AvailableWallet } from './available-wallets'; - -export interface CardanoProviderProps { - wallet?: AvailableWallet -} - -export type CardanoUsedAddress = string diff --git a/src/cardano/available-wallets.ts b/src/cardano/available-wallets.ts new file mode 100644 index 0000000..f0bad71 --- /dev/null +++ b/src/cardano/available-wallets.ts @@ -0,0 +1,16 @@ +// TODO: Add klever mobile app source name +export const availableWallets = ['begin', 'eternl', 'flint', 'gerowallet', 'lace', 'nami', 'nufi', 'raywallet', 'yoroi'] as const + +export type AvailableWallet = typeof availableWallets[number] + +export enum CardanoWallet { + BEGIN = 'begin', + ETERNL = 'eternl', + FLINT = 'flint', + GERO_WALLET = 'gerowallet', + LACE = 'lace', + NAMI = 'nami', + NUFI = 'nufi', + RAY_WALLET = 'raywallet', + YOROI = 'yoroi', +} diff --git a/src/cardano/connect.spec.ts b/src/cardano/connect.spec.ts new file mode 100644 index 0000000..c79901f --- /dev/null +++ b/src/cardano/connect.spec.ts @@ -0,0 +1,31 @@ +import { NotInjectedError } from '@/errors'; +import { NoAvailableAccountsError } from '@/errors/no-accounts-available-error'; +import { NoProviderAvailableError } from '@/errors/no-provider-available-error'; +import { web3Window } from '@/types'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { connect } from './connect'; + +describe('Connect wallet use case', () => { + const cardanoWebMock = { + yoroi: { + icon: 'data:image/svg', + name: 'yoroi', + apiVersion: '0.3.0', + enable: vi.fn(), + isEnabled: vi.fn(), + }, + } + beforeEach(() => { + delete web3Window.cardano + web3Window.cardano = cardanoWebMock + }) + it('should be able to throw error when window dont have Cardano object', async () => { + delete web3Window.cardano + await expect(connect()).rejects.toThrow(NotInjectedError) + }) + + it('should be able to throw error when have no providers', async () => { + delete web3Window.cardano.yoroi + await expect(connect()).rejects.toThrow(NoProviderAvailableError) + }) +}) diff --git a/src/ada/connect.ts b/src/cardano/connect.ts similarity index 65% rename from src/ada/connect.ts rename to src/cardano/connect.ts index de58df6..f9c3eea 100644 --- a/src/ada/connect.ts +++ b/src/cardano/connect.ts @@ -18,13 +18,18 @@ export async function connect(wallet?: string): Promise { } if (typeof injectedWallet === 'undefined') + // maybe impossible to hit this branch since Cardano API demands a wallet in the browser to be injected. throw new NoProviderAvailableError() - await web3Window.cardano[injectedWallet].enable() - - const usedAddresses: CardanoUsedAddress[] = await web3Window.cardano.getUsedAddresses() - if (usedAddresses.length === 0) - throw new NoAvailableAccountsError() - - return usedAddresses + try { + const api = await web3Window.cardano[injectedWallet].enable() + const usedAddresses: CardanoUsedAddress[] = await api.getUsedAddresses() + if (usedAddresses.length === 0) + throw new NoAvailableAccountsError() + return usedAddresses + } + catch (error) { + console.log(error) + return [] + } } diff --git a/src/cardano/getBalance.ts b/src/cardano/getBalance.ts new file mode 100644 index 0000000..c587e5b --- /dev/null +++ b/src/cardano/getBalance.ts @@ -0,0 +1,20 @@ +import { BalanceFetchError } from '@/errors/balance-fetch-error'; +import { EmptyAddressError } from '@/errors/empty-address-error'; +import type { ApiPromise } from './types'; +import type { Balance } from '@/types'; + +export async function getBalance(api: ApiPromise, address: string): Promise { + if (address.length === 0) + throw new EmptyAddressError() + + try { + const accountBalance = await api.getBalance(address) + return { + free: accountBalance, + frozen: 0, // asset staking never gets "frozen" or "locked" in Cardano Network + } + } + catch (error) { + throw new BalanceFetchError(error as Error) + } +} diff --git a/src/ada/index.ts b/src/cardano/index.ts similarity index 100% rename from src/ada/index.ts rename to src/cardano/index.ts diff --git a/src/cardano/types.ts b/src/cardano/types.ts new file mode 100644 index 0000000..82852ed --- /dev/null +++ b/src/cardano/types.ts @@ -0,0 +1,11 @@ +import type { AvailableWallet } from './available-wallets'; + +export type CardanoProviderProps = Record; + +export type CardanoUsedAddress = string + +export interface ApiPromise { + getBalance: (address: string) => Promise + getUsedAddresses: () => Promise + getUnusedAddresses: () => Promise +} diff --git a/src/index.ts b/src/index.ts index 8fa2d24..4a2c188 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -export * from './ada/index' +export * from './cardano/index' export * from './networks' export * from './substrate/dot/index' export * from './substrate/ksm/index' diff --git a/src/types.ts b/src/types.ts index 2c4bbb1..27d4012 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import type { CardanoProviderProps } from './ada/types' +import type { CardanoProviderProps } from './cardano/types' import type { NetworkKey } from './networks' import type { SubstrateProviderProps } from './substrate/types' @@ -19,7 +19,7 @@ export type ProviderBuilderProps = T extends 'dot' | 'ksm' // TODO: Add type and functions of injected providers export type Web3Window = { injectedWeb3: any - cardano: any + cardano?: any } & Window & typeof globalThis export const web3Window = (window as Web3Window) diff --git a/src/web3-provider.ts b/src/web3-provider.ts index 7ea3a8a..4c0c0df 100644 --- a/src/web3-provider.ts +++ b/src/web3-provider.ts @@ -1,5 +1,5 @@ -import { CardanoProvider } from './ada'; -import type { CardanoProviderProps } from './ada/types'; +import { CardanoProvider } from './cardano'; +import type { CardanoProviderProps } from './cardano/types'; import type { ProviderEntity } from './entities/provider-entity'; import { InvalidNetworkError } from './errors/invalid-network-error'; import type { NetworkData, NetworkKey } from './networks';