@keplr-wallet/wc-client 0.12.21-rc.2 → 0.12.22-rc.0

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/index.ts CHANGED
@@ -1,263 +1,295 @@
1
1
  import {
2
- IConnector,
3
- IJsonRpcRequest,
4
- IRequestOptions,
5
- } from "@walletconnect/types";
6
- import {
2
+ AminoSignResponse,
3
+ BroadcastMode,
7
4
  ChainInfo,
5
+ ChainInfoWithoutEndpoints,
6
+ DirectSignResponse,
8
7
  EthSignType,
8
+ ICNSAdr36Signatures,
9
9
  Keplr,
10
10
  KeplrIntereactionOptions,
11
11
  KeplrMode,
12
12
  KeplrSignOptions,
13
13
  Key,
14
- DirectSignResponse,
15
- OfflineDirectSigner,
16
- AminoSignResponse,
17
- BroadcastMode,
18
14
  OfflineAminoSigner,
19
- StdSignature,
20
- StdSignDoc,
21
- ICNSAdr36Signatures,
22
- ChainInfoWithoutEndpoints,
15
+ OfflineDirectSigner,
23
16
  SecretUtils,
24
17
  SettledResponses,
18
+ StdSignature,
19
+ StdSignDoc,
25
20
  } from "@keplr-wallet/types";
21
+ import SignClient from "@walletconnect/sign-client";
26
22
  import {
27
23
  CosmJSOfflineSigner,
28
24
  CosmJSOfflineSignerOnlyAmino,
29
25
  } from "@keplr-wallet/provider";
30
- import { payloadId } from "@walletconnect/utils";
31
- import deepmerge from "deepmerge";
32
26
  import { Buffer } from "buffer/";
