@getpara/graz-connector 2.0.0-dev.10 → 2.0.0-dev.12

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/dist/connector.js CHANGED
@@ -38,23 +38,27 @@ class ParaOfflineSigner {
38
38
  signDirect(signerAddress, signDoc) {
39
39
  return __async(this, null, function* () {
40
40
  if (this.chainId !== signDoc.chainId) {
41
- throw new Error(`Para connector: signDirect chainId mismatch (expected ${this.chainId}, got ${signDoc.chainId})`);
41
+ throw new Error(`Chain ID mismatch: expected ${this.chainId}, got ${signDoc.chainId}`);
42
42
  }
43
43
  const accounts = yield this.getAccounts();
44
44
  if (accounts.every((a) => a.address !== signerAddress)) {
45
- throw new Error(`Para connector: signerAddress ${signerAddress} not found in wallet`);
45
+ throw new Error(`Signer address ${signerAddress} not found in wallet`);
46
46
  }
47
47
  const signer = new ParaProtoSigner(this.para, this.prefix, (yield this.wallet()).id);
48
- const result = yield signer.signDirect(signerAddress, signDoc);
49
- return {
50
- signed: {
51
- bodyBytes: result.signed.bodyBytes,
52
- authInfoBytes: result.signed.authInfoBytes,
53
- chainId: result.signed.chainId,
54
- accountNumber: result.signed.accountNumber
55
- },
56
- signature: result.signature
57
- };
48
+ try {
49
+ const result = yield signer.signDirect(signerAddress, signDoc);
50
+ return {
51
+ signed: {
52
+ bodyBytes: result.signed.bodyBytes,
53
+ authInfoBytes: result.signed.authInfoBytes,
54
+ chainId: result.signed.chainId,
55
+ accountNumber: result.signed.accountNumber
56
+ },
57
+ signature: result.signature
58
+ };
59
+ } catch (err) {
60
+ throw new Error(`Direct signing failed: ${err instanceof Error ? err.message : "Unknown error"}`);
61
+ }
58
62
  });
59
63
  }
60
64
  }
