@keplr-wallet/stores-core 0.12.32-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/.eslintignore +2 -0
- package/.prettierignore +2 -0
- package/LICENSE +209 -0
- package/build/core/index.d.ts +4 -0
- package/build/core/index.js +21 -0
- package/build/core/index.js.map +1 -0
- package/build/core/interaction/chain-suggest.d.ts +35 -0
- package/build/core/interaction/chain-suggest.js +106 -0
- package/build/core/interaction/chain-suggest.js.map +1 -0
- package/build/core/interaction/eth-sign.d.ts +25 -0
- package/build/core/interaction/eth-sign.js +60 -0
- package/build/core/interaction/eth-sign.js.map +1 -0
- package/build/core/interaction/icns.d.ts +32 -0
- package/build/core/interaction/icns.js +58 -0
- package/build/core/interaction/icns.js.map +1 -0
- package/build/core/interaction/index.d.ts +6 -0
- package/build/core/interaction/index.js +23 -0
- package/build/core/interaction/index.js.map +1 -0
- package/build/core/interaction/interaction.d.ts +64 -0
- package/build/core/interaction/interaction.js +232 -0
- package/build/core/interaction/interaction.js.map +1 -0
- package/build/core/interaction/permission.d.ts +22 -0
- package/build/core/interaction/permission.js +108 -0
- package/build/core/interaction/permission.js.map +1 -0
- package/build/core/interaction/sign.d.ts +49 -0
- package/build/core/interaction/sign.js +78 -0
- package/build/core/interaction/sign.js.map +1 -0
- package/build/core/keyring.d.ts +132 -0
- package/build/core/keyring.js +278 -0
- package/build/core/keyring.js.map +1 -0
- package/build/core/permission-manager.d.ts +15 -0
- package/build/core/permission-manager.js +122 -0
- package/build/core/permission-manager.js.map +1 -0
- package/build/core/tokens.d.ts +39 -0
- package/build/core/tokens.js +225 -0
- package/build/core/tokens.js.map +1 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +18 -0
- package/build/index.js.map +1 -0
- package/jest.config.js +5 -0
- package/package.json +31 -0
- package/src/core/index.ts +4 -0
- package/src/core/interaction/chain-suggest.ts +136 -0
- package/src/core/interaction/eth-sign.ts +71 -0
- package/src/core/interaction/icns.ts +68 -0
- package/src/core/interaction/index.ts +6 -0
- package/src/core/interaction/interaction.ts +290 -0
- package/src/core/interaction/permission.ts +121 -0
- package/src/core/interaction/sign.ts +124 -0
- package/src/core/keyring.ts +354 -0
- package/src/core/permission-manager.ts +114 -0
- package/src/core/tokens.ts +275 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +12 -0
@@ -0,0 +1,290 @@
|
|
1
|
+
import {
|
2
|
+
Router,
|
3
|
+
MessageRequester,
|
4
|
+
BACKGROUND_PORT,
|
5
|
+
} from "@keplr-wallet/router";
|
6
|
+
import {
|
7
|
+
InteractionForegroundHandler,
|
8
|
+
interactionForegroundInit,
|
9
|
+
InteractionForegroundService,
|
10
|
+
InteractionWaitingData,
|
11
|
+
ApproveInteractionMsg,
|
12
|
+
ApproveInteractionV2Msg,
|
13
|
+
RejectInteractionMsg,
|
14
|
+
RejectInteractionV2Msg,
|
15
|
+
} from "@keplr-wallet/background";
|
16
|
+
import { action, observable, makeObservable, flow, toJS } from "mobx";
|
17
|
+
import { computedFn } from "mobx-utils";
|
18
|
+
|
19
|
+
export class InteractionStore implements InteractionForegroundHandler {
|
20
|
+
@observable.shallow
|
21
|
+
protected data: InteractionWaitingData[] = [];
|
22
|
+
// 원래 obsolete에 대한 정보를 data 밑의 field에 포함시켰는데
|
23
|
+
// obsolete 처리가 추가되기 전에는 data는 한번 받으면 그 이후에 변화되지 않는다는 가정으로 다른 로직이 짜여졌었다.
|
24
|
+
// ref도 변하면 안됐기 때문에 obsolete가 data 밑에 있으면 이러한 요구사항을 이루면서 처리할 수가 없다.
|
25
|
+
// (특히 서명 페이지에서 문제가 될 수 있음)
|
26
|
+
// 기존의 로직과의 호환성을 위해서 아예 분리되었음.
|
27
|
+
@observable.shallow
|
28
|
+
protected obsoleteData = new Map<string, boolean>();
|
29
|
+
|
30
|
+
constructor(
|
31
|
+
protected readonly router: Router,
|
32
|
+
protected readonly msgRequester: MessageRequester
|
33
|
+
) {
|
34
|
+
makeObservable(this);
|
35
|
+
|
36
|
+
const service = new InteractionForegroundService(this);
|
37
|
+
interactionForegroundInit(router, service);
|
38
|
+
}
|
39
|
+
|
40
|
+
getAllData = computedFn(
|
41
|
+
<T = unknown>(type: string): InteractionWaitingData<T>[] => {
|
42
|
+
return toJS(
|
43
|
+
this.data.filter((d) => d.type === type)
|
44
|
+
) as InteractionWaitingData<T>[];
|
45
|
+
}
|
46
|
+
);
|
47
|
+
|
48
|
+
getData = computedFn(
|
49
|
+
<T = unknown>(id: string): InteractionWaitingData<T> | undefined => {
|
50
|
+
return this.data.find((d) => d.id === id) as InteractionWaitingData<T>;
|
51
|
+
}
|
52
|
+
);
|
53
|
+
|
54
|
+
@action
|
55
|
+
onInteractionDataReceived(data: InteractionWaitingData) {
|
56
|
+
this.data.push(data);
|
57
|
+
}
|
58
|
+
|
59
|
+
@action
|
60
|
+
onEventDataReceived() {
|
61
|
+
// noop
|
62
|
+
}
|
63
|
+
|
64
|
+
/**
|
65
|
+
* 웹페이지에서 어떤 API를 요청해서 extension이 켜졌을때
|
66
|
+
* extension에서 요청을 처리하고 바로 팝업을 닫으면
|
67
|
+
* 이후에 연속적인 api 요청의 경우 다시 페이지가 열려야하는데 이게 은근히 어색한 UX를 만들기 때문에
|
68
|
+
* 이를 대충 해결하기 위해서 approve 이후에 대충 조금 기다리고 남은 interaction이 있느냐 아니냐에 따라 다른 처리를 한다.
|
69
|
+
* @param type
|
70
|
+
* @param id
|
71
|
+
* @param result
|
72
|
+
* @param afterFn
|
73
|
+
*/
|
74
|
+
@flow
|
75
|
+
*approveWithProceedNext(
|
76
|
+
id: string,
|
77
|
+
result: unknown,
|
78
|
+
afterFn: (proceedNext: boolean) => void | Promise<void>
|
79
|
+
) {
|
80
|
+
const d = this.getData(id);
|
81
|
+
if (!d || this.isObsoleteInteraction(id)) {
|
82
|
+
return;
|
83
|
+
}
|
84
|
+
|
85
|
+
this.markAsObsolete(id);
|
86
|
+
yield this.msgRequester.sendMessage(
|
87
|
+
BACKGROUND_PORT,
|
88
|
+
new ApproveInteractionMsg(id, result)
|
89
|
+
);
|
90
|
+
yield this.delay(100);
|
91
|
+
yield afterFn(this.hasOtherData(id));
|
92
|
+
this.removeData(id);
|
93
|
+
}
|
94
|
+
|
95
|
+
/**
|
96
|
+
* 웹페이지에서 어떤 API를 요청해서 extension이 켜졌을때
|
97
|
+
* extension에서 요청을 처리하고 바로 팝업을 닫으면
|
98
|
+
* 이후에 연속적인 api 요청의 경우 다시 페이지가 열려야하는데 이게 은근히 어색한 UX를 만들기 때문에
|
99
|
+
* 이를 대충 해결하기 위해서 approve 이후에 대충 조금 기다리고 남은 interaction이 있느냐 아니냐에 따라 다른 처리를 한다.
|
100
|
+
* @param type
|
101
|
+
* @param id
|
102
|
+
* @param result
|
103
|
+
* @param afterFn
|
104
|
+
*/
|
105
|
+
@flow
|
106
|
+
*approveWithProceedNextV2(
|
107
|
+
ids: string | string[],
|
108
|
+
result: unknown,
|
109
|
+
afterFn: (proceedNext: boolean) => void | Promise<void>,
|
110
|
+
options: {
|
111
|
+
preDelay?: number;
|
112
|
+
postDelay?: number;
|
113
|
+
} = {}
|
114
|
+
) {
|
115
|
+
if (typeof ids === "string") {
|
116
|
+
ids = [ids];
|
117
|
+
}
|
118
|
+
|
119
|
+
const fresh: string[] = [];
|
120
|
+
|
121
|
+
for (const id of ids) {
|
122
|
+
const d = this.getData(id);
|
123
|
+
if (!d || this.isObsoleteInteraction(id)) {
|
124
|
+
continue;
|
125
|
+
}
|
126
|
+
|
127
|
+
this.markAsObsolete(id);
|
128
|
+
|
129
|
+
fresh.push(id);
|
130
|
+
}
|
131
|
+
|
132
|
+
if (options.preDelay && options.preDelay > 0) {
|
133
|
+
yield new Promise((resolve) => setTimeout(resolve, options.preDelay));
|
134
|
+
}
|
135
|
+
|
136
|
+
const promises: Promise<unknown>[] = [];
|
137
|
+
for (const id of fresh) {
|
138
|
+
promises.push(
|
139
|
+
this.msgRequester.sendMessage(
|
140
|
+
BACKGROUND_PORT,
|
141
|
+
new ApproveInteractionV2Msg(id, result)
|
142
|
+
)
|
143
|
+
);
|
144
|
+
}
|
145
|
+
|
146
|
+
yield Promise.all(promises);
|
147
|
+
|
148
|
+
if (options.postDelay == null || options.postDelay > 0) {
|
149
|
+
yield this.delay(options.postDelay ?? 50);
|
150
|
+
}
|
151
|
+
yield afterFn(this.hasOtherData(ids));
|
152
|
+
this.removeData(ids);
|
153
|
+
}
|
154
|
+
|
155
|
+
/**
|
156
|
+
* 웹페이지에서 어떤 API를 요청해서 extension이 켜졌을때
|
157
|
+
* extension에서 요청을 처리하고 바로 팝업을 닫으면
|
158
|
+
* 이후에 연속적인 api 요청의 경우 다시 페이지가 열려야하는데 이게 은근히 어색한 UX를 만들기 때문에
|
159
|
+
* 이를 대충 해결하기 위해서 approve 이후에 대충 조금 기다리고 남은 interaction이 있느냐 아니냐에 따라 다른 처리를 한다.
|
160
|
+
* @param type
|
161
|
+
* @param id
|
162
|
+
* @param afterFn
|
163
|
+
*/
|
164
|
+
@flow
|
165
|
+
*rejectWithProceedNext(
|
166
|
+
id: string,
|
167
|
+
afterFn: (proceedNext: boolean) => void | Promise<void>
|
168
|
+
) {
|
169
|
+
const d = this.getData(id);
|
170
|
+
if (!d || this.isObsoleteInteraction(id)) {
|
171
|
+
return;
|
172
|
+
}
|
173
|
+
|
174
|
+
this.markAsObsolete(id);
|
175
|
+
yield this.msgRequester.sendMessage(
|
176
|
+
BACKGROUND_PORT,
|
177
|
+
new RejectInteractionMsg(id)
|
178
|
+
);
|
179
|
+
yield this.delay(100);
|
180
|
+
yield afterFn(this.hasOtherData(id));
|
181
|
+
this.removeData(id);
|
182
|
+
}
|
183
|
+
|
184
|
+
/**
|
185
|
+
* 웹페이지에서 어떤 API를 요청해서 extension이 켜졌을때
|
186
|
+
* extension에서 요청을 처리하고 바로 팝업을 닫으면
|
187
|
+
* 이후에 연속적인 api 요청의 경우 다시 페이지가 열려야하는데 이게 은근히 어색한 UX를 만들기 때문에
|
188
|
+
* 이를 대충 해결하기 위해서 approve 이후에 대충 조금 기다리고 남은 interaction이 있느냐 아니냐에 따라 다른 처리를 한다.
|
189
|
+
* @param type
|
190
|
+
* @param id
|
191
|
+
* @param afterFn
|
192
|
+
*/
|
193
|
+
@flow
|
194
|
+
*rejectWithProceedNextV2(
|
195
|
+
ids: string | string[],
|
196
|
+
afterFn: (proceedNext: boolean) => void | Promise<void>
|
197
|
+
) {
|
198
|
+
if (typeof ids === "string") {
|
199
|
+
ids = [ids];
|
200
|
+
}
|
201
|
+
|
202
|
+
const fresh: string[] = [];
|
203
|
+
|
204
|
+
for (const id of ids) {
|
205
|
+
const d = this.getData(id);
|
206
|
+
if (!d || this.isObsoleteInteraction(id)) {
|
207
|
+
continue;
|
208
|
+
}
|
209
|
+
|
210
|
+
this.markAsObsolete(id);
|
211
|
+
|
212
|
+
fresh.push(id);
|
213
|
+
}
|
214
|
+
|
215
|
+
const promises: Promise<unknown>[] = [];
|
216
|
+
for (const id of fresh) {
|
217
|
+
promises.push(
|
218
|
+
this.msgRequester.sendMessage(
|
219
|
+
BACKGROUND_PORT,
|
220
|
+
new RejectInteractionV2Msg(id)
|
221
|
+
)
|
222
|
+
);
|
223
|
+
}
|
224
|
+
|
225
|
+
yield Promise.all(promises);
|
226
|
+
|
227
|
+
yield this.delay(50);
|
228
|
+
yield afterFn(this.hasOtherData(ids));
|
229
|
+
this.removeData(ids);
|
230
|
+
}
|
231
|
+
|
232
|
+
protected delay(ms: number): Promise<void> {
|
233
|
+
return new Promise((resolve) => {
|
234
|
+
setTimeout(resolve, ms);
|
235
|
+
});
|
236
|
+
}
|
237
|
+
|
238
|
+
@flow
|
239
|
+
*rejectAll(type: string) {
|
240
|
+
const data = this.getAllData(type);
|
241
|
+
for (const d of data) {
|
242
|
+
if (this.isObsoleteInteraction(d.id)) {
|
243
|
+
continue;
|
244
|
+
}
|
245
|
+
yield this.msgRequester.sendMessage(
|
246
|
+
BACKGROUND_PORT,
|
247
|
+
new RejectInteractionMsg(d.id)
|
248
|
+
);
|
249
|
+
this.removeData(d.id);
|
250
|
+
}
|
251
|
+
}
|
252
|
+
|
253
|
+
// UI에서 좀 더 편하게 쓸 수 있게 하려고 undefined도 파라미터로 허용함.
|
254
|
+
isObsoleteInteraction(id: string | undefined): boolean {
|
255
|
+
if (!id) {
|
256
|
+
return false;
|
257
|
+
}
|
258
|
+
return this.obsoleteData.get(id) ?? false;
|
259
|
+
}
|
260
|
+
|
261
|
+
@action
|
262
|
+
protected removeData(ids: string | string[]) {
|
263
|
+
if (typeof ids === "string") {
|
264
|
+
ids = [ids];
|
265
|
+
}
|
266
|
+
|
267
|
+
for (const id of ids) {
|
268
|
+
this.data = this.data.filter((d) => d.id !== id);
|
269
|
+
this.obsoleteData.delete(id);
|
270
|
+
}
|
271
|
+
}
|
272
|
+
|
273
|
+
@action
|
274
|
+
protected markAsObsolete(id: string) {
|
275
|
+
if (this.getData(id)) {
|
276
|
+
this.obsoleteData.set(id, true);
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
protected hasOtherData(ids: string | string[]): boolean {
|
281
|
+
if (typeof ids === "string") {
|
282
|
+
ids = [ids];
|
283
|
+
}
|
284
|
+
|
285
|
+
const find = this.data.find((data) => {
|
286
|
+
return !ids.includes(data.id);
|
287
|
+
});
|
288
|
+
return !!find;
|
289
|
+
}
|
290
|
+
}
|
@@ -0,0 +1,121 @@
|
|
1
|
+
import { InteractionStore } from "./interaction";
|
2
|
+
import {
|
3
|
+
GlobalPermissionData,
|
4
|
+
INTERACTION_TYPE_GLOBAL_PERMISSION,
|
5
|
+
INTERACTION_TYPE_PERMISSION,
|
6
|
+
PermissionData,
|
7
|
+
} from "@keplr-wallet/background";
|
8
|
+
import { MessageRequester } from "@keplr-wallet/router";
|
9
|
+
import { computed, makeObservable } from "mobx";
|
10
|
+
|
11
|
+
export class PermissionStore {
|
12
|
+
constructor(
|
13
|
+
protected readonly interactionStore: InteractionStore,
|
14
|
+
protected readonly requester: MessageRequester
|
15
|
+
) {
|
16
|
+
makeObservable(this);
|
17
|
+
}
|
18
|
+
|
19
|
+
get waitingPermissionData() {
|
20
|
+
if (this.waitingPermissionDatas.length > 0) {
|
21
|
+
return this.waitingPermissionDatas[0];
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
get waitingPermissionDatas() {
|
26
|
+
return this.interactionStore.getAllData<PermissionData>(
|
27
|
+
INTERACTION_TYPE_PERMISSION
|
28
|
+
);
|
29
|
+
}
|
30
|
+
|
31
|
+
@computed
|
32
|
+
get waitingPermissionMergedData():
|
33
|
+
| ({
|
34
|
+
ids: string[];
|
35
|
+
} & PermissionData)
|
36
|
+
| undefined {
|
37
|
+
const data = this.waitingPermissionDatas;
|
38
|
+
if (data.length === 0) {
|
39
|
+
return;
|
40
|
+
}
|
41
|
+
|
42
|
+
const first = data[0];
|
43
|
+
const res: {
|
44
|
+
ids: string[];
|
45
|
+
} & PermissionData = {
|
46
|
+
ids: [first.id],
|
47
|
+
chainIds: first.data.chainIds,
|
48
|
+
type: first.data.type,
|
49
|
+
origins: first.data.origins,
|
50
|
+
};
|
51
|
+
for (let i = 1; i < data.length; i++) {
|
52
|
+
const d = data[i];
|
53
|
+
if (d.data.type !== first.data.type) {
|
54
|
+
break;
|
55
|
+
}
|
56
|
+
if (d.data.origins.join(",") !== first.data.origins.join(",")) {
|
57
|
+
break;
|
58
|
+
}
|
59
|
+
|
60
|
+
res.ids.push(d.id);
|
61
|
+
res.chainIds.push(...d.data.chainIds);
|
62
|
+
}
|
63
|
+
|
64
|
+
// Remove duplicated chain ids.
|
65
|
+
res.chainIds = [...new Set(res.chainIds)];
|
66
|
+
|
67
|
+
return res;
|
68
|
+
}
|
69
|
+
|
70
|
+
get waitingGlobalPermissionData() {
|
71
|
+
if (this.waitingGlobalPermissionDatas.length > 0) {
|
72
|
+
return this.waitingGlobalPermissionDatas[0];
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
get waitingGlobalPermissionDatas() {
|
77
|
+
return this.interactionStore.getAllData<GlobalPermissionData>(
|
78
|
+
INTERACTION_TYPE_GLOBAL_PERMISSION
|
79
|
+
);
|
80
|
+
}
|
81
|
+
|
82
|
+
async approvePermissionWithProceedNext(
|
83
|
+
id: string | string[],
|
84
|
+
afterFn: (proceedNext: boolean) => void | Promise<void>
|
85
|
+
) {
|
86
|
+
await this.interactionStore.approveWithProceedNextV2(id, {}, afterFn);
|
87
|
+
}
|
88
|
+
|
89
|
+
async rejectPermissionWithProceedNext(
|
90
|
+
id: string | string[],
|
91
|
+
afterFn: (proceedNext: boolean) => void | Promise<void>
|
92
|
+
) {
|
93
|
+
await this.interactionStore.rejectWithProceedNextV2(id, afterFn);
|
94
|
+
}
|
95
|
+
|
96
|
+
async rejectPermissionAll() {
|
97
|
+
await this.interactionStore.rejectAll(INTERACTION_TYPE_PERMISSION);
|
98
|
+
}
|
99
|
+
|
100
|
+
async approveGlobalPermissionWithProceedNext(
|
101
|
+
id: string,
|
102
|
+
afterFn: (proceedNext: boolean) => void | Promise<void>
|
103
|
+
) {
|
104
|
+
await this.interactionStore.approveWithProceedNextV2(id, {}, afterFn);
|
105
|
+
}
|
106
|
+
|
107
|
+
async rejectGlobalPermissionWithProceedNext(
|
108
|
+
id: string,
|
109
|
+
afterFn: (proceedNext: boolean) => void | Promise<void>
|
110
|
+
) {
|
111
|
+
await this.interactionStore.rejectWithProceedNextV2(id, afterFn);
|
112
|
+
}
|
113
|
+
|
114
|
+
async rejectGlobalPermissionAll() {
|
115
|
+
await this.interactionStore.rejectAll(INTERACTION_TYPE_GLOBAL_PERMISSION);
|
116
|
+
}
|
117
|
+
|
118
|
+
isObsoleteInteraction(id: string | undefined): boolean {
|
119
|
+
return this.interactionStore.isObsoleteInteraction(id);
|
120
|
+
}
|
121
|
+
}
|
@@ -0,0 +1,124 @@
|
|
1
|
+
import { InteractionStore } from "./interaction";
|
2
|
+
import { computed, makeObservable } from "mobx";
|
3
|
+
import { SignDocWrapper } from "@keplr-wallet/cosmos";
|
4
|
+
import { KeplrSignOptions, StdSignDoc } from "@keplr-wallet/types";
|
5
|
+
import { InteractionWaitingData, PlainObject } from "@keplr-wallet/background";
|
6
|
+
|
7
|
+
export type SignInteractionData =
|
8
|
+
| {
|
9
|
+
origin: string;
|
10
|
+
chainId: string;
|
11
|
+
mode: "amino";
|
12
|
+
signer: string;
|
13
|
+
pubKey: Uint8Array;
|
14
|
+
signDoc: StdSignDoc;
|
15
|
+
signOptions: KeplrSignOptions & {
|
16
|
+
isADR36WithString?: boolean;
|
17
|
+
};
|
18
|
+
keyType: string;
|
19
|
+
keyInsensitive: PlainObject;
|
20
|
+
|
21
|
+
eip712?: {
|
22
|
+
types: Record<string, { name: string; type: string }[] | undefined>;
|
23
|
+
domain: Record<string, any>;
|
24
|
+
primaryType: string;
|
25
|
+
};
|
26
|
+
}
|
27
|
+
| {
|
28
|
+
origin: string;
|
29
|
+
chainId: string;
|
30
|
+
mode: "direct";
|
31
|
+
signer: string;
|
32
|
+
pubKey: Uint8Array;
|
33
|
+
signDocBytes: Uint8Array;
|
34
|
+
signOptions: KeplrSignOptions;
|
35
|
+
keyType: string;
|
36
|
+
keyInsensitive: PlainObject;
|
37
|
+
};
|
38
|
+
|
39
|
+
export class SignInteractionStore {
|
40
|
+
constructor(protected readonly interactionStore: InteractionStore) {
|
41
|
+
makeObservable(this);
|
42
|
+
}
|
43
|
+
|
44
|
+
get waitingDatas() {
|
45
|
+
return this.interactionStore.getAllData<SignInteractionData>(
|
46
|
+
"request-sign-cosmos"
|
47
|
+
);
|
48
|
+
}
|
49
|
+
|
50
|
+
@computed
|
51
|
+
get waitingData():
|
52
|
+
| InteractionWaitingData<
|
53
|
+
SignInteractionData & { signDocWrapper: SignDocWrapper }
|
54
|
+
>
|
55
|
+
| undefined {
|
56
|
+
const datas = this.waitingDatas;
|
57
|
+
|
58
|
+
if (datas.length === 0) {
|
59
|
+
return undefined;
|
60
|
+
}
|
61
|
+
|
62
|
+
const data = datas[0];
|
63
|
+
const wrapper =
|
64
|
+
data.data.mode === "amino"
|
65
|
+
? SignDocWrapper.fromAminoSignDoc(data.data.signDoc)
|
66
|
+
: SignDocWrapper.fromDirectSignDocBytes(data.data.signDocBytes);
|
67
|
+
|
68
|
+
return {
|
69
|
+
id: data.id,
|
70
|
+
type: data.type,
|
71
|
+
isInternal: data.isInternal,
|
72
|
+
data: {
|
73
|
+
...data.data,
|
74
|
+
signDocWrapper: wrapper,
|
75
|
+
},
|
76
|
+
};
|
77
|
+
}
|
78
|
+
|
79
|
+
async approveWithProceedNext(
|
80
|
+
id: string,
|
81
|
+
newSignDocWrapper: SignDocWrapper,
|
82
|
+
signature: Uint8Array | undefined,
|
83
|
+
afterFn: (proceedNext: boolean) => void | Promise<void>,
|
84
|
+
options: {
|
85
|
+
preDelay?: number;
|
86
|
+
} = {}
|
87
|
+
) {
|
88
|
+
const res = (() => {
|
89
|
+
if (newSignDocWrapper.mode === "amino") {
|
90
|
+
return {
|
91
|
+
newSignDoc: newSignDocWrapper.aminoSignDoc,
|
92
|
+
};
|
93
|
+
}
|
94
|
+
return {
|
95
|
+
newSignDocBytes: newSignDocWrapper.protoSignDoc.toBytes(),
|
96
|
+
};
|
97
|
+
})();
|
98
|
+
|
99
|
+
await this.interactionStore.approveWithProceedNextV2(
|
100
|
+
id,
|
101
|
+
{
|
102
|
+
...res,
|
103
|
+
signature,
|
104
|
+
},
|
105
|
+
afterFn,
|
106
|
+
options
|
107
|
+
);
|
108
|
+
}
|
109
|
+
|
110
|
+
async rejectWithProceedNext(
|
111
|
+
id: string,
|
112
|
+
afterFn: (proceedNext: boolean) => void | Promise<void>
|
113
|
+
) {
|
114
|
+
await this.interactionStore.rejectWithProceedNext(id, afterFn);
|
115
|
+
}
|
116
|
+
|
117
|
+
async rejectAll() {
|
118
|
+
await this.interactionStore.rejectAll("request-sign-cosmos");
|
119
|
+
}
|
120
|
+
|
121
|
+
isObsoleteInteraction(id: string | undefined): boolean {
|
122
|
+
return this.interactionStore.isObsoleteInteraction(id);
|
123
|
+
}
|
124
|
+
}
|