@getpara/graz-connector 0.1.0-alpha.6 → 2.0.0-dev.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/connector.ts CHANGED
@@ -1,77 +1,66 @@
1
- import ParaWeb from '@getpara/react-sdk';
2
- import type { Environment, ParaModalProps } from '@getpara/react-sdk';
3
- import type { Wallet, Key as GrazKey } from 'graz';
4
- import { getChainInfo } from 'graz';
5
- import type {
6
- OfflineAminoSigner,
7
- OfflineDirectSigner,
8
- AminoSignResponse,
9
- StdSignDoc,
10
- StdSignature,
11
- DirectSignResponse,
12
- AccountData,
13
- Algo,
14
- SignDoc as KeplrSignDoc,
15
- SignDoc,
16
- } from '@keplr-wallet/types';
17
- import { ParaAminoSigner, ParaProtoSigner } from '@getpara/cosmjs-v0-integration';
18
1
  import { fromBech32 } from '@cosmjs/encoding';
19
- import { renderModal } from './connectorModal.js';
20
- import Long from 'long';
2
+ import { SignDoc } from 'cosmjs-types/cosmos/tx/v1beta1/tx.js';
3
+ import { Wallet, SignDoc as GrazSignDoc } from 'graz';
4
+ import { ParaAminoSigner, ParaProtoSigner } from '@getpara/cosmjs-v0-integration';
5
+ import { ParaWeb, Wallet as ParaWallet } from '@getpara/web-sdk';
6
+ import { Algo, DirectSignResponse, OfflineDirectSigner } from '@cosmjs/proto-signing';
7
+ import { AccountData, AminoSignResponse, OfflineAminoSigner, StdSignature, StdSignDoc } from '@cosmjs/amino';
8
+ import { ChainInfo, KeplrSignOptions } from '@keplr-wallet/types';
21
9
 
22
- const TEN_MINUTES_MS = 600000;
10
+ export type ParaGrazConnectorEvents = {
11
+ onEnabled?: (chainIds: string[], connector: ParaGrazConnector) => void;
12
+ };
23
13
 
24
14
  export interface ParaGrazConfig {
25
- apiKey: string;
26
- env: Environment;
27
- modalProps?: ParaModalProps;
15
+ paraWeb: ParaWeb;
16
+ events?: ParaGrazConnectorEvents;
17
+ noModal?: boolean;
28
18
  }
29
19
 
