Skip to content

Commit 2a51bfb

Browse files
committed
Refactor code and add unit-tests
1 parent 570f39a commit 2a51bfb

File tree

5 files changed

+664
-19
lines changed

5 files changed

+664
-19
lines changed

examples/demo-inkv5/src/main.tsx

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,24 @@ import {
99
alephZero,
1010
ExtensionWallet,
1111
polkadotjs,
12+
popTestnet,
1213
ReactToastifyAdapter,
1314
setupTxToaster,
1415
subwallet,
1516
talisman,
1617
TypinkProvider,
17-
WalletConnect,
18+
walletConnect,
1819
} from 'typink';
1920
import { toast } from 'react-toastify';
2021

2122
setupTxToaster({ adapter: new ReactToastifyAdapter(toast) });
2223

2324
const DEFAULT_CALLER = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; // Alice
24-
const SUPPORTED_NETWORK = [alephZero];
25+
const SUPPORTED_NETWORK = [alephZero, popTestnet];
2526
// if (process.env.NODE_ENV === 'development') {
2627
// SUPPORTED_NETWORK.push(development);
2728
// }
2829

29-
export const walletConnect = new WalletConnect({
30-
name: 'WalletConnect',
31-
id: 'walletconnect',
32-
logo: 'https://raw.githubusercontent.com/dedotdev/typink/feature/wallet-connect/assets/wallets/wallet-connect-logo.svg',
33-
projectId: 'b56e18d47c72ab683b10814fe9495694', // Default
34-
relayUrl: 'wss://relay.walletconnect.com',
35-
metadata: {
36-
name: 'Typink Dapp',
37-
description: 'Typink powered dApp',
38-
url: typeof window !== 'undefined' ? window.location.origin : 'https://typink.dev',
39-
icons: ['https://raw.githubusercontent.com/dedotdev/typink/main/assets/typink/typink-pink-logo.png'],
40-
},
41-
});
42-
4330
const enkrypt = new ExtensionWallet({
4431
name: 'Enkrypt',
4532
id: 'enkrypt',
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { describe, expect, it } from 'vitest';
2+
import { genesisHashToCaipId, convertNetworkInfoToCaipId } from '../chains.js';
3+
import { NetworkInfo, NetworkType } from '../../types.js';
4+
5+
describe('chains utilities', () => {
6+
describe('genesisHashToCaipId', () => {
7+
it('should convert genesis hash to CAIP-2 format', () => {
8+
const genesisHash = '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3';
9+
const result = genesisHashToCaipId(genesisHash);
10+
11+
expect(result).toBe('polkadot:91b171bb158e2d3848fa23a9f1c25182');
12+
});
13+
14+
it('should remove 0x prefix and take first 32 characters', () => {
15+
const genesisHash = '0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890';
16+
const result = genesisHashToCaipId(genesisHash);
17+
18+
expect(result).toBe('polkadot:abcdef1234567890abcdef1234567890');
19+
expect(result.split(':')[1]).toHaveLength(32);
20+
});
21+
22+
it('should handle genesis hash without 0x prefix', () => {
23+
const genesisHash = '91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3';
24+
const result = genesisHashToCaipId(genesisHash);
25+
26+
expect(result).toBe('polkadot:91b171bb158e2d3848fa23a9f1c25182');
27+
});
28+
29+
it('should handle short genesis hash', () => {
30+
const genesisHash = '0xabcd1234';
31+
const result = genesisHashToCaipId(genesisHash);
32+
33+
expect(result).toBe('polkadot:abcd1234');
34+
});
35+
});
36+
37+
describe('convertNetworkInfoToCaipId', () => {
38+
it('should convert multiple networks to CAIP-2 identifiers', () => {
39+
const networks: NetworkInfo[] = [
40+
{
41+
id: 'polkadot',
42+
type: NetworkType.MAINNET,
43+
name: 'Polkadot',
44+
logo: 'polkadot.png',
45+
providers: ['wss://rpc.polkadot.io'],
46+
symbol: 'DOT',
47+
decimals: 10,
48+
genesisHash: '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3',
49+
},
50+
{
51+
id: 'kusama',
52+
type: NetworkType.MAINNET,
53+
name: 'Kusama',
54+
logo: 'kusama.png',
55+
providers: ['wss://kusama-rpc.polkadot.io'],
56+
symbol: 'KSM',
57+
decimals: 12,
58+
genesisHash: '0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe',
59+
},
60+
];
61+
62+
const result = convertNetworkInfoToCaipId(networks);
63+
64+
expect(result).toHaveLength(2);
65+
expect(result[0]).toBe('polkadot:91b171bb158e2d3848fa23a9f1c25182');
66+
expect(result[1]).toBe('polkadot:b0a8d493285c2df73290dfb7e61f870f');
67+
});
68+
69+
it('should filter out networks without genesis hash', () => {
70+
const networks: NetworkInfo[] = [
71+
{
72+
id: 'polkadot',
73+
type: NetworkType.MAINNET,
74+
name: 'Polkadot',
75+
logo: 'polkadot.png',
76+
providers: ['wss://rpc.polkadot.io'],
77+
symbol: 'DOT',
78+
decimals: 10,
79+
genesisHash: '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3',
80+
},
81+
{
82+
id: 'custom',
83+
name: 'Custom Network',
84+
logo: 'custom.png',
85+
providers: ['wss://custom.io'],
86+
symbol: 'CUST',
87+
decimals: 10,
88+
// No genesisHash
89+
},
90+
];
91+
92+
const result = convertNetworkInfoToCaipId(networks);
93+
94+
expect(result).toHaveLength(1);
95+
expect(result[0]).toBe('polkadot:91b171bb158e2d3848fa23a9f1c25182');
96+
});
97+
98+
it('should return empty array for networks without genesis hash', () => {
99+
const networks: NetworkInfo[] = [
100+
{
101+
id: 'custom',
102+
name: 'Custom Network',
103+
logo: 'custom.png',
104+
providers: ['wss://custom.io'],
105+
symbol: 'CUST',
106+
decimals: 10,
107+
},
108+
];
109+
110+
const result = convertNetworkInfoToCaipId(networks);
111+
112+
expect(result).toHaveLength(0);
113+
});
114+
115+
it('should return empty array for empty input', () => {
116+
const result = convertNetworkInfoToCaipId([]);
117+
118+
expect(result).toHaveLength(0);
119+
});
120+
});
121+
});

packages/typink/src/wallets/WalletConnect.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export class WalletConnect extends Wallet<WalletConnectOptions> {
6767

6868
async #connect(): Promise<void> {
6969
assert(this.#provider, 'WalletConnect provider not initialized');
70+
assert(this.#modal, 'WalletConnect modal not initialized');
7071

7172
try {
7273
if (this.#provider.session) {
@@ -93,13 +94,13 @@ export class WalletConnect extends Wallet<WalletConnectOptions> {
9394
await this.#modal!.openModal({ uri });
9495
}
9596

96-
const race = new Promise<never>((_, reject) => {
97+
const userCloseModal = new Promise<never>((_, reject) => {
9798
this.#modal!.subscribeModal((state: { open: boolean }) => {
9899
!state.open && reject(new DedotError('User closed WalletConnect modal'));
99100
});
100101
});
101102

102-
this.#provider.session = await Promise.race([approval(), race]);
103+
this.#provider.session = await Promise.race([approval(), userCloseModal]);
103104
this.#modal!.closeModal();
104105
this.#accounts = this.#getAccounts();
105106
}
@@ -283,7 +284,7 @@ export class WalletConnect extends Wallet<WalletConnectOptions> {
283284
const accounts = this.#getInjectedAccounts();
284285

285286
return {
286-
enable: async (): Promise<{ accounts: InjectedAccounts; signer: InjectedSigner }> => {
287+
enable: async (_origin: string): Promise<{ accounts: InjectedAccounts; signer: InjectedSigner }> => {
287288
if (!this.#provider?.session) {
288289
throw new Error('WalletConnect session not established');
289290
}

0 commit comments

Comments
 (0)