@@ -64,7 +68,7 @@ class ParaGrazConnector {
64
68
  this.chains = chains;
65
69
  this.enabledChainIds = /* @__PURE__ */ new Set();
66
70
  if (!(config == null ? void 0 : config.paraWeb)) {
67
- throw new Error("Para connector: missing paraWeb instance in config");
71
+ throw new Error("ParaWeb instance required in config");
68
72
  }
69
73
  this.events = config.events;
70
74
  this.paraWebClient = config.paraWeb;
@@ -73,10 +77,10 @@ class ParaGrazConnector {
73
77
  ensureChainEnabled(chainId) {
74
78
  return __async(this, null, function* () {
75
79
  if (!this.enabledChainIds.has(chainId)) {
76
- throw new Error(`Para connector: chain ${chainId} was not enabled via wallet.enable()`);
80
+ throw new Error(`Chain ${chainId} not enabled. Call enable() first`);
77
81
  }
78
82
  if (!(yield this.paraWebClient.isFullyLoggedIn())) {
79
- throw new Error("Para connector: wallet is not connected \u2013 call enable() first");
83
+ throw new Error("Para wallet not authenticated");
80
84
  }
81
85
  });
82
86
  }
@@ -86,8 +90,12 @@ class ParaGrazConnector {
86
90
  let delay = 500;
87
91
  const MAX_DELAY = 5e3;
88
92
  while (true) {
89
- if (yield this.paraWebClient.isFullyLoggedIn()) return;
90
- if (Date.now() >= deadline) throw new Error("Para connector: login timeout");
93
+ if (yield this.paraWebClient.isFullyLoggedIn()) {
94
+ return;
95
+ }
96
+ if (Date.now() >= deadline) {
97
+ throw new Error(`Login timeout after ${timeoutMs / 1e3}s`);
98
+ }
91
99
  yield new Promise((r) => setTimeout(r, delay));
92
100
  delay = Math.min(delay * 1.5, MAX_DELAY);
93
101
  }
@@ -100,8 +108,12 @@ class ParaGrazConnector {
100
108
  const MAX_DELAY = 1e3;
101
109
  while (true) {
102
110
  const wallets = this.paraWebClient.getWalletsByType("COSMOS");
103
- if (wallets.length) return wallets;
104
- if (Date.now() >= deadline) throw new Error("Para connector: no COSMOS wallets found after login");
111
+ if (wallets.length) {
112
+ return wallets;
113
+ }
114
+ if (Date.now() >= deadline) {
115
+ throw new Error("No Cosmos wallets found");
116
+ }
105
117
  yield new Promise((r) => setTimeout(r, delay));
106
118
  delay = Math.min(delay * 1.5, MAX_DELAY);
107
119
  }
@@ -109,7 +121,9 @@ class ParaGrazConnector {
109
121
  }
110
122
  hasCosmosWallet() {
111
123
  return __async(this, null, function* () {
112
- return (yield this.paraWebClient.isFullyLoggedIn()) && this.paraWebClient.getWalletsByType("COSMOS").length > 0;
124
+ const isLoggedIn = yield this.paraWebClient.isFullyLoggedIn();
125
+ const wallets = this.paraWebClient.getWalletsByType("COSMOS");
126
+ return isLoggedIn && wallets.length > 0;
113
127
  });
114
128
  }
115
129
  enable(chainIdsInput) {
@@ -124,32 +138,45 @@ class ParaGrazConnector {
124
138
  return;
125
139
  }
126
140
  if (!this.noModal) {
127
- throw new Error("Modal rendering not supported in core library. Use @getpara/graz-integration for modal support.");
141
+ throw new Error("Modal not supported. Use @getpara/graz-integration or set noModal: true");
128
142
  }
129
143
  yield this.waitForLogin();
130
144
  yield this.waitForAccounts();
131
145
  (_d = (_c = this.events) == null ? void 0 : _c.onEnabled) == null ? void 0 : _d.call(_c, chainIds, this);
132
146
  } catch (err) {
133
147
  this.enabledChainIds = previousEnabled;
134
- throw err;
148
+ if (err instanceof Error) {
149
+ throw err;
150
+ }
151
+ throw new Error("Failed to enable Para wallet");
135
152
  }
136
153
  });
137
154
  }
138
155
  disconnect() {
139
156
  return __async(this, null, function* () {
140
- yield this.paraWebClient.logout();
141
- this.enabledChainIds.clear();
157
+ try {
158
+ yield this.paraWebClient.logout();
159
+ } catch (err) {
160
+ throw new Error("Disconnect failed");
161
+ } finally {
162
+ this.enabledChainIds.clear();
163
+ }
142
164
  });
143
165
  }
144
166
  getFirstWallet() {
145
167
  return __async(this, null, function* () {
146
- const [wallet] = yield this.waitForAccounts();
147
- return wallet;
168
+ try {
169
+ const [wallet] = yield this.waitForAccounts();
170
+ return wallet;
171
+ } catch (err) {
172
+ throw new Error("No Para wallet available");
173
+ }
148
174
  });
149
175
  }
150
176
  getBech32Prefix(chainId) {
151
177
  var _a, _b, _c;
152
- return ((_c = (_b = (_a = this.chains) == null ? void 0 : _a.find((c) => c.chainId === chainId)) == null ? void 0 : _b.bech32Config) == null ? void 0 : _c.bech32PrefixAccAddr) || "cosmos";
178
+ const prefix = ((_c = (_b = (_a = this.chains) == null ? void 0 : _a.find((c) => c.chainId === chainId)) == null ? void 0 : _b.bech32Config) == null ? void 0 : _c.bech32PrefixAccAddr) || "cosmos";
179
+ return prefix;
153
180
  }
154
181
  getParaWebClient() {
155
182
  return this.paraWebClient;
@@ -168,27 +195,36 @@ class ParaGrazConnector {
168
195
  }
169
196
  getKey(chainId) {
170
197
  return __async(this, null, function* () {
171
- yield this.ensureChainEnabled(chainId);
172
- const wallet = yield this.getFirstWallet();
173
- const signer = new ParaProtoSigner(this.paraWebClient, this.getBech32Prefix(chainId), wallet.id);
174
- const [account] = yield signer.getAccounts();
175
- if (!account) throw new Error(`Para connector: wallet ${wallet.id} has no Cosmos accounts`);
176
- return {
177
- name: "Para Wallet",
178
- algo: account.algo,
179
- pubKey: account.pubkey,
180
- address: fromBech32(account.address).data,
181
- bech32Address: account.address,
182
- isKeystone: false,
183
- isNanoLedger: false
184
- };
198
+ try {
199
+ yield this.ensureChainEnabled(chainId);
200
+ const wallet = yield this.getFirstWallet();
201
+ const signer = new ParaProtoSigner(this.paraWebClient, this.getBech32Prefix(chainId), wallet.id);
202
+ const [account] = yield signer.getAccounts();
203
+ if (!account) {
204
+ throw new Error(`No Cosmos accounts for chain ${chainId}`);
205
+ }
206
+ return {
207
+ name: "Para Wallet",
208
+ algo: account.algo,
209
+ pubKey: account.pubkey,
210
+ address: fromBech32(account.address).data,
211
+ bech32Address: account.address,
212
+ isKeystone: false,
213
+ isNanoLedger: false
214
+ };
215
+ } catch (err) {
216
+ if (err instanceof Error) {
217
+ throw err;
218
+ }
219
+ throw new Error(`Failed to get key for chain ${chainId}`);
220
+ }
185
221
  });
186
222
  }
187
223
  getOfflineSignerOnlyAmino(chainId) {
188
224
  void this.ensureChainEnabled(chainId);
189
225
  const wallet = this.paraWebClient.getWalletsByType("COSMOS")[0];
190
226
  if (!wallet) {
191
- throw new Error(`Para connector: no wallets found when requesting Amino signer for ${chainId}`);
227
+ throw new Error("No Cosmos wallet for Amino signing");
192
228
  }
193
229
  return new ParaAminoSigner(this.paraWebClient, this.getBech32Prefix(chainId), wallet.id);
194
230
  }
@@ -208,9 +244,10 @@ class ParaGrazConnector {
208
244
  try {
209
245
  const wallet = yield this.getFirstWallet();
210
246
  const signerImpl = new ParaAminoSigner(this.paraWebClient, this.getBech32Prefix(chainId), wallet.id);
211
- return yield signerImpl.signAmino(signer, signDoc);
247
+ const response = yield signerImpl.signAmino(signer, signDoc);
248
+ return response;
212
249
  } catch (err) {
213
- throw new Error(`Para connector: signAmino failed \u2013 ${err.message}`);
250
+ throw new Error(`Amino signing failed: ${err instanceof Error ? err.message : "Unknown error"}`);
214
251
  }
215
252
  });
216
253
  }