30
- export class ParaOfflineSigner implements OfflineDirectSigner {
31
- private chainId: string;
32
- private paraWebClient: ParaWeb;
20
+ export function toArray<T>(v: T | T[]): T[] {
21
+ return Array.isArray(v) ? v : [v];
22
+ }
33
23
 
34
- constructor(chainId: string, paraWebClient: ParaWeb) {
35
- this.chainId = chainId;
36
- this.paraWebClient = paraWebClient;
24
+ class ParaOfflineSigner implements OfflineDirectSigner {
25
+ constructor(
26
+ protected readonly chainId: string,
27
+ protected readonly connector: ParaGrazConnector,
28
+ ) {}
29
+ protected get para() {
30
+ return this.connector.getParaWebClient();
31
+ }
32
+ protected get prefix() {
33
+ return this.connector.getBech32Prefix(this.chainId);
34
+ }
35
+ protected async wallet() {
36
+ return this.connector.getFirstWallet();
37
37
  }
38
-
39
38
  async getAccounts(): Promise<readonly AccountData[]> {
40
- const key = await getKey(this.paraWebClient, this.chainId);
39
+ const key = await this.connector.getKey(this.chainId);
41
40
  return [
42
41
  {
43
- address: key.address,
42
+ address: key.bech32Address,
44
43
  algo: key.algo as Algo,
45
- pubkey: key.pubkey,
44
+ pubkey: key.pubKey,
46
45
  },
47
46
  ];
48
47
  }
49
-
50
- async signDirect(signerAddress: string, signDoc: KeplrSignDoc): Promise<DirectSignResponse> {
48
+ async signDirect(signerAddress: string, signDoc: SignDoc): Promise<DirectSignResponse> {
51
49
  if (this.chainId !== signDoc.chainId) {
52
- throw new Error('Chain ID does not match signer chain ID');
50
+ throw new Error(`Para connector: signDirect chainId mismatch (expected ${this.chainId}, got ${signDoc.chainId})`);
53
51
  }
54
-
55
52
  const accounts = await this.getAccounts();
56
- if (accounts.find(account => account.address !== signerAddress)) {
57
- throw new Error('Signer address does not match wallet address');
53
+ if (accounts.every(a => a.address !== signerAddress)) {
54
+ throw new Error(`Para connector: signerAddress ${signerAddress} not found in wallet`);
58
55
  }
59
-
60
- const convertedSignDoc = {
61
- bodyBytes: signDoc.bodyBytes,
62
- authInfoBytes: signDoc.authInfoBytes,
63
- chainId: signDoc.chainId,
64
- accountNumber: typeof signDoc.accountNumber === 'string' ? signDoc.accountNumber : signDoc.accountNumber.toString(),
65
- };
66
-
67
- const result = await requestSignature(this.paraWebClient, this.chainId, signerAddress, convertedSignDoc);
68
-
56
+ const signer = new ParaProtoSigner(this.para, this.prefix, (await this.wallet()).id);
57
+ const result = await signer.signDirect(signerAddress, signDoc);
69
58
  return {
70
59
  signed: {
71
60
  bodyBytes: result.signed.bodyBytes,
72
61
  authInfoBytes: result.signed.authInfoBytes,
73
62
  chainId: result.signed.chainId,
74
- accountNumber: Long.fromString(result.signed.accountNumber.toString()),
63
+ accountNumber: result.signed.accountNumber,
75
64
  },
76
65
  signature: result.signature,
77
66
  };
@@ -79,292 +68,202 @@ export class ParaOfflineSigner implements OfflineDirectSigner {
79
68
  }
80
69
 
81
70
  export class ParaGrazConnector implements Omit<Wallet, 'experimentalSuggestChain'> {
82
- private paraWebClient: ParaWeb;
83
- private config: ParaGrazConfig;
84
- private isModalClosed: boolean;
85
-
86
- constructor(config: ParaGrazConfig) {
87
- if (!config || !config.apiKey || !config.env) {
88
- throw new Error('Para Connector: Missing API Key or Environment in config.');
71
+ protected paraWebClient: ParaWeb;
72
+ protected enabledChainIds = new Set<string>();
73
+ protected readonly events?: ParaGrazConnectorEvents;
74
+ protected noModal?: boolean;
75
+ constructor(
76
+ protected readonly config: ParaGrazConfig,
77
+ protected readonly chains: ChainInfo[] | null = null,
78
+ ) {
79
+ if (!config?.paraWeb) {
80
+ throw new Error('Para connector: missing paraWeb instance in config');
89
81
  }
90
- this.config = config;
91
- this.paraWebClient = new ParaWeb(config.env, config.apiKey);
92
- this.isModalClosed = true;
82
+ this.events = config.events;
83
+ this.paraWebClient = config.paraWeb;
84
+ this.noModal = config.noModal;
93
85
  }
94
-
95
- closeModal = () => {
96
- this.isModalClosed = true;
97
- };
98
-
99
- private async waitForLogin(timeoutMs = TEN_MINUTES_MS): Promise<boolean> {
100
- const startTime = Date.now();
101
- while (Date.now() - startTime < timeoutMs) {
102
- if (await this.paraWebClient.isFullyLoggedIn()) {
103
- return true;
104
- }
105
-
106
- if (this.isModalClosed) {
107
- throw new Error('user closed modal');
108
- }
109
-
110
- await new Promise(resolve => setTimeout(resolve, 2000));
86
+ protected async ensureChainEnabled(chainId: string): Promise<void> {
87
+ if (!this.enabledChainIds.has(chainId)) {
88
+ throw new Error(`Para connector: chain ${chainId} was not enabled via wallet.enable()`);
89
+ }
90
+ if (!(await this.paraWebClient.isFullyLoggedIn())) {
91
+ throw new Error('Para connector: wallet is not connected – call enable() first');
111
92
  }
112
-
113
- throw new Error('timed out waiting for user to log in');
114
93
  }
115
-
116
- private async waitForAccounts(chainIds: string | string[], timeoutMs = 5000): Promise<boolean> {
117
- const startTime = Date.now();
118
- while (Date.now() - startTime < timeoutMs) {
119
- const wallets = Object.values(this.paraWebClient.getWalletsByType('COSMOS'));
120
- if (wallets && wallets.length > 0) {
121
- return true;
122
- }
123
- await new Promise(resolve => setTimeout(resolve, 500));
94
+ protected async waitForLogin(timeoutMs = 60_000): Promise<void> {
95
+ const deadline = Date.now() + timeoutMs;
96
+ let delay = 500;
97
+ const MAX_DELAY = 5_000;
98
+ while (true) {
99
+ if (await this.paraWebClient.isFullyLoggedIn()) return;
100
+ if (Date.now() >= deadline) throw new Error('Para connector: login timeout');
101
+ await new Promise(r => setTimeout(r, delay));
102
+ delay = Math.min(delay * 1.5, MAX_DELAY);
124
103
  }
125
-
126
- throw new Error('timed out waiting for accounts to load');
127
104
  }
128
105
 
129
- async enable(chainIds: string | string[]): Promise<void> {
130
- if (await this.paraWebClient.isFullyLoggedIn()) {
131
- const wallets = Object.values(this.paraWebClient.getWalletsByType('COSMOS'));
132
- if (wallets && wallets.length > 0) {
133
- return;
134
- }
106
+ protected async waitForAccounts(timeoutMs = 5_000): Promise<ParaWallet[]> {
107
+ const deadline = Date.now() + timeoutMs;
108
+ let delay = 250;
109
+ const MAX_DELAY = 1_000;
110
+ while (true) {
111
+ const wallets = this.paraWebClient.getWalletsByType('COSMOS');
112
+ if (wallets.length) return wallets;
113
+ if (Date.now() >= deadline) throw new Error('Para connector: no COSMOS wallets found after login');
114
+ await new Promise(r => setTimeout(r, delay));
115
+ delay = Math.min(delay * 1.5, MAX_DELAY);
135
116
  }
136
-
137
- this.isModalClosed = false;
138
- renderModal(this.paraWebClient, this.config.modalProps, () => {
139
- this.isModalClosed = true;
140
- });
141
-
142
- await this.waitForLogin();
143
-
117
+ }
118
+ protected async hasCosmosWallet(): Promise<boolean> {
119
+ return (await this.paraWebClient.isFullyLoggedIn()) && this.paraWebClient.getWalletsByType('COSMOS').length > 0;
120
+ }
121
+ async enable(chainIdsInput: string | string[]): Promise<void> {
122
+ const chainIds = toArray(chainIdsInput);
123
+ const previousEnabled = new Set(this.enabledChainIds);
144
124
  try {
145
- await this.waitForAccounts(chainIds);
146
- } catch (error) {
147
- throw new Error('accounts not available after login');
125
+ chainIds.forEach(id => this.enabledChainIds.add(id));
126
+ if (await this.hasCosmosWallet()) {
127
+ this.events?.onEnabled?.(chainIds, this);
128
+ return;
129
+ }
130
+ if (!this.noModal) {
131
+ throw new Error('Modal rendering not supported in core library. Use @getpara/graz-integration for modal support.');
132
+ }
133
+ await this.waitForLogin();
134
+ await this.waitForAccounts();
135
+ this.events?.onEnabled?.(chainIds, this);
136
+ } catch (err) {
137
+ this.enabledChainIds = previousEnabled;
138
+ throw err;
148
139
  }
149
140
  }
150
141
 
142
+ async disconnect(): Promise<void> {
143
+ await this.paraWebClient.logout();
144
+ this.enabledChainIds.clear();
145
+ }
146
+ async getFirstWallet(): Promise<ParaWallet> {
147
+ const [wallet] = await this.waitForAccounts();
148
+ return wallet;
149
+ }
150
+ getBech32Prefix(chainId: string): string {
151
+ return this.chains?.find(c => c.chainId === chainId)?.bech32Config?.bech32PrefixAccAddr || 'cosmos';
152
+ }
151
153
  getParaWebClient(): ParaWeb {
152
154
  return this.paraWebClient;
153
155
  }
154
-
155
156
  getConfig(): ParaGrazConfig {
156
157
  return this.config;
157
158
  }
158
-
159
- async getKey(chainId: string): Promise<GrazKey> {
160
- const wallets = Object.values(this.paraWebClient.getWalletsByType('COSMOS'));
161
-
162
- if (wallets.length === 0) {
163
- throw new Error(`Para Connector: No wallets found for chainId ${chainId}`);
164
- }
165
-
166
- // Get the bech32 prefix from chain info
167
- const bech32Prefix = this.getBech32Prefix(chainId);
168
-
169
- const walletSigner = new ParaProtoSigner(this.paraWebClient, bech32Prefix, wallets[0].id);
170
- const accountData = await walletSigner.getAccounts();
171
- if (accountData.length === 0) {
172
- throw new Error(`Para Connector: No accounts found for wallet ${wallets[0].id}`);
173
- }
174
-
175
- const account = accountData[0];
159
+ protected buildHybridSigner(chainId: string): OfflineAminoSigner & OfflineDirectSigner {
160
+ const aminoSigner = this.getOfflineSignerOnlyAmino(chainId);
161
+ const directSigner = new ParaOfflineSigner(chainId, this);
176
162
  return {
177
- address: fromBech32(account.address).data,
178
- bech32Address: account.address,
163
+ getAccounts: () => directSigner.getAccounts(),
164
+ signAmino: (signer: string, signDoc: StdSignDoc) => aminoSigner.signAmino(signer, signDoc),
165
+ signDirect: (signer: string, signDoc: SignDoc) => directSigner.signDirect(signer, signDoc),
166
+ } as unknown as OfflineAminoSigner & OfflineDirectSigner;
167
+ }
168
+ async getKey(chainId: string) {
169
+ await this.ensureChainEnabled(chainId);
170
+ const wallet = await this.getFirstWallet();
171
+ const signer = new ParaProtoSigner(this.paraWebClient, this.getBech32Prefix(chainId), wallet.id);
172
+ const [account] = await signer.getAccounts();
173
+ if (!account) throw new Error(`Para connector: wallet ${wallet.id} has no Cosmos accounts`);
174
+ return {
175
+ name: 'Para Wallet',
179
176
  algo: account.algo,
180
- name: account.address,
181
177
  pubKey: account.pubkey,
178
+ address: fromBech32(account.address).data,
179
+ bech32Address: account.address,
182
180
  isKeystone: false,
183
181
  isNanoLedger: false,
184
182
  };
185
183
  }
186
-
187
- getOfflineSigner(chainId: string): OfflineAminoSigner & OfflineDirectSigner {
188
- const aminoSigner = this.getOfflineSignerOnlyAmino(chainId);
189
- const directSigner = new ParaOfflineSigner(chainId, this.paraWebClient);
190
-
191
- const combinedSigner = {
192
- getAccounts: () => directSigner.getAccounts(),
193
- signAmino: (signerAddress: string, signDoc: StdSignDoc) => aminoSigner.signAmino(signerAddress, signDoc),
194
- signDirect: (signerAddress: string, signDoc: SignDoc) => directSigner.signDirect(signerAddress, signDoc),
195
- };
196
-
197
- return combinedSigner as unknown as OfflineAminoSigner & OfflineDirectSigner;
198
- }
199
-
200
184
  getOfflineSignerOnlyAmino(chainId: string): OfflineAminoSigner {
201
- const wallets = Object.values(this.paraWebClient.getWalletsByType('COSMOS'));
202
- if (wallets.length === 0) {
203
- throw new Error(`Para Connector: No wallets found for chainId ${chainId}`);
185
+ void this.ensureChainEnabled(chainId); // fire & forget – returns void
186
+ const wallet = this.paraWebClient.getWalletsByType('COSMOS')[0];
187
+ if (!wallet) {
188
+ throw new Error(`Para connector: no wallets found when requesting Amino signer for ${chainId}`);
204
189
  }
205
-
206
- const bech32Prefix = this.getBech32Prefix(chainId);
207
-
208
- return new ParaAminoSigner(this.paraWebClient, bech32Prefix, wallets[0].id);
190
+ return new ParaAminoSigner(this.paraWebClient, this.getBech32Prefix(chainId), wallet.id);
209
191
  }
210
-
211
- getOfflineSignerAuto(chainId: string): Promise<OfflineAminoSigner | OfflineDirectSigner> {
212
- return Promise.resolve(this.getOfflineSignerOnlyAmino(chainId));
192
+ getOfflineSigner(chainId: string): OfflineAminoSigner & OfflineDirectSigner {
193
+ void this.ensureChainEnabled(chainId);
194
+ return this.buildHybridSigner(chainId);
213
195
  }
214
-
215
- async signAmino(chainId: string, signer: string, signDoc: StdSignDoc): Promise<AminoSignResponse> {
216
- await this.ensureConnected();
217
-
218
- const wallets = Object.values(this.paraWebClient.getWalletsByType('COSMOS'));
219
- if (wallets.length === 0) {
220
- throw new Error(`Para Connector: No wallets found for chainId ${chainId}`);
196
+ async getOfflineSignerAuto(chainId: string): Promise<OfflineAminoSigner | OfflineDirectSigner> {
197
+ void this.ensureChainEnabled(chainId);
198
+ return this.buildHybridSigner(chainId);
199
+ }
200
+ async signAmino(
201
+ chainId: string,
202
+ signer: string,
203
+ signDoc: StdSignDoc,
204
+ _signOptions?: KeplrSignOptions,
205
+ ): Promise<AminoSignResponse> {
206
+ await this.ensureChainEnabled(chainId);
207
+ try {
208
+ const wallet = await this.getFirstWallet();
209
+ const signerImpl = new ParaAminoSigner(this.paraWebClient, this.getBech32Prefix(chainId), wallet.id);
210
+ return await signerImpl.signAmino(signer, signDoc);
211
+ } catch (err) {
212
+ throw new Error(`Para connector: signAmino failed – ${(err as Error).message}`);
221
213
  }
222
-
223
- const bech32Prefix = this.getBech32Prefix(chainId);
224
-
225
- const walletSigner = new ParaAminoSigner(this.paraWebClient, bech32Prefix, wallets[0].id);
226
-
227
- return walletSigner.signAmino(signer, signDoc);
228
214
  }
229
-
230
215
  async signDirect(
231
216
  chainId: string,
232
217
  signer: string,
233
- signDoc: {
234
- bodyBytes?: Uint8Array;
235
- authInfoBytes?: Uint8Array;
236
- chainId?: string;
237
- accountNumber?: Long;
238
- },
218
+ signDoc: GrazSignDoc,
219
+ _signOptions?: KeplrSignOptions,
239
220
  ): Promise<DirectSignResponse> {
240
- await this.ensureConnected();
241
-
242
- const wallets = Object.values(this.paraWebClient.getWalletsByType('COSMOS'));
243
- if (wallets.length === 0) {
244
- throw new Error(`Para Connector: No wallets found for chainId ${chainId}`);
221
+ await this.ensureChainEnabled(chainId);
222
+ try {
223
+ const wallet = await this.getFirstWallet();
224
+ const signerImpl = new ParaProtoSigner(this.paraWebClient, this.getBech32Prefix(chainId), wallet.id);
225
+ const convertedSignDoc: SignDoc = {
226
+ bodyBytes: signDoc.bodyBytes ?? new Uint8Array(),
227
+ authInfoBytes: signDoc.authInfoBytes ?? new Uint8Array(),
228
+ chainId: signDoc.chainId,
229
+ accountNumber: typeof signDoc.accountNumber === 'bigint' ? signDoc.accountNumber : BigInt(signDoc.accountNumber),
230
+ };
231
+ const result = await signerImpl.signDirect(signer, convertedSignDoc);
232
+ return {
233
+ signed: {
234
+ bodyBytes: result.signed.bodyBytes,
235
+ authInfoBytes: result.signed.authInfoBytes,
236
+ chainId: result.signed.chainId,
237
+ accountNumber: result.signed.accountNumber,
238
+ },
239
+ signature: result.signature,
240
+ };
241
+ } catch (err) {
242
+ throw new Error(`Para connector: signDirect failed – ${(err as Error).message}`);
245
243
  }
246
-
247
- const convertedSignDoc = {
248
- bodyBytes: signDoc.bodyBytes || new Uint8Array(),
249
- authInfoBytes: signDoc.authInfoBytes || new Uint8Array(),
250
- chainId: signDoc.chainId || chainId,
251
- accountNumber: signDoc.accountNumber ? signDoc.accountNumber.toString() : '0',
252
- };
253
-
254
- const bech32Prefix = this.getBech32Prefix(chainId);
255
-
256
- const walletSigner = new ParaProtoSigner(this.paraWebClient, bech32Prefix, wallets[0].id);
257
-
258
- const result = await walletSigner.signDirect(signer, {
259
- ...convertedSignDoc,
260
- accountNumber: BigInt(convertedSignDoc.accountNumber),
261
- });
262
-
263
- return {
264
- signed: {
265
- bodyBytes: result.signed.bodyBytes,
266
- authInfoBytes: result.signed.authInfoBytes,
267
- chainId: result.signed.chainId,
268
- accountNumber: Long.fromString(result.signed.accountNumber.toString()),
269
- },
270
- signature: result.signature,
271
- };
272
244
  }
273
-
274
245
  async signArbitrary(chainId: string, signer: string, data: string | Uint8Array): Promise<StdSignature> {
275
- await this.ensureConnected();
276
-
277
- let encodedData: string;
278
- let isADR36WithString = false;
279
-
280
- if (typeof data === 'string') {
281
- encodedData = Buffer.from(data).toString('base64');
282
- isADR36WithString = true;
283
- } else {
284
- encodedData = Buffer.from(data).toString('base64');
285
- }
286
-
246
+ await this.ensureChainEnabled(chainId);
247
+ const encodedData =
248
+ typeof data === 'string' ? Buffer.from(data, 'utf-8').toString('base64') : Buffer.from(data).toString('base64');
287
249
  const signDoc = {
288
250
  chain_id: '',
289
251
  account_number: '0',
290
252
  sequence: '0',
291
- fee: {
292
- gas: '0',
293
- amount: [],
294
- },
253
+ fee: { gas: '0', amount: [] },
295
254
  msgs: [
296
255
  {
297
256
  type: 'sign/MsgSignData',
298
- value: {
299
- signer,
300
- data: encodedData,
301
- },
257
+ value: { signer, data: encodedData },
302
258
  },
303
259
  ],
304
260
  memo: '',
305
261
  };
306
-
307
- const response = await this.signAmino(chainId, signer, signDoc);
308
-
309
- return response.signature;
310
- }
311
-
312
- async disconnect(): Promise<void> {
313
- await this.paraWebClient.logout();
314
- }
315
-
316
- private async ensureConnected(): Promise<void> {
317
- const isConnected = await this.paraWebClient.isFullyLoggedIn();
318
- if (!isConnected) {
319
- throw new Error('Wallet is not connected, please connect first');
320
- }
321
- }
322
-
323
- private getBech32Prefix(chainId: string): string {
324
- const chainInfo = getChainInfo({ chainId });
325
- if (chainInfo?.bech32Config?.bech32PrefixAccAddr) {
326
- return chainInfo.bech32Config.bech32PrefixAccAddr;
262
+ try {
263
+ const response = await this.signAmino(chainId, signer, signDoc);
264
+ return response.signature;
265
+ } catch (err) {
266
+ throw new Error(`Para connector: signArbitrary failed – ${(err as Error).message}`);
327
267
  }
328
-
329
- return 'cosmos';
330
- }
331
- }
332
-
333
- async function getKey(paraWebClient: ParaWeb, chainId: string) {
334
- const wallets = Object.values(paraWebClient.getWalletsByType('COSMOS'));
335
-
336
- if (wallets.length < 1) {
337
- throw Error('No wallets available');
338
- }
339
-
340
- const chainInfo = getChainInfo({ chainId });
341
- const bech32Prefix = chainInfo?.bech32Config?.bech32PrefixAccAddr || 'cosmos';
342
-
343
- const walletSigner = new ParaProtoSigner(paraWebClient, bech32Prefix, wallets[0].id);
344
-
345
- const accountData = (await walletSigner.getAccounts())[0];
346
- if (!accountData) {
347
- throw new Error('No account data found');
348
- }
349
-
350
- return accountData;
351
- }
352
-
353
- async function requestSignature(paraWebClient: ParaWeb, chainId: string, signerAddress: string, signDoc: any) {
354
- const isConnected = await paraWebClient.isFullyLoggedIn();
355
- if (!isConnected) {
356
- throw new Error('Wallet is not connected, please connect first');
357
- }
358
-
359
- const wallets = Object.values(paraWebClient.getWalletsByType('COSMOS'));
360
- if (wallets.length === 0) {
361
- throw new Error('No wallets available');
362
268
  }
363
-
364
- const chainInfo = getChainInfo({ chainId });
365
- const bech32Prefix = chainInfo?.bech32Config?.bech32PrefixAccAddr || 'cosmos';
366
-
367
- const walletSigner = new ParaProtoSigner(paraWebClient, bech32Prefix, wallets[0].id);
368
-
369
- return walletSigner.signDirect(signerAddress, signDoc);
370
269
  }
package/src/index.ts CHANGED
@@ -1,3 +1,2 @@
1
- export { WalletType, AuthLayout, AuthMethod, OAuthMethod, Environment } from '@getpara/react-sdk';
2
- export { ParaGrazConnector } from './connector.js';
1
+ export { toArray, ParaGrazConnector } from './connector.js';
3
2
  export type { ParaGrazConfig } from './connector.js';
package/tsconfig.json CHANGED
@@ -6,8 +6,8 @@
6
6
  "jsx": "react-jsx",
7
7
  "module": "ESNext",
8
8
  "declaration": true,
9
- "declarationDir": "dist"
9
+ "declarationDir": "./dist"
10
10
  },
11
- "include": ["**/*.ts", "**/*.tsx"],
12
- "exclude": ["node_modules", "dist"]
11
+ "include": ["src/**/*.ts", "src/**/*.tsx"],
12
+ "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx", "__tests__"]
13
13
  }
@@ -0,0 +1,22 @@
1
+ import { mergeConfig } from 'vite';
2
+ import baseConfig from '../../vitest.config.js';
3
+
4
+ export default mergeConfig(baseConfig, {
5
+ test: {
6
+ environment: 'jsdom',
7
+ coverage: {
8
+ provider: 'v8',
9
+ reporter: ['html', 'text'],
10
+ all: true,
11
+ include: ['src/**/*.{ts,tsx,js,jsx}'],
12
+ thresholds: {
13
+ lines: 98,
14
+ functions: 90,
15
+ branches: 98,
16
+ statements: 98,
17
+ },
18
+ reportOnFailure: true,
19
+ exclude: ['src/index.ts'],
20
+ },
21
+ },
22
+ });
@@ -1,46 +0,0 @@
1
- "use client";
2
- var __defProp = Object.defineProperty;
3
- var __defProps = Object.defineProperties;
4
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
- var __spreadValues = (a, b) => {
10
- for (var prop in b || (b = {}))
11
- if (__hasOwnProp.call(b, prop))
12
- __defNormalProp(a, prop, b[prop]);
13
- if (__getOwnPropSymbols)
14
- for (var prop of __getOwnPropSymbols(b)) {
15
- if (__propIsEnum.call(b, prop))
16
- __defNormalProp(a, prop, b[prop]);
17
- }
18
- return a;
19
- };
20
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
- var __async = (__this, __arguments, generator) => {
22
- return new Promise((resolve, reject) => {
23
- var fulfilled = (value) => {
24
- try {
25
- step(generator.next(value));
26
- } catch (e) {
27
- reject(e);
28
- }
29
- };
30
- var rejected = (value) => {
31
- try {
32
- step(generator.throw(value));
33
- } catch (e) {
34
- reject(e);
35
- }
36
- };
37
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
38
- step((generator = generator.apply(__this, __arguments)).next());
39
- });
40
- };
41
-
42
- export {
43
- __spreadValues,
44
- __spreadProps,
45
- __async
46
- };
@@ -1,2 +0,0 @@
1
- import ParaWeb, { ParaModalProps } from '@getpara/react-sdk';
2
- export declare function renderModal(para: ParaWeb, modalProps: Partial<ParaModalProps>, onCloseArg: () => void): void;