33
- import { IndexedDBKVStore, KVStore } from "@keplr-wallet/common";
34
-
35
- // VersionFormatRegExp checks if a chainID is in the format required for parsing versions
36
- // The chainID should be in the form: `{identifier}-{version}`
37
- const ChainVersionFormatRegExp = /(.+)-([\d]+)/;
38
-
39
- function parseChainId(chainId: string): {
40
- identifier: string;
41
- version: number;
42
- } {
43
- const split = chainId.split(ChainVersionFormatRegExp).filter(Boolean);
44
- if (split.length !== 2) {
45
- return {
46
- identifier: chainId,
47
- version: 0,
48
- };
49
- } else {
50
- return { identifier: split[0], version: parseInt(split[1]) };
51
- }
27
+ import { ProposalTypes, SessionTypes } from "@walletconnect/types";
28
+ import Long from "long";
29
+
30
+ interface RequestParams {
31
+ topic: string;
32
+ request: {
33
+ method: string;
34
+ params: any;
35
+ };
36
+ chainId: string;
37
+ expiry?: number;
38
+ }
39
+
40
+ interface KeplrGetKeyWalletConnectV2Response {
41
+ // Name of the selected key store.
42
+ readonly name: string;
43
+ readonly algo: string;
44
+ readonly pubKey: string;
45
+ readonly address: string;
46
+ readonly bech32Address: string;
47
+ readonly isNanoLedger: boolean;
52
48
  }
53
49
 
54
- export type KeplrGetKeyWalletCoonectV1Response = {
55
- address: string;
56
- algo: string;
57
- bech32Address: string;
58
- isKeystone: boolean;
59
- isNanoLedger: boolean;
60
- name: string;
61
- pubKey: string;
62
- };
63
-
64
- export type KeplrKeystoreMayChangedEventParam = {
65
- algo: string;
66
- name: string;
67
- isKeystone: boolean;
68
- isNanoLedger: boolean;
69
- keys: {
70
- chainIdentifier: string;
71
- address: string;
72
- bech32Address: string;
73
- pubKey: string;
74
- }[];
75
- };
76
-
77
- export class KeplrWalletConnectV1 implements Keplr {
50
+ export class KeplrWalletConnectV2 implements Keplr {
51
+ defaultOptions: KeplrIntereactionOptions = {};
52
+
53
+ readonly version: string = "0.12.20";
54
+ readonly mode: KeplrMode = "walletconnect";
55
+ protected readonly storeKey = "keplr_wallet_connect_v2_key";
56
+
78
57
  constructor(
79
- public readonly connector: IConnector,
58
+ public readonly signClient: SignClient,
80
59
  public readonly options: {
81
- kvStore?: KVStore;
82
60
  sendTx?: Keplr["sendTx"];
83
- onBeforeSendRequest?: (
84
- request: Partial<IJsonRpcRequest>,
85
- options?: IRequestOptions
86
- ) => Promise<void> | void;
87
- onAfterSendRequest?: (
88
- response: any,
89
- request: Partial<IJsonRpcRequest>,
90
- options?: IRequestOptions
91
- ) => Promise<void> | void;
92
- } = {}
61
+ sessionProperties?: ProposalTypes.SessionProperties;
62
+ }
93
63
  ) {
94
- if (!options.kvStore) {
95
- options.kvStore = new IndexedDBKVStore("keplr_wallet_connect");
64
+ if (options.sessionProperties) {
65
+ this.saveKeys(options.sessionProperties);
96
66
  }
97
67
 
98
- connector.on("disconnect", () => {
99
- this.clearSaved();
68
+ signClient.on("session_event", (event) => {
69
+ if (event.params.event.name === "keplr_accountsChanged") {
70
+ this.saveKeys(event.params.event.data);
71
+
72
+ window.dispatchEvent(new Event("keplr_keystorechange"));
73
+ }
100
74
  });
101
75
 
102
- connector.on("call_request", this.onCallReqeust);
76
+ signClient.on("session_delete", async () => {
77
+ localStorage.removeItem(this.getKeyLastSeenKey());
78
+ });
103
79
  }
104
80
 
105
- readonly version: string = "0.9.0";
106
- readonly mode: KeplrMode = "walletconnect";
107
-
108
- defaultOptions: KeplrIntereactionOptions = {};
81
+ protected saveKeys(sessionProperty: ProposalTypes.SessionProperties) {
82
+ if (sessionProperty.hasOwnProperty("keys")) {
83
+ const keys = JSON.parse(sessionProperty["keys"]);
109
84
 
110
- protected readonly onCallReqeust = async (
111
- error: Error | null,
112
- payload: any | null
113
- ) => {
114
- if (error) {
115
- console.log(error);
116
- return;
117
- }
118
-
119
- if (!payload) {
120
- return;
85
+ if (keys.length > 0) {
86
+ keys.forEach((key: any) => {
87
+ if (key.hasOwnProperty("chainId")) {
88
+ this.saveLastSeenKey(
89
+ key["chainId"],
90
+ this.convertToKeplrGetKeyWalletConnectV2Response(key)
91
+ );
92
+ }
93
+ });
94
+ }
121
95
  }
96
+ }
122
97
 
98
+ protected convertToKeplrGetKeyWalletConnectV2Response(
99
+ data: any
100
+ ): KeplrGetKeyWalletConnectV2Response {
123
101
  if (
124
- payload.method === "keplr_keystore_may_changed_event_wallet_connect_v1"
102
+ !data.hasOwnProperty("name") ||
103
+ !data.hasOwnProperty("algo") ||
104
+ !data.hasOwnProperty("pubKey") ||
105
+ !data.hasOwnProperty("address") ||
106
+ !data.hasOwnProperty("bech32Address") ||
107
+ !data.hasOwnProperty("isNanoLedger")
125
108
  ) {
126
- const param = payload.params[0] as
127
- | KeplrKeystoreMayChangedEventParam
128
- | undefined;
129
- if (!param) {
130
- return;
131
- }
109
+ throw new Error("Invalid data");
110
+ }
132
111
 
133
- const lastSeenKeys = await this.getAllLastSeenKey();
134
- if (!lastSeenKeys) {
135
- return;
136
- }
112
+ return {
113
+ name: data.name as string,
114
+ algo: data.algo as string,
115
+ pubKey: data.pubKey as string,
116
+ address: data.address as string,
117
+ bech32Address: data.bech32Address as string,
118
+ isNanoLedger: data.isNanoLedger === "true",
119
+ };
120
+ }
137
121
 
138
- const mayChangedKeyMap: Record<
139
- string,
140
- KeplrGetKeyWalletCoonectV1Response
141
- > = {};
142
- for (const mayChangedKey of param.keys) {
143
- mayChangedKeyMap[mayChangedKey.chainIdentifier] = {
144
- address: mayChangedKey.address,
145
- algo: param.algo,
146
- bech32Address: mayChangedKey.bech32Address,
147
- isKeystone: param.isKeystone,
148
- isNanoLedger: param.isNanoLedger,
149
- name: param.name,
150
- pubKey: mayChangedKey.pubKey,
151
- };
152
- }
122
+ protected getLastSession(): SessionTypes.Struct | undefined {
123
+ const lastKeyIndex = this.signClient.session.getAll().length - 1;
124
+ return this.signClient.session.getAll()[lastKeyIndex];
125
+ }
153
126
 
154
- let hasChanged = false;
155
-
156
- for (const chainId of Object.keys(lastSeenKeys)) {
157
- const savedKey = lastSeenKeys[chainId];
158
- if (savedKey) {
159
- const { identifier } = parseChainId(chainId);
160
- const mayChangedKey = mayChangedKeyMap[identifier];
161
- if (mayChangedKey) {
162
- if (
163
- mayChangedKey.algo !== savedKey.algo ||
164
- mayChangedKey.name !== savedKey.name ||
165
- mayChangedKey.isKeystone !== savedKey.isKeystone ||
166
- mayChangedKey.isNanoLedger !== savedKey.isNanoLedger ||
167
- mayChangedKey.address !== savedKey.address ||
168
- mayChangedKey.bech32Address !== savedKey.bech32Address ||
169
- mayChangedKey.pubKey !== savedKey.pubKey
170
- ) {
171
- hasChanged = true;
172
-
173
- lastSeenKeys[chainId] = mayChangedKey;
174
- }
175
- }
176
- }
177
- }
127
+ protected getCurrentTopic(): string {
128
+ const lastSession = this.getLastSession();
178
129
 
179
- if (hasChanged) {
180
- await this.saveAllLastSeenKey(lastSeenKeys);
181
- window.dispatchEvent(new Event("keplr_keystorechange"));
182
- }
130
+ if (!lastSession) {
131
+ throw new Error("No session");
183
132
  }
184
- };
185
133
 
186
- protected async clearSaved(): Promise<void> {
187
- const kvStore = this.options.kvStore!;
134
+ return lastSession.topic;
135
+ }
188
136
 
189
- await Promise.all([
190
- kvStore.set(this.getKeyHasEnabled(), null),
191
- kvStore.set(this.getKeyLastSeenKey(), null),
192
- ]);
137
+ protected getKeyLastSeenKey() {
138
+ const topic = this.getCurrentTopic();
139
+ return `${this.storeKey}/${topic}-key`;
193
140
  }
194
141
 
195
- protected async sendCustomRequest(
196
- request: Partial<IJsonRpcRequest>,
197
- options?: IRequestOptions
198
- ): Promise<any> {
199
- if (this.options.onBeforeSendRequest) {
200
- await this.options.onBeforeSendRequest(request, options);
142
+ protected getLastSeenKey(
143
+ chainId: string
144
+ ): KeplrGetKeyWalletConnectV2Response | undefined {
145
+ const saved = this.getAllLastSeenKey();
146
+
147
+ if (!saved) {
148
+ return undefined;
201
149
  }
202
150
 
203
- const res = await this.connector.sendCustomRequest(request, options);
151
+ return saved[chainId];
152
+ }
204
153
 
205
- if (this.options.onAfterSendRequest) {
206
- await this.options.onAfterSendRequest(res, request, options);
154
+ protected getAllLastSeenKey() {
155
+ const data = localStorage.getItem(this.getKeyLastSeenKey());
156
+ if (!data) {
157
+ return undefined;
207
158
  }
208
159
 
209
- return res;
160
+ return JSON.parse(data);
210
161
  }
211
162
 
212
- async enable(chainIds: string | string[]): Promise<void> {
213
- if (typeof chainIds === "string") {
214
- chainIds = [chainIds];
215
- }
163
+ protected saveLastSeenKey(
164
+ chainId: string,
165
+ response: KeplrGetKeyWalletConnectV2Response
166
+ ) {
167
+ let saved = this.getAllLastSeenKey();
216
168
 
217
- const hasEnabledChainIds = await this.getHasEnabledChainIds();
218
- let allEnabled = true;
219
- for (const chainId of chainIds) {
220
- if (hasEnabledChainIds.indexOf(chainId) < 0) {
221
- allEnabled = false;
222
- break;
223
- }
169
+ if (!saved) {
170
+ saved = {};
224
171
  }
225
172
 
226
- if (allEnabled) {
227
- return;
228
- }
173
+ saved[chainId] = response;
229
174
 
230
- await this.sendCustomRequest({
231
- id: payloadId(),
232
- jsonrpc: "2.0",
233
- method: "keplr_enable_wallet_connect_v1",
234
- params: chainIds,
235
- });
175
+ this.saveAllLastSeenKey(saved);
176
+ }
236
177
 
237
- await this.saveHasEnabledChainIds(chainIds);
178
+ protected saveAllLastSeenKey(data: {
179
+ [chainId: string]: KeplrGetKeyWalletConnectV2Response | undefined;
180
+ }) {
181
+ localStorage.setItem(this.getKeyLastSeenKey(), JSON.stringify(data));
182
+ }
183
+
184
+ protected async sendCustomRequest<T>(
185
+ requestParams: RequestParams
186
+ ): Promise<T> {
187
+ const response = await this.signClient.request(requestParams);
188
+ return response as T;
238
189
  }
239
190
 
240
- protected getKeyHasEnabled() {
241
- return `${this.connector.session.handshakeTopic}-enabled`;
191
+ protected getNamespaceChainId(): string {
192
+ const lastSession = this.getLastSession();
193
+
194
+ if (
195
+ lastSession &&
196
+ lastSession.namespaces.hasOwnProperty("cosmos") &&
197
+ lastSession.namespaces["cosmos"].hasOwnProperty("accounts")
198
+ ) {
199
+ const splitAccount =
200
+ lastSession.namespaces["cosmos"]["accounts"][0].split(":");
201
+
202
+ return `${splitAccount[0]}:${splitAccount[1]}`;
203
+ }
204
+
205
+ return "cosmos:cosmoshub-4";
242
206
  }
243
207
 
244
- protected async getHasEnabledChainIds(): Promise<string[]> {
245
- return (
246
- (await this.options.kvStore!.get<string[]>(this.getKeyHasEnabled())) ?? []
208
+ protected checkDeepLink() {
209
+ const mobileLinkInfo = localStorage.getItem(
210
+ "wallet-connect-v2-mobile-link"
247
211
  );
212
+
213
+ if (mobileLinkInfo) {
214
+ window.location.href = JSON.parse(mobileLinkInfo).href;
215
+ }
216
+ }
217
+
218
+ changeKeyRingName(_opts: {
219
+ defaultName: string;
220
+ editable?: boolean | undefined;
221
+ }): Promise<string> {
222
+ throw new Error("Not yet implemented");
248
223
  }
249
224
 
250
- protected async saveHasEnabledChainIds(chainIds: string[]) {
251
- const hasEnabledChainIds = await this.getHasEnabledChainIds();
252
- for (const chainId of chainIds) {
253
- if (hasEnabledChainIds.indexOf(chainId) < 0) {
254
- hasEnabledChainIds.push(chainId);
225
+ disable(_chainIds?: string | string[]): Promise<void> {
226
+ throw new Error("Not yet implemented");
227
+ }
228
+
229
+ async enable(chainIds: string | string[]): Promise<void> {
230
+ if (typeof chainIds === "string") {
231
+ chainIds = [chainIds];
232
+ }
233
+
234
+ // Check public key from local storage.
235
+ const keys = await this.getAllLastSeenKey();
236
+ if (keys) {
237
+ const hasChainId = chainIds.every((chainId) => {
238
+ return Object.keys(keys).includes(chainId);
239
+ });
240
+
241
+ if (hasChainId) {
242
+ return;
255
243
  }
256
244
  }
257
- await this.options.kvStore!.set(
258
- this.getKeyHasEnabled(),
259
- hasEnabledChainIds
260
- );
245
+
246
+ this.checkDeepLink();
247
+
248
+ // Request enable from the mobile wallet.
249
+ const topic = this.getCurrentTopic();
250
+ const chainId = this.getNamespaceChainId();
251
+ if (!chainId) {
252
+ throw new Error("No Namespace chain id");
253
+ }
254
+ const param = {
255
+ topic: topic,
256
+ chainId: this.getNamespaceChainId(),
257
+ request: {
258
+ method: "keplr_enable",
259
+ params: {
260
+ chainId: chainIds,
261
+ },
262
+ },
263
+ };
264
+
265
+ await this.sendCustomRequest<void>(param);
266
+
267
+ // session의 정보가 업데이트 되기 전에 다음로직이 실행되면 안되기 때문에 namespace가 업데이트 될때까지 기다린다.
268
+ // We wait for the namespace to be updated because we don't want the next logic to run before the session's information is updated.
269
+ return new Promise(async (resolve) => {
270
+ while (true) {
271
+ await new Promise((resolve) => setTimeout(resolve, 100));
272
+
273
+ const lastSession = this.getLastSession();
274
+ if (
275
+ lastSession &&
276
+ lastSession.namespaces.hasOwnProperty("cosmos") &&
277
+ lastSession.namespaces["cosmos"].hasOwnProperty("accounts")
278
+ ) {
279
+ const hasChainId = lastSession.namespaces["cosmos"]["accounts"].some(
280
+ (account) => {
281
+ const chainId = account.replace("cosmos:", "").split(":")[0];
282
+ return chainIds.includes(chainId);
283
+ }
284
+ );
285
+
286
+ if (hasChainId) {
287
+ resolve();
288
+ return;
289
+ }
290
+ }
291
+ }
292
+ });
261
293
  }
262
294
 
263
295
  enigmaDecrypt(
@@ -277,10 +309,28 @@ export class KeplrWalletConnectV1 implements Keplr {
277
309
  throw new Error("Not yet implemented");
278
310
  }
279
311
 
312
+ experimentalSignEIP712CosmosTx_v0(
313
+ _chainId: string,
314
+ _signer: string,
315
+ _eip712: {
316
+ types: Record<string, { name: string; type: string }[] | undefined>;
317
+ domain: Record<string, any>;
318
+ primaryType: string;
319
+ },
320
+ _signDoc: StdSignDoc,
321
+ _signOptions: KeplrSignOptions = {}
322
+ ): Promise<AminoSignResponse> {
323
+ throw new Error("Not yet implemented");
324
+ }
325
+
280
326
  experimentalSuggestChain(_chainInfo: ChainInfo): Promise<void> {
281
327
  throw new Error("Not yet implemented");
282
328
  }
283
329
 
330
+ getChainInfosWithoutEndpoints(): Promise<ChainInfoWithoutEndpoints[]> {
331
+ throw new Error("Not yet implemented");
332
+ }
333
+
284
334
  getEnigmaPubKey(_chainId: string): Promise<Uint8Array> {
285
335
  throw new Error("Not yet implemented");
286
336
  }
@@ -297,122 +347,81 @@ export class KeplrWalletConnectV1 implements Keplr {
297
347
  }
298
348
 
299
349
  async getKey(chainId: string): Promise<Key> {
300
- const lastSeenKey = await this.getLastSeenKey(chainId);
350
+ // Check public key from local storage.
351
+ const lastSeenKey = this.getLastSeenKey(chainId);
301
352
  if (lastSeenKey) {
302
353
  return {
303
- address: Buffer.from(lastSeenKey.address, "hex"),
304
354
  algo: lastSeenKey.algo,
305
355
  bech32Address: lastSeenKey.bech32Address,
306
- isKeystone: lastSeenKey.isKeystone,
307
- isNanoLedger: lastSeenKey.isNanoLedger,
356
+ address: Buffer.from(lastSeenKey.address, "base64"),
308
357
  name: lastSeenKey.name,
309
- pubKey: Buffer.from(lastSeenKey.pubKey, "hex"),
358
+ pubKey: Buffer.from(lastSeenKey.pubKey, "base64"),
359
+ isNanoLedger: lastSeenKey.isNanoLedger,
360
+ isKeystone: false,
310
361
  };
311
362
  }
312
363
 
313
- const response = (
314
- await this.sendCustomRequest({
315
- id: payloadId(),
316
- jsonrpc: "2.0",
317
- method: "keplr_get_key_wallet_connect_v1",
318
- params: [chainId],
319
- })
320
- )[0] as KeplrGetKeyWalletCoonectV1Response;
321
-
322
- await this.saveLastSeenKey(chainId, response);
323
-
324
- return {
325
- address: Buffer.from(response.address, "hex"),
326
- algo: response.algo,
327
- bech32Address: response.bech32Address,
328
- isKeystone: response.isKeystone,
329
- isNanoLedger: response.isNanoLedger,
330
- name: response.name,
331
- pubKey: Buffer.from(response.pubKey, "hex"),
332
- };
333
- }
334
-
335
- getKeysSettled(_chainIds: string[]): Promise<SettledResponses<Key>> {
336
- throw new Error("Not yet implemented");
337
- }
338
-
339
- protected getKeyLastSeenKey() {
340
- return `${this.connector.session.handshakeTopic}-key`;
341
- }
342
-
343
- protected async getLastSeenKey(
344
- chainId: string
345
- ): Promise<KeplrGetKeyWalletCoonectV1Response | undefined> {
346
- const saved = await this.getAllLastSeenKey();
347
-
348
- if (!saved) {
349
- return undefined;
350
- }
351
-
352
- return saved[chainId];
353
- }
354
-
355
- protected async getAllLastSeenKey() {
356
- return await this.options.kvStore!.get<{
357
- [chainId: string]: KeplrGetKeyWalletCoonectV1Response | undefined;
358
- }>(this.getKeyLastSeenKey());
359
- }
360
-
361
- protected async saveAllLastSeenKey(data: {
362
- [chainId: string]: KeplrGetKeyWalletCoonectV1Response | undefined;
363
- }) {
364
- await this.options.kvStore!.set(this.getKeyLastSeenKey(), data);
365
- }
366
-
367
- protected async saveLastSeenKey(
368
- chainId: string,
369
- response: KeplrGetKeyWalletCoonectV1Response
370
- ) {
371
- let saved = await this.getAllLastSeenKey();
372
-
373
- if (!saved) {
374
- saved = {};
364
+ // Check public key from session properties.
365
+ const lastSession = this.getLastSession();
366
+ if (lastSession && lastSession.sessionProperties) {
367
+ const sessionChainId = lastSession.sessionProperties["chainId"];
368
+
369
+ if (sessionChainId === chainId) {
370
+ return {
371
+ algo: lastSession.sessionProperties["algo"],
372
+ bech32Address: lastSession.sessionProperties["bech32Address"],
373
+ address: Buffer.from(
374
+ lastSession.sessionProperties["address"],
375
+ "base64"
376
+ ),
377
+ name: lastSession.sessionProperties["name"],
378
+ pubKey: Buffer.from(
379
+ lastSession.sessionProperties["pubKey"],
380
+ "base64"
381
+ ),
382
+ isNanoLedger:
383
+ lastSession.sessionProperties["isNanoLedger"] === "true",
384
+ isKeystone: false,
385
+ };
386
+ }
375
387
  }
376
388
 
377
- saved[chainId] = response;
378
-
379
- await this.saveAllLastSeenKey(saved);
380
- }
389
+ // Request `get_key` from the mobile wallet.
390
+ const topic = this.getCurrentTopic();
391
+ const param = {
392
+ topic,
393
+ chainId: this.getNamespaceChainId(),
394
+ request: {
395
+ method: "keplr_getKey",
396
+ params: {
397
+ chainId,
398
+ },
399
+ },
400
+ };
381
401
 
382
- signArbitrary(
383
- _chainId: string,
384
- _signer: string,
385
- _data: string | Uint8Array
386
- ): Promise<StdSignature> {
387
- throw new Error("Not yet implemented");
388
- }
402
+ const response = await this.sendCustomRequest<{
403
+ name: string;
404
+ algo: string;
405
+ pubKey: string;
406
+ address: string;
407
+ bech32Address: string;
408
+ isNanoLedger: boolean;
409
+ }>(param);
389
410
 
390
- verifyArbitrary(
391
- _chainId: string,
392
- _signer: string,
393
- _data: string | Uint8Array,
394
- _signature: StdSignature
395
- ): Promise<boolean> {
396
- throw new Error("Not yet implemented");
411
+ return {
412
+ ...response,
413
+ pubKey: Buffer.from(response.pubKey, "base64"),
414
+ address: Buffer.from(response.address, "base64"),
415
+ isKeystone: false,
416
+ };
397
417
  }
398
418
 
399
- signEthereum(
400
- _chainId: string,
401
- _signer: string,
402
- _data: string | Uint8Array,
403
- _mode: EthSignType
404
- ): Promise<Uint8Array> {
405
- throw new Error("Not yet implemented");
406
- }
419
+ async getKeysSettled(chainIds: string[]): Promise<SettledResponses<Key>> {
420
+ const paramArray = chainIds.map(async (chainId) => {
421
+ return await this.getKey(chainId);
422
+ });
407
423
 
408
- signICNSAdr36(
409
- _chainId: string,
410
- _contractAddress: string,
411
- _owner: string,
412
- _username: string,
413
- _addressChainIds: string[]
414
- ): Promise<ICNSAdr36Signatures> {
415
- throw new Error("Not yet implemented");
424
+ return await Promise.allSettled(paramArray);
416
425
  }
417
426
 
418
427
  getOfflineSigner(chainId: string): OfflineAminoSigner & OfflineDirectSigner {
@@ -440,15 +449,6 @@ export class KeplrWalletConnectV1 implements Keplr {
440
449
  throw new Error("Not yet implemented");
441
450
  }
442
451
 
443
- /**
444
- * In the extension environment, this API let the extension to send the tx on behalf of the client.
445
- * But, in the wallet connect environment, in order to send the tx on behalf of the client, wallet should receive the tx data from remote.
446
- * However, this approach is not efficient and hard to ensure the stability and `KeplrWalletConnect` should have the informations of rpc and rest endpoints.
447
- * So, rather than implementing this, just fallback to the client sided implementation or throw error of the client sided implementation is not delivered to the `options`.
448
- * @param chainId
449
- * @param stdTx
450
- * @param mode
451
- */
452
452
  sendTx(
453
453
  chainId: string,
454
454
  tx: Uint8Array,
@@ -465,71 +465,155 @@ export class KeplrWalletConnectV1 implements Keplr {
465
465
  chainId: string,
466
466
  signer: string,
467
467
  signDoc: StdSignDoc,
468
- signOptions: KeplrSignOptions = {}
468
+ signOptions?: KeplrSignOptions
469
469
  ): Promise<AminoSignResponse> {
470
- return (
471
- await this.sendCustomRequest({
472
- id: payloadId(),
473
- jsonrpc: "2.0",
474
- method: "keplr_sign_amino_wallet_connect_v1",
475
- params: [
470
+ this.checkDeepLink();
471
+
472
+ const topic = this.getCurrentTopic();
473
+
474
+ const param = {
475
+ topic,
476
+ chainId: this.getNamespaceChainId(),
477
+ request: {
478
+ method: "keplr_signAmino",
479
+ params: {
476
480
  chainId,
477
481
  signer,
478
482
  signDoc,
479
- deepmerge(this.defaultOptions.sign ?? {}, signOptions),
480
- ],
481
- })
482
- )[0];
483
+ signOptions: signOptions,
484
+ },
485
+ },
486
+ };
487
+
488
+ return await this.sendCustomRequest<AminoSignResponse>(param);
483
489
  }
484
490
 
485
- signDirect(
486
- _chainId: string,
487
- _signer: string,
488
- _signDoc: {
491
+ signArbitrary(
492
+ chainId: string,
493
+ signer: string,
494
+ data: string | Uint8Array
495
+ ): Promise<StdSignature> {
496
+ this.checkDeepLink();
497
+
498
+ const topic = this.getCurrentTopic();
499
+
500
+ const param = {
501
+ topic,
502
+ chainId: this.getNamespaceChainId(),
503
+ request: {
504
+ method: "keplr_signArbitrary",
505
+ params: {
506
+ chainId,
507
+ signer,
508
+ type: typeof data === "string" ? "string" : "Uint8Array",
509
+ data:
510
+ typeof data === "string"
511
+ ? data
512
+ : Buffer.from(data).toString("base64"),
513
+ },
514
+ },
515
+ };
516
+ return this.sendCustomRequest<StdSignature>(param);
517
+ }
518
+
519
+ async signDirect(
520
+ chainId: string,
521
+ signer: string,
522
+ signDoc: {
489
523
  bodyBytes?: Uint8Array | null;
490
524
  authInfoBytes?: Uint8Array | null;
491
525
  chainId?: string | null;
492
526
  accountNumber?: Long | null;
493
527
  },
494
- _signOptions: KeplrSignOptions = {}
528
+ signOptions?: KeplrSignOptions
495
529
  ): Promise<DirectSignResponse> {
496
- throw new Error("Not yet implemented");
497
- }
530
+ this.checkDeepLink();
498
531
 
499
- suggestToken(
500
- _chainId: string,
501
- _contractAddress: string,
502
- _viewingKey?: string
503
- ): Promise<void> {
504
- throw new Error("Not yet implemented");
532
+ const topic = this.getCurrentTopic();
533
+
534
+ const param = {
535
+ topic,
536
+ chainId: this.getNamespaceChainId(),
537
+ request: {
538
+ method: "keplr_signDirect",
539
+ params: {
540
+ chainId,
541
+ signer,
542
+ signDoc: {
543
+ chainId: signDoc.chainId,
544
+ accountNumber: signDoc.accountNumber?.toString(),
545
+ bodyBytes: signDoc.bodyBytes
546
+ ? Buffer.from(signDoc.bodyBytes).toString("base64")
547
+ : null,
548
+ authInfoBytes: signDoc.authInfoBytes
549
+ ? Buffer.from(signDoc.authInfoBytes).toString("base64")
550
+ : null,
551
+ },
552
+ signOptions: signOptions,
553
+ },
554
+ },
555
+ };
556
+
557
+ const response = await this.sendCustomRequest<{
558
+ readonly signed: {
559
+ bodyBytes?: string | null;
560
+ authInfoBytes?: string | null;
561
+ chainId?: string | null;
562
+ accountNumber?: string | null;
563
+ };
564
+ readonly signature: StdSignature;
565
+ }>(param);
566
+
567
+ return {
568
+ signature: response.signature,
569
+ signed: {
570
+ chainId: response.signed.chainId ?? "",
571
+ accountNumber: response.signed.accountNumber
572
+ ? Long.fromString(response.signed.accountNumber)
573
+ : new Long(0),
574
+ bodyBytes: response.signed.bodyBytes
575
+ ? Buffer.from(response.signed.bodyBytes, "base64")
576
+ : new Uint8Array([]),
577
+ authInfoBytes: response.signed.authInfoBytes
578
+ ? Buffer.from(response.signed.authInfoBytes, "base64")
579
+ : new Uint8Array([]),
580
+ },
581
+ };
505
582
  }
506
583
 
507
- experimentalSignEIP712CosmosTx_v0(
584
+ signEthereum(
508
585
  _chainId: string,
509
586
  _signer: string,
510
- _eip712: {
511
- types: Record<string, { name: string; type: string }[] | undefined>;
512
- domain: Record<string, any>;
513
- primaryType: string;
514
- },
515
- _signDoc: StdSignDoc,
516
- _signOptions: KeplrSignOptions = {}
517
- ): Promise<AminoSignResponse> {
587
+ _data: string | Uint8Array,
588
+ _type: EthSignType
589
+ ): Promise<Uint8Array> {
518
590
  throw new Error("Not yet implemented");
519
591
  }
520
592
 
521
- getChainInfosWithoutEndpoints(): Promise<ChainInfoWithoutEndpoints[]> {
593
+ signICNSAdr36(
594
+ _chainId: string,
595
+ _contractAddress: string,
596
+ _owner: string,
597
+ _username: string,
598
+ _addressChainIds: string[]
599
+ ): Promise<ICNSAdr36Signatures> {
522
600
  throw new Error("Not yet implemented");
523
601
  }
524
602
 
525
- disable(_chainIds?: string | string[]): Promise<void> {
603
+ suggestToken(
604
+ _chainId: string,
605
+ _contractAddress: string,
606
+ _viewingKey?: string
607
+ ): Promise<void> {
526
608
  throw new Error("Not yet implemented");
527
609
  }
528
610
 
529
- changeKeyRingName(_opts: {
530
- defaultName: string;
531
- editable?: boolean | undefined;
532
- }): Promise<string> {
611
+ verifyArbitrary(
612
+ _chainId: string,
613
+ _signer: string,
614
+ _data: string | Uint8Array,
615
+ _signature: StdSignature
616
+ ): Promise<boolean> {
533
617
  throw new Error("Not yet implemented");
534
618
  }
535
619
  }