@@ -238,7 +275,7 @@ class ParaGrazConnector {
238
275
  signature: result.signature
239
276
  };
240
277
  } catch (err) {
241
- throw new Error(`Para connector: signDirect failed \u2013 ${err.message}`);
278
+ throw new Error(`Direct signing failed: ${err instanceof Error ? err.message : "Unknown error"}`);
242
279
  }
243
280
  });
244
281
  }
@@ -263,7 +300,7 @@ class ParaGrazConnector {
263
300
  const response = yield this.signAmino(chainId, signer, signDoc);
264
301
  return response.signature;
265
302
  } catch (err) {
266
- throw new Error(`Para connector: signArbitrary failed \u2013 ${err.message}`);
303
+ throw new Error(`Arbitrary signing failed: ${err instanceof Error ? err.message : "Unknown error"}`);
267
304
  }
268
305
  });
269
306
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getpara/graz-connector",
3
- "version": "2.0.0-dev.10",
3
+ "version": "2.0.0-dev.12",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,33 +11,26 @@
11
11
  "typegen": "tsc --emitDeclarationOnly"
12
12
  },
13
13
  "dependencies": {
14
- "@getpara/cosmjs-v0-integration": "2.0.0-alpha.42",
15
- "@getpara/web-sdk": "2.0.0-alpha.42"
14
+ "@getpara/cosmjs-v0-integration": "~2.0.0-alpha.44",
15
+ "@getpara/web-sdk": "~2.0.0-alpha.44"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@cosmjs/amino": "^0.32.4",
19
- "@cosmjs/cosmwasm-stargate": "^0.32.4",
20
19
  "@cosmjs/encoding": "^0.32.4",
21
- "@cosmjs/launchpad": "0.27.1",
22
20
  "@cosmjs/proto-signing": "^0.32.4",
23
- "@cosmjs/stargate": "^0.32.4",
24
- "@cosmjs/tendermint-rpc": "^0.32.4",
25
- "@keplr-wallet/types": "0.12.156",
21
+ "@keplr-wallet/types": "^0.12.156",
26
22
  "cosmjs-types": "^0.9.0",
27
23
  "graz": "^0.3.3",
28
- "long": "5.3.2",
29
24
  "typescript": "5.1.6"
30
25
  },
31
26
  "peerDependencies": {
32
- "@cosmjs/amino": "*",
33
- "@cosmjs/cosmwasm-stargate": "*",
34
- "@cosmjs/encoding": "*",
35
- "@cosmjs/launchpad": ">=0.27.1",
36
- "@cosmjs/proto-signing": "*",
37
- "@cosmjs/stargate": "*",
38
- "@cosmjs/tendermint-rpc": "*",
27
+ "@cosmjs/amino": ">=0.32.4",
28
+ "@cosmjs/encoding": ">=0.32.4",
29
+ "@cosmjs/proto-signing": ">=0.32.4",
30
+ "@cosmjs/stargate": ">=0.32.4",
31
+ "@cosmjs/tendermint-rpc": ">=0.32.4",
39
32
  "@keplr-wallet/types": ">=0.12.156",
40
- "cosmjs-types": ">=0.8.0",
33
+ "cosmjs-types": ">=0.9.0",
41
34
  "graz": ">=0.3.3"
42
35
  }
43
36
  }
package/src/connector.ts CHANGED
@@ -26,15 +26,19 @@ class ParaOfflineSigner implements OfflineDirectSigner {
26
26
  protected readonly chainId: string,
27
27
  protected readonly connector: ParaGrazConnector,
28
28
  ) {}
29
+
29
30
  protected get para() {
30
31
  return this.connector.getParaWebClient();
31
32
  }
33
+
32
34
  protected get prefix() {
33
35
  return this.connector.getBech32Prefix(this.chainId);
34
36
  }
37
+
35
38
  protected async wallet() {
36
39
  return this.connector.getFirstWallet();
37
40
  }
41
+
38
42
  async getAccounts(): Promise<readonly AccountData[]> {
39
43
  const key = await this.connector.getKey(this.chainId);
40
44
  return [
@@ -45,25 +49,33 @@ class ParaOfflineSigner implements OfflineDirectSigner {
45
49
  },
46
50
  ];
47
51
  }
52
+
48
53
  async signDirect(signerAddress: string, signDoc: SignDoc): Promise<DirectSignResponse> {
49
54
  if (this.chainId !== signDoc.chainId) {
50
- throw new Error(`Para connector: signDirect chainId mismatch (expected ${this.chainId}, got ${signDoc.chainId})`);
55
+ throw new Error(`Chain ID mismatch: expected ${this.chainId}, got ${signDoc.chainId}`);
51
56
  }
57
+
52
58
  const accounts = await this.getAccounts();
53
59
  if (accounts.every(a => a.address !== signerAddress)) {
54
- throw new Error(`Para connector: signerAddress ${signerAddress} not found in wallet`);
60
+ throw new Error(`Signer address ${signerAddress} not found in wallet`);
55
61
  }
62
+
56
63
  const signer = new ParaProtoSigner(this.para, this.prefix, (await this.wallet()).id);
57
- const result = await signer.signDirect(signerAddress, signDoc);
58
- return {
59
- signed: {
60
- bodyBytes: result.signed.bodyBytes,
61
- authInfoBytes: result.signed.authInfoBytes,
62
- chainId: result.signed.chainId,
63
- accountNumber: result.signed.accountNumber,
64
- },
65
- signature: result.signature,
66
- };
64
+
65
+ try {
66
+ const result = await signer.signDirect(signerAddress, signDoc);
67
+ return {
68
+ signed: {
69
+ bodyBytes: result.signed.bodyBytes,
70
+ authInfoBytes: result.signed.authInfoBytes,
71
+ chainId: result.signed.chainId,
72
+ accountNumber: result.signed.accountNumber,
73
+ },
74
+ signature: result.signature,
75
+ };
76
+ } catch (err) {
77
+ throw new Error(`Direct signing failed: ${err instanceof Error ? err.message : 'Unknown error'}`);
78
+ }
67
79
  }
68
80
  }
69
81
 
@@ -72,32 +84,43 @@ export class ParaGrazConnector implements Omit<Wallet, 'experimentalSuggestChain
72
84
  protected enabledChainIds = new Set<string>();
73
85
  protected readonly events?: ParaGrazConnectorEvents;
74
86
  protected noModal?: boolean;
87
+
75
88
  constructor(
76
89
  protected readonly config: ParaGrazConfig,
77
90
  protected readonly chains: ChainInfo[] | null = null,
78
91
  ) {
79
92
  if (!config?.paraWeb) {
80
- throw new Error('Para connector: missing paraWeb instance in config');
93
+ throw new Error('ParaWeb instance required in config');
81
94
  }
82
95
  this.events = config.events;
83
96
  this.paraWebClient = config.paraWeb;
84
97
  this.noModal = config.noModal;
85
98
  }
99
+
86
100
  protected async ensureChainEnabled(chainId: string): Promise<void> {
87
101
  if (!this.enabledChainIds.has(chainId)) {
88
- throw new Error(`Para connector: chain ${chainId} was not enabled via wallet.enable()`);
102
+ throw new Error(`Chain ${chainId} not enabled. Call enable() first`);
89
103
  }
104
+
90
105
  if (!(await this.paraWebClient.isFullyLoggedIn())) {
91
- throw new Error('Para connector: wallet is not connected – call enable() first');
106
+ throw new Error('Para wallet not authenticated');
92
107
  }
93
108
  }
109
+
94
110
  protected async waitForLogin(timeoutMs = 60_000): Promise<void> {
95
111
  const deadline = Date.now() + timeoutMs;
96
112
  let delay = 500;
97
113
  const MAX_DELAY = 5_000;
114
+
98
115
  while (true) {
99
- if (await this.paraWebClient.isFullyLoggedIn()) return;
100
- if (Date.now() >= deadline) throw new Error('Para connector: login timeout');
116
+ if (await this.paraWebClient.isFullyLoggedIn()) {
117
+ return;
118
+ }
119
+
120
+ if (Date.now() >= deadline) {
121
+ throw new Error(`Login timeout after ${timeoutMs / 1000}s`);
122
+ }
123
+
101
124
  await new Promise(r => setTimeout(r, delay));
102
125
  delay = Math.min(delay * 1.5, MAX_DELAY);
103
126
  }
@@ -107,55 +130,90 @@ export class ParaGrazConnector implements Omit<Wallet, 'experimentalSuggestChain
107
130
  const deadline = Date.now() + timeoutMs;
108
131
  let delay = 250;
109
132
  const MAX_DELAY = 1_000;
133
+
110
134
  while (true) {
111
135
  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');
136
+ if (wallets.length) {
137
+ return wallets;
138
+ }
139
+
140
+ if (Date.now() >= deadline) {
141
+ throw new Error('No Cosmos wallets found');
142
+ }
143
+
114
144
  await new Promise(r => setTimeout(r, delay));
115
145
  delay = Math.min(delay * 1.5, MAX_DELAY);
116
146
  }
117
147
  }
148
+
118
149
  protected async hasCosmosWallet(): Promise<boolean> {
119
- return (await this.paraWebClient.isFullyLoggedIn()) && this.paraWebClient.getWalletsByType('COSMOS').length > 0;
150
+ const isLoggedIn = await this.paraWebClient.isFullyLoggedIn();
151
+ const wallets = this.paraWebClient.getWalletsByType('COSMOS');
152
+ return isLoggedIn && wallets.length > 0;
120
153
  }
154
+
121
155
  async enable(chainIdsInput: string | string[]): Promise<void> {
122
156
  const chainIds = toArray(chainIdsInput);
123
157
  const previousEnabled = new Set(this.enabledChainIds);
158
+
124
159
  try {
125
160
  chainIds.forEach(id => this.enabledChainIds.add(id));
161
+
126
162
  if (await this.hasCosmosWallet()) {
127
163
  this.events?.onEnabled?.(chainIds, this);
128
164
  return;
129
165
  }
166
+
130
167
  if (!this.noModal) {
131
- throw new Error('Modal rendering not supported in core library. Use @getpara/graz-integration for modal support.');
168
+ throw new Error('Modal not supported. Use @getpara/graz-integration or set noModal: true');
132
169
  }
170
+
133
171
  await this.waitForLogin();
134
172
  await this.waitForAccounts();
135
173
  this.events?.onEnabled?.(chainIds, this);
136
174
  } catch (err) {
137
175
  this.enabledChainIds = previousEnabled;
138
- throw err;
176
+
177
+ if (err instanceof Error) {
178
+ throw err;
179
+ }
180
+
181
+ throw new Error('Failed to enable Para wallet');
139
182
  }
140
183
  }
141
184
 
142
185
  async disconnect(): Promise<void> {
143
- await this.paraWebClient.logout();
144
- this.enabledChainIds.clear();
186
+ try {
187
+ await this.paraWebClient.logout();
188
+ } catch (err) {
189
+ throw new Error('Disconnect failed');
190
+ } finally {
191
+ this.enabledChainIds.clear();
192
+ }
145
193
  }
194
+
146
195
  async getFirstWallet(): Promise<ParaWallet> {
147
- const [wallet] = await this.waitForAccounts();
148
- return wallet;
196
+ try {
197
+ const [wallet] = await this.waitForAccounts();
198
+ return wallet;
199
+ } catch (err) {
200
+ throw new Error('No Para wallet available');
201
+ }
149
202
  }
203
+
150
204
  getBech32Prefix(chainId: string): string {
151
- return this.chains?.find(c => c.chainId === chainId)?.bech32Config?.bech32PrefixAccAddr || 'cosmos';
205
+ const prefix = this.chains?.find(c => c.chainId === chainId)?.bech32Config?.bech32PrefixAccAddr || 'cosmos';
206
+ return prefix;
152
207
  }
208
+
153
209
  getParaWebClient(): ParaWeb {
154
210
  return this.paraWebClient;
155
211
  }
212
+
156
213
  getConfig(): ParaGrazConfig {
157
214
  return this.config;
158
215
  }
216
+
159
217
  protected buildHybridSigner(chainId: string): OfflineAminoSigner & OfflineDirectSigner {
160
218
  const aminoSigner = this.getOfflineSignerOnlyAmino(chainId);
161
219
  const directSigner = new ParaOfflineSigner(chainId, this);
@@ -165,38 +223,57 @@ export class ParaGrazConnector implements Omit<Wallet, 'experimentalSuggestChain
165
223
  signDirect: (signer: string, signDoc: SignDoc) => directSigner.signDirect(signer, signDoc),
166
224
  } as unknown as OfflineAminoSigner & OfflineDirectSigner;
167
225
  }
226
+
168
227
  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',
176
- algo: account.algo,
177
- pubKey: account.pubkey,
178
- address: fromBech32(account.address).data,
179
- bech32Address: account.address,
180
- isKeystone: false,
181
- isNanoLedger: false,
182
- };
228
+ try {
229
+ await this.ensureChainEnabled(chainId);
230
+ const wallet = await this.getFirstWallet();
231
+ const signer = new ParaProtoSigner(this.paraWebClient, this.getBech32Prefix(chainId), wallet.id);
232
+ const [account] = await signer.getAccounts();
233
+
234
+ if (!account) {
235
+ throw new Error(`No Cosmos accounts for chain ${chainId}`);
236
+ }
237
+
238
+ return {
239
+ name: 'Para Wallet',
240
+ algo: account.algo,
241
+ pubKey: account.pubkey,
242
+ address: fromBech32(account.address).data,
243
+ bech32Address: account.address,
244
+ isKeystone: false,
245
+ isNanoLedger: false,
246
+ };
247
+ } catch (err) {
248
+ if (err instanceof Error) {
249
+ throw err;
250
+ }
251
+
252
+ throw new Error(`Failed to get key for chain ${chainId}`);
253
+ }
183
254
  }
255
+
184
256
  getOfflineSignerOnlyAmino(chainId: string): OfflineAminoSigner {
185
- void this.ensureChainEnabled(chainId); // fire & forget – returns void
257
+ void this.ensureChainEnabled(chainId);
186
258
  const wallet = this.paraWebClient.getWalletsByType('COSMOS')[0];
259
+
187
260
  if (!wallet) {
188
- throw new Error(`Para connector: no wallets found when requesting Amino signer for ${chainId}`);
261
+ throw new Error('No Cosmos wallet for Amino signing');
189
262
  }
263
+
190
264
  return new ParaAminoSigner(this.paraWebClient, this.getBech32Prefix(chainId), wallet.id);
191
265
  }
266
+
192
267
  getOfflineSigner(chainId: string): OfflineAminoSigner & OfflineDirectSigner {
193
268
  void this.ensureChainEnabled(chainId);
194
269
  return this.buildHybridSigner(chainId);
195
270
  }
271
+
196
272
  async getOfflineSignerAuto(chainId: string): Promise<OfflineAminoSigner | OfflineDirectSigner> {
197
273
  void this.ensureChainEnabled(chainId);
198
274
  return this.buildHybridSigner(chainId);
199
275
  }
276
+
200
277
  async signAmino(
201
278
  chainId: string,
202
279
  signer: string,
@@ -204,14 +281,17 @@ export class ParaGrazConnector implements Omit<Wallet, 'experimentalSuggestChain
204
281
  _signOptions?: KeplrSignOptions,
205
282
  ): Promise<AminoSignResponse> {
206
283
  await this.ensureChainEnabled(chainId);
284
+
207
285
  try {
208
286
  const wallet = await this.getFirstWallet();
209
287
  const signerImpl = new ParaAminoSigner(this.paraWebClient, this.getBech32Prefix(chainId), wallet.id);
210
- return await signerImpl.signAmino(signer, signDoc);
288
+ const response = await signerImpl.signAmino(signer, signDoc);
289
+ return response;
211
290
  } catch (err) {
212
- throw new Error(`Para connector: signAmino failed ${(err as Error).message}`);
291
+ throw new Error(`Amino signing failed: ${err instanceof Error ? err.message : 'Unknown error'}`);
213
292
  }
214
293
  }
294
+
215
295
  async signDirect(
216
296
  chainId: string,
217
297
  signer: string,
@@ -219,6 +299,7 @@ export class ParaGrazConnector implements Omit<Wallet, 'experimentalSuggestChain
219
299
  _signOptions?: KeplrSignOptions,
220
300
  ): Promise<DirectSignResponse> {
221
301
  await this.ensureChainEnabled(chainId);
302
+
222
303
  try {
223
304
  const wallet = await this.getFirstWallet();
224
305
  const signerImpl = new ParaProtoSigner(this.paraWebClient, this.getBech32Prefix(chainId), wallet.id);
@@ -228,6 +309,7 @@ export class ParaGrazConnector implements Omit<Wallet, 'experimentalSuggestChain
228
309
  chainId: signDoc.chainId,
229
310
  accountNumber: typeof signDoc.accountNumber === 'bigint' ? signDoc.accountNumber : BigInt(signDoc.accountNumber),
230
311
  };
312
+
231
313
  const result = await signerImpl.signDirect(signer, convertedSignDoc);
232
314
  return {
233
315
  signed: {
@@ -239,13 +321,16 @@ export class ParaGrazConnector implements Omit<Wallet, 'experimentalSuggestChain
239
321
  signature: result.signature,
240
322
  };
241
323
  } catch (err) {
242
- throw new Error(`Para connector: signDirect failed ${(err as Error).message}`);
324
+ throw new Error(`Direct signing failed: ${err instanceof Error ? err.message : 'Unknown error'}`);
243
325
  }
244
326
  }
327
+
245
328
  async signArbitrary(chainId: string, signer: string, data: string | Uint8Array): Promise<StdSignature> {
246
329
  await this.ensureChainEnabled(chainId);
330
+
247
331
  const encodedData =
248
332
  typeof data === 'string' ? Buffer.from(data, 'utf-8').toString('base64') : Buffer.from(data).toString('base64');
333
+
249
334
  const signDoc = {
250
335
  chain_id: '',
251
336
  account_number: '0',
@@ -259,11 +344,12 @@ export class ParaGrazConnector implements Omit<Wallet, 'experimentalSuggestChain
259
344
  ],
260
345
  memo: '',
261
346
  };
347
+
262
348
  try {
263
349
  const response = await this.signAmino(chainId, signer, signDoc);
264
350
  return response.signature;
265
351
  } catch (err) {
266
- throw new Error(`Para connector: signArbitrary failed ${(err as Error).message}`);
352
+ throw new Error(`Arbitrary signing failed: ${err instanceof Error ? err.message : 'Unknown error'}`);
267
353
  }
268
354
  }
269
355
  }