@novasamatech/host-container 0.6.18 → 0.7.0-1
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/README.md +176 -24
- package/dist/chainConnectionManager.d.ts +3 -5
- package/dist/chainConnectionManager.js +49 -29
- package/dist/createContainer.js +173 -392
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/rateLimiter.d.ts +0 -1
- package/dist/rateLimiter.js +4 -4
- package/dist/types.d.ts +24 -12
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -62,25 +62,59 @@ container.handleFeatureSupported((params, { ok, err }) => {
|
|
|
62
62
|
|
|
63
63
|
### handleDevicePermission
|
|
64
64
|
|
|
65
|
+
The `request` parameter is one of: `'Notifications'`, `'Camera'`, `'Microphone'`, `'Bluetooth'`, `'NFC'`, `'Location'`, `'Clipboard'`, `'OpenUrl'`, `'Biometrics'`.
|
|
66
|
+
|
|
65
67
|
```ts
|
|
66
68
|
container.handleDevicePermission(async (request, { ok, err }) => {
|
|
67
|
-
|
|
69
|
+
// request is a string literal: 'Notifications' | 'Camera' | 'Microphone' | ...
|
|
70
|
+
const granted = await promptDevicePermission(request);
|
|
68
71
|
return ok(granted);
|
|
69
72
|
});
|
|
70
73
|
```
|
|
71
74
|
|
|
72
75
|
### handlePermission
|
|
73
76
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
The `request` parameter is an **array** of `RemotePermission` items. Return `ok(true)` only when **all** permissions in the batch are granted.
|
|
78
|
+
|
|
79
|
+
Each item has one of these shapes:
|
|
80
|
+
- `{ tag: 'Remote', value: string[] }` — HTTP/WS domain patterns (exact or `*.wildcard`)
|
|
81
|
+
- `{ tag: 'WebRTC', value: undefined }` — WebRTC access (may expose user IP)
|
|
82
|
+
- `{ tag: 'ChainSubmit', value: undefined }` — broadcast transactions via `remote_chain_transaction_broadcast`
|
|
83
|
+
- `{ tag: 'PreimageSubmit', value: undefined }` — submit preimages via `remote_preimage_submit`
|
|
84
|
+
- `{ tag: 'StatementSubmit', value: undefined }` — submit statements via `remote_statement_store_submit`
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
container.handlePermission(async (permissions, { ok, err }) => {
|
|
88
|
+
for (const permission of permissions) {
|
|
89
|
+
switch (permission.tag) {
|
|
90
|
+
case 'Remote': {
|
|
91
|
+
const allowed = await checkDomainPermissions(permission.value);
|
|
92
|
+
if (!allowed) return ok(false);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case 'WebRTC': {
|
|
96
|
+
const allowed = await promptWebRTCPermission();
|
|
97
|
+
if (!allowed) return ok(false);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
case 'ChainSubmit': {
|
|
101
|
+
const allowed = await promptChainSubmitPermission();
|
|
102
|
+
if (!allowed) return ok(false);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case 'PreimageSubmit': {
|
|
106
|
+
const allowed = await promptPreimageSubmitPermission();
|
|
107
|
+
if (!allowed) return ok(false);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case 'StatementSubmit': {
|
|
111
|
+
const allowed = await promptStatementSubmitPermission();
|
|
112
|
+
if (!allowed) return ok(false);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
79
116
|
}
|
|
80
|
-
|
|
81
|
-
return ok(true);
|
|
82
|
-
}
|
|
83
|
-
return ok(false);
|
|
117
|
+
return ok(true);
|
|
84
118
|
});
|
|
85
119
|
```
|
|
86
120
|
|
|
@@ -102,6 +136,15 @@ container.handleNavigateTo(async (url, { ok, err }) => {
|
|
|
102
136
|
});
|
|
103
137
|
```
|
|
104
138
|
|
|
139
|
+
### handleDeriveEntropy
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
container.handleDeriveEntropy(async (key, { ok, err }) => {
|
|
143
|
+
const entropy = await deriveEntropy(key);
|
|
144
|
+
return ok(entropy);
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
105
148
|
### handleLocalStorageRead
|
|
106
149
|
|
|
107
150
|
```ts
|
|
@@ -143,6 +186,55 @@ container.handleAccountConnectionStatusSubscribe((_, send, interrupt) => {
|
|
|
143
186
|
});
|
|
144
187
|
```
|
|
145
188
|
|
|
189
|
+
### handleThemeSubscribe
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
container.handleThemeSubscribe((_, send, interrupt) => {
|
|
193
|
+
const listener = (theme: 'light' | 'dark') => send(theme);
|
|
194
|
+
themeService.on('change', listener);
|
|
195
|
+
send(themeService.getCurrentTheme());
|
|
196
|
+
return () => themeService.off('change', listener);
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### handleAccountGetRoot
|
|
201
|
+
|
|
202
|
+
Called when a product requests the user's root (primary) account. Show a permission prompt on first call; cache the grant for the session. Return `NotFound` if the user has no DotNS username.
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
import { RequestCredentialsErr } from '@novasamatech/host-api';
|
|
206
|
+
|
|
207
|
+
container.handleAccountGetRoot(async (_, { ok, err }) => {
|
|
208
|
+
const granted = await promptUserForRootAccountAccess();
|
|
209
|
+
if (!granted) {
|
|
210
|
+
return err(new RequestCredentialsErr.Rejected());
|
|
211
|
+
}
|
|
212
|
+
const rootAccount = await getRootAccount();
|
|
213
|
+
if (!rootAccount) {
|
|
214
|
+
return err(new RequestCredentialsErr.NotConnected());
|
|
215
|
+
}
|
|
216
|
+
return ok({ publicKey: rootAccount.publicKey, name: rootAccount.name ?? undefined });
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### handleRequestLogin
|
|
221
|
+
|
|
222
|
+
Called when a product requests the host login UI. Present the sign-in flow and return the outcome. `reason` is an optional human-readable string the product provides to explain why login is needed.
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
import { LoginErr } from '@novasamatech/host-api';
|
|
226
|
+
|
|
227
|
+
container.handleRequestLogin(async (reason, { ok, err }) => {
|
|
228
|
+
const alreadyConnected = await checkIfConnected();
|
|
229
|
+
if (alreadyConnected) return ok('alreadyConnected');
|
|
230
|
+
|
|
231
|
+
const result = await presentLoginUI(reason);
|
|
232
|
+
if (!result.success) return ok('rejected');
|
|
233
|
+
|
|
234
|
+
return ok('success');
|
|
235
|
+
});
|
|
236
|
+
```
|
|
237
|
+
|
|
146
238
|
### handleAccountGet
|
|
147
239
|
|
|
148
240
|
```ts
|
|
@@ -180,11 +272,11 @@ container.handleAccountCreateProof(async ([[dotnsId, derivationIndex], ringLocat
|
|
|
180
272
|
});
|
|
181
273
|
```
|
|
182
274
|
|
|
183
|
-
###
|
|
275
|
+
### handleGetLegacyAccounts
|
|
184
276
|
|
|
185
277
|
```ts
|
|
186
|
-
container.
|
|
187
|
-
const accounts = await
|
|
278
|
+
container.handleGetLegacyAccounts(async (_, { ok, err }) => {
|
|
279
|
+
const accounts = await getLegacyAccounts();
|
|
188
280
|
return ok(accounts);
|
|
189
281
|
});
|
|
190
282
|
```
|
|
@@ -202,12 +294,12 @@ container.handleCreateTransaction(async ([productAccountId, payload], { ok, err
|
|
|
202
294
|
});
|
|
203
295
|
```
|
|
204
296
|
|
|
205
|
-
###
|
|
297
|
+
### handleCreateTransactionWithLegacyAccount
|
|
206
298
|
|
|
207
299
|
```ts
|
|
208
|
-
container.
|
|
300
|
+
container.handleCreateTransactionWithLegacyAccount(async (payload, { ok, err }) => {
|
|
209
301
|
try {
|
|
210
|
-
const signedTx = await
|
|
302
|
+
const signedTx = await createTransactionWithLegacyAccount(payload);
|
|
211
303
|
return ok(signedTx);
|
|
212
304
|
} catch (e) {
|
|
213
305
|
return err({ tag: 'Rejected' });
|
|
@@ -303,10 +395,11 @@ subscription.unsubscribe();
|
|
|
303
395
|
### handleStatementStoreSubscribe
|
|
304
396
|
|
|
305
397
|
```ts
|
|
306
|
-
container.handleStatementStoreSubscribe((
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
398
|
+
container.handleStatementStoreSubscribe((filter, send, interrupt) => {
|
|
399
|
+
// filter is { tag: 'MatchAll', value: Uint8Array[] } | { tag: 'MatchAny', value: Uint8Array[] }
|
|
400
|
+
const listener = (page) => send(page);
|
|
401
|
+
statementStore.subscribe(filter, listener);
|
|
402
|
+
return () => statementStore.unsubscribe(filter, listener);
|
|
310
403
|
});
|
|
311
404
|
```
|
|
312
405
|
|
|
@@ -359,6 +452,69 @@ container.handlePreimageSubmit(async (preimage, { ok, err }) => {
|
|
|
359
452
|
});
|
|
360
453
|
```
|
|
361
454
|
|
|
455
|
+
### handlePaymentBalanceSubscribe
|
|
456
|
+
|
|
457
|
+
Called when a product subscribes to balance updates. Host should prompt for user consent on the first call; interrupt the subscription to communicate denial.
|
|
458
|
+
|
|
459
|
+
```ts
|
|
460
|
+
container.handlePaymentBalanceSubscribe((_params, send, interrupt) => {
|
|
461
|
+
const unsubscribe = balanceService.subscribe(balance => {
|
|
462
|
+
send({ available: balance.available, pending: balance.pending });
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
return () => unsubscribe();
|
|
466
|
+
});
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### handlePaymentTopUp
|
|
470
|
+
|
|
471
|
+
Called when a product requests a balance top-up from a product-controlled source. Does not require user consent.
|
|
472
|
+
|
|
473
|
+
```ts
|
|
474
|
+
container.handlePaymentTopUp(async ({ amount, source }, { ok, err }) => {
|
|
475
|
+
if (source.tag === 'ProductAccount') {
|
|
476
|
+
const [dotNsIdentifier, derivationIndex] = source.value;
|
|
477
|
+
await transferFromProductAccount(dotNsIdentifier, derivationIndex, amount);
|
|
478
|
+
return ok(undefined);
|
|
479
|
+
}
|
|
480
|
+
if (source.tag === 'PrivateKey') {
|
|
481
|
+
await transferFromPrivateKey(source.value, amount);
|
|
482
|
+
return ok(undefined);
|
|
483
|
+
}
|
|
484
|
+
return err(new PaymentTopUpErr.InvalidSource());
|
|
485
|
+
});
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### handlePaymentRequest
|
|
489
|
+
|
|
490
|
+
Called when a product requests a payment from the user's balance. Host MUST show a confirmation UI. Returns a receipt immediately; settlement is asynchronous.
|
|
491
|
+
|
|
492
|
+
```ts
|
|
493
|
+
container.handlePaymentRequest(async ({ amount, destination }, { ok, err }) => {
|
|
494
|
+
const approved = await showPaymentConfirmation({ amount, destination });
|
|
495
|
+
if (!approved) return err(new PaymentRequestErr.Denied());
|
|
496
|
+
|
|
497
|
+
const paymentId = await paymentService.submit(amount, destination);
|
|
498
|
+
return ok({ id: paymentId });
|
|
499
|
+
});
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### handlePaymentStatusSubscribe
|
|
503
|
+
|
|
504
|
+
Called when a product subscribes to the status of a previously requested payment.
|
|
505
|
+
|
|
506
|
+
```ts
|
|
507
|
+
container.handlePaymentStatusSubscribe((paymentId, send, interrupt) => {
|
|
508
|
+
const unsubscribe = paymentService.trackStatus(paymentId, status => {
|
|
509
|
+
if (status === 'processing') send({ tag: 'Processing', value: undefined });
|
|
510
|
+
if (status === 'completed') send({ tag: 'Completed', value: undefined });
|
|
511
|
+
if (status === 'failed') send({ tag: 'Failed', value: 'settlement failed' });
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
return () => unsubscribe();
|
|
515
|
+
});
|
|
516
|
+
```
|
|
517
|
+
|
|
362
518
|
### handleChainConnection
|
|
363
519
|
|
|
364
520
|
```ts
|
|
@@ -374,10 +530,6 @@ container.handleChainConnection({
|
|
|
374
530
|
const endpoint = chains.get(genesisHash);
|
|
375
531
|
if (!endpoint) return null;
|
|
376
532
|
return getWsProvider(endpoint);
|
|
377
|
-
},
|
|
378
|
-
async submitPermission(transaction) {
|
|
379
|
-
if (hasPermission(transaction)) return true;
|
|
380
|
-
return false;
|
|
381
533
|
}
|
|
382
534
|
});
|
|
383
535
|
```
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { HexString } from '@novasamatech/host-api';
|
|
2
|
-
import type { JsonRpcProvider } from '
|
|
2
|
+
import type { JsonRpcProvider } from 'polkadot-api';
|
|
3
|
+
type JsonRpcConnection = ReturnType<JsonRpcProvider>;
|
|
3
4
|
type PendingRequest = {
|
|
4
5
|
resolve: (result: unknown) => void;
|
|
5
6
|
reject: (error: unknown) => void;
|
|
@@ -10,10 +11,7 @@ type FollowSubscription = {
|
|
|
10
11
|
pendingRequestId?: string;
|
|
11
12
|
};
|
|
12
13
|
type ChainEntry = {
|
|
13
|
-
connection:
|
|
14
|
-
send: (msg: string) => void;
|
|
15
|
-
disconnect: () => void;
|
|
16
|
-
};
|
|
14
|
+
connection: JsonRpcConnection;
|
|
17
15
|
pendingRequests: Map<string, PendingRequest>;
|
|
18
16
|
followSubscriptions: Map<string, FollowSubscription>;
|
|
19
17
|
refCount: number;
|
|
@@ -24,36 +24,31 @@ export function createChainConnectionManager(factory) {
|
|
|
24
24
|
followSubscriptions,
|
|
25
25
|
refCount: 1,
|
|
26
26
|
};
|
|
27
|
-
entry.connection = provider(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
// Request-response (has 'id' field)
|
|
36
|
-
if ('id' in parsed && parsed.id != null) {
|
|
37
|
-
const pending = pendingRequests.get(String(parsed.id));
|
|
27
|
+
entry.connection = provider(message => {
|
|
28
|
+
// Response: has 'id' but no 'method'
|
|
29
|
+
if ('id' in message && message.id != null && !('method' in message)) {
|
|
30
|
+
const pending = pendingRequests.get(String(message.id));
|
|
38
31
|
if (pending) {
|
|
39
|
-
pendingRequests.delete(String(
|
|
40
|
-
if ('error' in
|
|
41
|
-
pending.reject(
|
|
32
|
+
pendingRequests.delete(String(message.id));
|
|
33
|
+
if ('error' in message) {
|
|
34
|
+
pending.reject(message.error);
|
|
42
35
|
}
|
|
43
36
|
else {
|
|
44
|
-
pending.resolve(
|
|
37
|
+
pending.resolve(message.result);
|
|
45
38
|
}
|
|
46
39
|
return;
|
|
47
40
|
}
|
|
48
41
|
}
|
|
49
|
-
// Subscription notification
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
follow.
|
|
56
|
-
|
|
42
|
+
// Subscription notification: has 'method' and 'params'
|
|
43
|
+
if ('method' in message && 'params' in message) {
|
|
44
|
+
const params = message.params;
|
|
45
|
+
if (params?.subscription) {
|
|
46
|
+
const subId = String(params.subscription);
|
|
47
|
+
for (const follow of followSubscriptions.values()) {
|
|
48
|
+
if (follow.chainSubId === subId) {
|
|
49
|
+
follow.eventListener(params.result);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
57
52
|
}
|
|
58
53
|
}
|
|
59
54
|
}
|
|
@@ -68,7 +63,7 @@ export function createChainConnectionManager(factory) {
|
|
|
68
63
|
const id = getNextId();
|
|
69
64
|
return new Promise((resolve, reject) => {
|
|
70
65
|
entry.pendingRequests.set(id, { resolve, reject });
|
|
71
|
-
entry.connection.send(
|
|
66
|
+
entry.connection.send({ jsonrpc: '2.0', id, method, params });
|
|
72
67
|
});
|
|
73
68
|
}
|
|
74
69
|
function startFollow(genesisHash, withRuntime, onEvent) {
|
|
@@ -96,7 +91,12 @@ export function createChainConnectionManager(factory) {
|
|
|
96
91
|
entry.followSubscriptions.delete(followId);
|
|
97
92
|
},
|
|
98
93
|
});
|
|
99
|
-
entry.connection.send(
|
|
94
|
+
entry.connection.send({
|
|
95
|
+
jsonrpc: '2.0',
|
|
96
|
+
id: requestId,
|
|
97
|
+
method: 'chainHead_v1_follow',
|
|
98
|
+
params: [withRuntime],
|
|
99
|
+
});
|
|
100
100
|
return { followId };
|
|
101
101
|
}
|
|
102
102
|
function stopFollow(genesisHash, followId) {
|
|
@@ -109,7 +109,12 @@ export function createChainConnectionManager(factory) {
|
|
|
109
109
|
entry.followSubscriptions.delete(followId);
|
|
110
110
|
if (follow.chainSubId) {
|
|
111
111
|
const id = getNextId();
|
|
112
|
-
entry.connection.send(
|
|
112
|
+
entry.connection.send({
|
|
113
|
+
jsonrpc: '2.0',
|
|
114
|
+
id,
|
|
115
|
+
method: 'chainHead_v1_unfollow',
|
|
116
|
+
params: [follow.chainSubId],
|
|
117
|
+
});
|
|
113
118
|
}
|
|
114
119
|
else if (follow.pendingRequestId) {
|
|
115
120
|
// Follow response hasn't arrived yet — replace the pending resolve to send unfollow when it does
|
|
@@ -118,7 +123,12 @@ export function createChainConnectionManager(factory) {
|
|
|
118
123
|
const chainSubId = result;
|
|
119
124
|
if (chainSubId) {
|
|
120
125
|
const unfollowId = getNextId();
|
|
121
|
-
entry.connection.send(
|
|
126
|
+
entry.connection.send({
|
|
127
|
+
jsonrpc: '2.0',
|
|
128
|
+
id: unfollowId,
|
|
129
|
+
method: 'chainHead_v1_unfollow',
|
|
130
|
+
params: [chainSubId],
|
|
131
|
+
});
|
|
122
132
|
}
|
|
123
133
|
},
|
|
124
134
|
reject: () => {
|
|
@@ -147,7 +157,12 @@ export function createChainConnectionManager(factory) {
|
|
|
147
157
|
for (const follow of entry.followSubscriptions.values()) {
|
|
148
158
|
if (follow.chainSubId) {
|
|
149
159
|
const id = getNextId();
|
|
150
|
-
entry.connection.send(
|
|
160
|
+
entry.connection.send({
|
|
161
|
+
jsonrpc: '2.0',
|
|
162
|
+
id,
|
|
163
|
+
method: 'chainHead_v1_unfollow',
|
|
164
|
+
params: [follow.chainSubId],
|
|
165
|
+
});
|
|
151
166
|
}
|
|
152
167
|
}
|
|
153
168
|
entry.followSubscriptions.clear();
|
|
@@ -160,7 +175,12 @@ export function createChainConnectionManager(factory) {
|
|
|
160
175
|
for (const follow of entry.followSubscriptions.values()) {
|
|
161
176
|
if (follow.chainSubId) {
|
|
162
177
|
const id = getNextId();
|
|
163
|
-
entry.connection.send(
|
|
178
|
+
entry.connection.send({
|
|
179
|
+
jsonrpc: '2.0',
|
|
180
|
+
id,
|
|
181
|
+
method: 'chainHead_v1_unfollow',
|
|
182
|
+
params: [follow.chainSubId],
|
|
183
|
+
});
|
|
164
184
|
}
|
|
165
185
|
}
|
|
166
186
|
entry.followSubscriptions.clear();
|
package/dist/createContainer.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { ChatBotRegistrationErr, ChatMessagePostingErr, ChatRoomRegistrationErr, CreateProofErr, CreateTransactionErr, GenericError, NavigateToErr, PreimageSubmitErr, RequestCredentialsErr, SigningErr, StatementProofErr, StorageErr, createTransport, enumValue, isEnumVariant, resultErr, resultOk, } from '@novasamatech/host-api';
|
|
1
|
+
import { ChatBotRegistrationErr, ChatMessagePostingErr, ChatRoomRegistrationErr, CreateProofErr, CreateTransactionErr, DeriveEntropyErr, GenericError, LoginErr, NavigateToErr, PaymentRequestErr, PaymentTopUpErr, PreimageSubmitErr, RemotePermission, RequestCredentialsErr, SigningErr, StatementProofErr, StorageErr, createTransport, enumValue, isEnumVariant, resultErr, resultOk, } from '@novasamatech/host-api';
|
|
2
2
|
import { err, errAsync, ok, okAsync } from 'neverthrow';
|
|
3
3
|
import { createChainConnectionManager } from './chainConnectionManager.js';
|
|
4
4
|
const UNSUPPORTED_MESSAGE_FORMAT_ERROR = 'Unsupported message format';
|
|
5
5
|
const NOT_IMPLEMENTED = 'Not implemented';
|
|
6
6
|
function guardVersion(value, tag, error) {
|
|
7
|
+
if (!value) {
|
|
8
|
+
return err(error);
|
|
9
|
+
}
|
|
7
10
|
if (isEnumVariant(value, tag)) {
|
|
8
11
|
return ok(value.value);
|
|
9
12
|
}
|
|
@@ -51,393 +54,204 @@ export function createContainer(provider) {
|
|
|
51
54
|
};
|
|
52
55
|
};
|
|
53
56
|
}
|
|
57
|
+
function makeNotImplementedSlot(method, makeError) {
|
|
58
|
+
// Cast needed: async () returns a fixed v1 error shape that TypeScript can't verify
|
|
59
|
+
// matches the generic Method's response type without evaluating template literal types.
|
|
60
|
+
const handler = async () => enumValue('v1', resultErr(makeError()));
|
|
61
|
+
return makeRequestSlot(method, handler);
|
|
62
|
+
}
|
|
63
|
+
function makeInterruptSlot(method) {
|
|
64
|
+
// Cast needed: the default handler ignores typed params/send which TypeScript can't verify
|
|
65
|
+
// matches the generic Method's subscription type without evaluating template literal types.
|
|
66
|
+
const defaultHandler = ((_params, _send, interrupt) => {
|
|
67
|
+
queueMicrotask(interrupt);
|
|
68
|
+
return () => {
|
|
69
|
+
/* nothing to clean up */
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
return makeSubscriptionSlot(method, defaultHandler);
|
|
73
|
+
}
|
|
74
|
+
function makePermissionGatedRequestSlot(method, permissionVariant, makeError) {
|
|
75
|
+
const defaultHandler = async () => enumValue('v1', resultErr(makeError()));
|
|
76
|
+
let current = defaultHandler;
|
|
77
|
+
let version = 0;
|
|
78
|
+
transport.handleRequest(method, async (params) => {
|
|
79
|
+
const permissionResponse = await handleRemotePermissionSlot.call(enumValue('v1', [enumValue(permissionVariant, undefined)]));
|
|
80
|
+
const permissionGranted = isEnumVariant(permissionResponse, 'v1') &&
|
|
81
|
+
permissionResponse.value.success === true &&
|
|
82
|
+
permissionResponse.value.value === true;
|
|
83
|
+
if (!permissionGranted) {
|
|
84
|
+
return enumValue('v1', resultErr(makeError()));
|
|
85
|
+
}
|
|
86
|
+
return current(params);
|
|
87
|
+
});
|
|
88
|
+
return {
|
|
89
|
+
update: handler => {
|
|
90
|
+
current = handler;
|
|
91
|
+
const myVersion = ++version;
|
|
92
|
+
return () => {
|
|
93
|
+
if (myVersion !== version)
|
|
94
|
+
return;
|
|
95
|
+
version++;
|
|
96
|
+
current = defaultHandler;
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
call: (...args) => current(...args),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function handleV1Request(slot, makeError, handler) {
|
|
103
|
+
init();
|
|
104
|
+
const version = 'v1';
|
|
105
|
+
return slot.update(async (params) => {
|
|
106
|
+
const error = makeError();
|
|
107
|
+
return guardVersion(params, version, error)
|
|
108
|
+
.asyncMap(async (p) => await handler(p, { ok: (okAsync), err: (errAsync) }))
|
|
109
|
+
.andThen(r => r.map(v => enumValue(version, resultOk(v))))
|
|
110
|
+
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
111
|
+
.unwrapOr(enumValue(version, resultErr(error)));
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
function handleV1Subscription(slot, handler) {
|
|
115
|
+
init();
|
|
116
|
+
const version = 'v1';
|
|
117
|
+
const slotHandler = ((params, send, interrupt) => {
|
|
118
|
+
return guardVersion(params, version, null)
|
|
119
|
+
.map(p => handler(p, ((payload) => send(enumValue(version, payload))), interrupt))
|
|
120
|
+
.orTee(interrupt)
|
|
121
|
+
.unwrapOr(() => {
|
|
122
|
+
/* empty */
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
return slot(slotHandler);
|
|
126
|
+
}
|
|
54
127
|
// account slots
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
});
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
});
|
|
63
|
-
const handleGetNonProductAccountsSlot = makeRequestSlot('host_get_non_product_accounts', async () => {
|
|
64
|
-
const error = new RequestCredentialsErr.Unknown({ reason: NOT_IMPLEMENTED });
|
|
65
|
-
return enumValue('v1', resultErr(error));
|
|
66
|
-
});
|
|
67
|
-
const handleAccountCreateProofSlot = makeRequestSlot('host_account_create_proof', async () => {
|
|
68
|
-
const error = new CreateProofErr.Unknown({ reason: NOT_IMPLEMENTED });
|
|
69
|
-
return enumValue('v1', resultErr(error));
|
|
70
|
-
});
|
|
128
|
+
const handleAccountGetRootSlot = makeNotImplementedSlot('host_account_get_root', () => new RequestCredentialsErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
129
|
+
const handleRequestLoginSlot = makeNotImplementedSlot('host_request_login', () => new LoginErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
130
|
+
const handleAccountGetSlot = makeNotImplementedSlot('host_account_get', () => new RequestCredentialsErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
131
|
+
const handleAccountGetAliasSlot = makeNotImplementedSlot('host_account_get_alias', () => new RequestCredentialsErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
132
|
+
const handleGetLegacyAccountsSlot = makeNotImplementedSlot('host_get_legacy_accounts', () => new RequestCredentialsErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
133
|
+
const handleAccountCreateProofSlot = makeNotImplementedSlot('host_account_create_proof', () => new CreateProofErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
134
|
+
// entropy derivation slot
|
|
135
|
+
const handleDeriveEntropySlot = makeNotImplementedSlot('host_derive_entropy', () => new DeriveEntropyErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
71
136
|
// storage slots
|
|
72
|
-
const handleLocalStorageReadSlot =
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
});
|
|
76
|
-
const handleLocalStorageWriteSlot = makeRequestSlot('host_local_storage_write', async () => {
|
|
77
|
-
const error = new StorageErr.Unknown({ reason: NOT_IMPLEMENTED });
|
|
78
|
-
return enumValue('v1', resultErr(error));
|
|
79
|
-
});
|
|
80
|
-
const handleLocalStorageClearSlot = makeRequestSlot('host_local_storage_clear', async () => {
|
|
81
|
-
const error = new StorageErr.Unknown({ reason: NOT_IMPLEMENTED });
|
|
82
|
-
return enumValue('v1', resultErr(error));
|
|
83
|
-
});
|
|
137
|
+
const handleLocalStorageReadSlot = makeNotImplementedSlot('host_local_storage_read', () => new StorageErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
138
|
+
const handleLocalStorageWriteSlot = makeNotImplementedSlot('host_local_storage_write', () => new StorageErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
139
|
+
const handleLocalStorageClearSlot = makeNotImplementedSlot('host_local_storage_clear', () => new StorageErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
84
140
|
// signing slots
|
|
85
|
-
const handleSignRawSlot =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
});
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
});
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
});
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
});
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
});
|
|
105
|
-
const handleDevicePermissionSlot = makeRequestSlot('host_device_permission', async () => {
|
|
106
|
-
const error = new GenericError({ reason: NOT_IMPLEMENTED });
|
|
107
|
-
return enumValue('v1', resultErr(error));
|
|
108
|
-
});
|
|
109
|
-
const handleRemotePermissionSlot = makeRequestSlot('remote_permission', async () => {
|
|
110
|
-
const error = new GenericError({ reason: NOT_IMPLEMENTED });
|
|
111
|
-
return enumValue('v1', resultErr(error));
|
|
112
|
-
});
|
|
113
|
-
const handlePushNotificationSlot = makeRequestSlot('host_push_notification', async () => {
|
|
114
|
-
const error = new GenericError({ reason: NOT_IMPLEMENTED });
|
|
115
|
-
return enumValue('v1', resultErr(error));
|
|
116
|
-
});
|
|
117
|
-
const handleNavigateToSlot = makeRequestSlot('host_navigate_to', async () => {
|
|
118
|
-
const error = new NavigateToErr.Unknown({ reason: NOT_IMPLEMENTED });
|
|
119
|
-
return enumValue('v1', resultErr(error));
|
|
120
|
-
});
|
|
121
|
-
const handleChatCreateRoomSlot = makeRequestSlot('host_chat_create_room', async () => {
|
|
122
|
-
const error = new ChatRoomRegistrationErr.Unknown({ reason: NOT_IMPLEMENTED });
|
|
123
|
-
return enumValue('v1', resultErr(error));
|
|
124
|
-
});
|
|
125
|
-
const handleChatBotRegistrationSlot = makeRequestSlot('host_chat_register_bot', async () => {
|
|
126
|
-
const error = new ChatBotRegistrationErr.Unknown({ reason: NOT_IMPLEMENTED });
|
|
127
|
-
return enumValue('v1', resultErr(error));
|
|
128
|
-
});
|
|
129
|
-
const handleChatPostMessageSlot = makeRequestSlot('host_chat_post_message', async () => {
|
|
130
|
-
const error = new ChatMessagePostingErr.Unknown({ reason: NOT_IMPLEMENTED });
|
|
131
|
-
return enumValue('v1', resultErr(error));
|
|
132
|
-
});
|
|
133
|
-
const handleStatementStoreSubmitSlot = makeRequestSlot('remote_statement_store_submit', async () => {
|
|
134
|
-
const error = new GenericError({ reason: NOT_IMPLEMENTED });
|
|
135
|
-
return enumValue('v1', resultErr(error));
|
|
136
|
-
});
|
|
137
|
-
const handleStatementStoreCreateProofSlot = makeRequestSlot('remote_statement_store_create_proof', async () => {
|
|
138
|
-
const error = new StatementProofErr.Unknown({ reason: NOT_IMPLEMENTED });
|
|
139
|
-
return enumValue('v1', resultErr(error));
|
|
140
|
-
});
|
|
141
|
-
const handlePreimageSubmitSlot = makeRequestSlot('remote_preimage_submit', async () => {
|
|
142
|
-
const error = new PreimageSubmitErr.Unknown({ reason: NOT_IMPLEMENTED });
|
|
143
|
-
return enumValue('v1', resultErr(error));
|
|
144
|
-
});
|
|
141
|
+
const handleSignRawSlot = makeNotImplementedSlot('host_sign_raw', () => new SigningErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
142
|
+
const handleSignPayloadSlot = makeNotImplementedSlot('host_sign_payload', () => new SigningErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
143
|
+
const handleSignRawWithLegacyAccountSlot = makeNotImplementedSlot('host_sign_raw_with_legacy_account', () => new SigningErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
144
|
+
const handleSignPayloadWithLegacyAccountSlot = makeNotImplementedSlot('host_sign_payload_with_legacy_account', () => new SigningErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
145
|
+
const handleCreateTransactionSlot = makeNotImplementedSlot('host_create_transaction', () => new CreateTransactionErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
146
|
+
const handleCreateTransactionWithLegacyAccountSlot = makeNotImplementedSlot('host_create_transaction_with_legacy_account', () => new CreateTransactionErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
147
|
+
const handleFeatureSupportedSlot = makeNotImplementedSlot('host_feature_supported', () => new GenericError({ reason: NOT_IMPLEMENTED }));
|
|
148
|
+
const handleDevicePermissionSlot = makeNotImplementedSlot('host_device_permission', () => new GenericError({ reason: NOT_IMPLEMENTED }));
|
|
149
|
+
const handleRemotePermissionSlot = makeNotImplementedSlot('remote_permission', () => new GenericError({ reason: NOT_IMPLEMENTED }));
|
|
150
|
+
const handlePushNotificationSlot = makeNotImplementedSlot('host_push_notification', () => new GenericError({ reason: NOT_IMPLEMENTED }));
|
|
151
|
+
const handleNavigateToSlot = makeNotImplementedSlot('host_navigate_to', () => new NavigateToErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
152
|
+
const handleChatCreateRoomSlot = makeNotImplementedSlot('host_chat_create_room', () => new ChatRoomRegistrationErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
153
|
+
const handleChatBotRegistrationSlot = makeNotImplementedSlot('host_chat_register_bot', () => new ChatBotRegistrationErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
154
|
+
const handleChatPostMessageSlot = makeNotImplementedSlot('host_chat_post_message', () => new ChatMessagePostingErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
155
|
+
const handleStatementStoreSubmitSlot = makePermissionGatedRequestSlot('remote_statement_store_submit', 'StatementSubmit', () => new GenericError({ reason: NOT_IMPLEMENTED }));
|
|
156
|
+
const handleStatementStoreCreateProofSlot = makeNotImplementedSlot('remote_statement_store_create_proof', () => new StatementProofErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
157
|
+
const handlePreimageSubmitSlot = makePermissionGatedRequestSlot('remote_preimage_submit', 'PreimageSubmit', () => new PreimageSubmitErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
158
|
+
// payment request slots
|
|
159
|
+
const handlePaymentTopUpSlot = makeNotImplementedSlot('host_payment_top_up', () => new PaymentTopUpErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
160
|
+
const handlePaymentRequestSlot = makeNotImplementedSlot('host_payment_request', () => new PaymentRequestErr.Unknown({ reason: NOT_IMPLEMENTED }));
|
|
145
161
|
// subscription slots — default interrupts on next microtask so that
|
|
146
162
|
// the caller has a chance to register an onInterrupt listener first
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
return () => {
|
|
156
|
-
/* nothing to clean up */
|
|
157
|
-
};
|
|
158
|
-
});
|
|
159
|
-
const handleChatActionSubscribeSlot = makeSubscriptionSlot('host_chat_action_subscribe', (_params, _send, interrupt) => {
|
|
160
|
-
queueMicrotask(interrupt);
|
|
161
|
-
return () => {
|
|
162
|
-
/* nothing to clean up */
|
|
163
|
-
};
|
|
164
|
-
});
|
|
165
|
-
const handleStatementStoreSubscribeSlot = makeSubscriptionSlot('remote_statement_store_subscribe', (_params, _send, interrupt) => {
|
|
166
|
-
queueMicrotask(interrupt);
|
|
167
|
-
return () => {
|
|
168
|
-
/* nothing to clean up */
|
|
169
|
-
};
|
|
170
|
-
});
|
|
171
|
-
const handlePreimageLookupSubscribeSlot = makeSubscriptionSlot('remote_preimage_lookup_subscribe', (_params, _send, interrupt) => {
|
|
172
|
-
queueMicrotask(interrupt);
|
|
173
|
-
return () => {
|
|
174
|
-
/* nothing to clean up */
|
|
175
|
-
};
|
|
176
|
-
});
|
|
163
|
+
const handleThemeSubscribeSlot = makeInterruptSlot('host_theme_subscribe');
|
|
164
|
+
const handleAccountConnectionStatusSubscribeSlot = makeInterruptSlot('host_account_connection_status_subscribe');
|
|
165
|
+
const handleChatListSubscribeSlot = makeInterruptSlot('host_chat_list_subscribe');
|
|
166
|
+
const handleChatActionSubscribeSlot = makeInterruptSlot('host_chat_action_subscribe');
|
|
167
|
+
const handleStatementStoreSubscribeSlot = makeInterruptSlot('remote_statement_store_subscribe');
|
|
168
|
+
const handlePreimageLookupSubscribeSlot = makeInterruptSlot('remote_preimage_lookup_subscribe');
|
|
169
|
+
const handlePaymentBalanceSubscribeSlot = makeInterruptSlot('host_payment_balance_subscribe');
|
|
170
|
+
const handlePaymentStatusSubscribeSlot = makeInterruptSlot('host_payment_status_subscribe');
|
|
177
171
|
return {
|
|
178
172
|
handleFeatureSupported(handler) {
|
|
179
|
-
|
|
180
|
-
return handleFeatureSupportedSlot.update(async (message) => {
|
|
181
|
-
const version = 'v1';
|
|
182
|
-
const error = new GenericError({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
183
|
-
return guardVersion(message, version, error)
|
|
184
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
185
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
186
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
187
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
188
|
-
});
|
|
173
|
+
return handleV1Request(handleFeatureSupportedSlot, () => new GenericError({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
189
174
|
},
|
|
190
175
|
handleDevicePermission(handler) {
|
|
191
|
-
|
|
192
|
-
return handleDevicePermissionSlot.update(async (message) => {
|
|
193
|
-
const version = 'v1';
|
|
194
|
-
const error = new GenericError({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
195
|
-
return guardVersion(message, version, error)
|
|
196
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
197
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
198
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
199
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
200
|
-
});
|
|
176
|
+
return handleV1Request(handleDevicePermissionSlot, () => new GenericError({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
201
177
|
},
|
|
202
178
|
handlePermission(handler) {
|
|
203
|
-
|
|
204
|
-
return handleRemotePermissionSlot.update(async (message) => {
|
|
205
|
-
const version = 'v1';
|
|
206
|
-
const error = new GenericError({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
207
|
-
return guardVersion(message, version, error)
|
|
208
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
209
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
210
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
211
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
212
|
-
});
|
|
179
|
+
return handleV1Request(handleRemotePermissionSlot, () => new GenericError({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
213
180
|
},
|
|
214
181
|
handlePushNotification(handler) {
|
|
215
|
-
|
|
216
|
-
return handlePushNotificationSlot.update(async (message) => {
|
|
217
|
-
const version = 'v1';
|
|
218
|
-
const error = new GenericError({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
219
|
-
return guardVersion(message, version, error)
|
|
220
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
221
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
222
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
223
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
224
|
-
});
|
|
182
|
+
return handleV1Request(handlePushNotificationSlot, () => new GenericError({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
225
183
|
},
|
|
226
184
|
handleNavigateTo(handler) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
return guardVersion(message, version, error)
|
|
232
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
233
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
234
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
235
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
236
|
-
});
|
|
185
|
+
return handleV1Request(handleNavigateToSlot, () => new NavigateToErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
186
|
+
},
|
|
187
|
+
handleDeriveEntropy(handler) {
|
|
188
|
+
return handleV1Request(handleDeriveEntropySlot, () => new DeriveEntropyErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
237
189
|
},
|
|
238
190
|
handleLocalStorageRead(handler) {
|
|
239
|
-
|
|
240
|
-
return handleLocalStorageReadSlot.update(async (message) => {
|
|
241
|
-
const version = 'v1';
|
|
242
|
-
const error = new StorageErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
243
|
-
return guardVersion(message, version, error)
|
|
244
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
245
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
246
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
247
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
248
|
-
});
|
|
191
|
+
return handleV1Request(handleLocalStorageReadSlot, () => new StorageErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
249
192
|
},
|
|
250
193
|
handleLocalStorageWrite(handler) {
|
|
251
|
-
|
|
252
|
-
return handleLocalStorageWriteSlot.update(async (message) => {
|
|
253
|
-
const version = 'v1';
|
|
254
|
-
const error = new StorageErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
255
|
-
return guardVersion(message, version, error)
|
|
256
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
257
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
258
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
259
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
260
|
-
});
|
|
194
|
+
return handleV1Request(handleLocalStorageWriteSlot, () => new StorageErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
261
195
|
},
|
|
262
196
|
handleLocalStorageClear(handler) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
});
|
|
197
|
+
return handleV1Request(handleLocalStorageClearSlot, () => new StorageErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
198
|
+
},
|
|
199
|
+
handleThemeSubscribe(handler) {
|
|
200
|
+
return handleV1Subscription(handleThemeSubscribeSlot, handler);
|
|
201
|
+
},
|
|
202
|
+
handleAccountGetRoot(handler) {
|
|
203
|
+
return handleV1Request(handleAccountGetRootSlot, () => new RequestCredentialsErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
204
|
+
},
|
|
205
|
+
handleRequestLogin(handler) {
|
|
206
|
+
return handleV1Request(handleRequestLoginSlot, () => new LoginErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
273
207
|
},
|
|
274
208
|
handleAccountConnectionStatusSubscribe(handler) {
|
|
275
|
-
|
|
276
|
-
return handleAccountConnectionStatusSubscribeSlot((params, send, interrupt) => {
|
|
277
|
-
const version = 'v1';
|
|
278
|
-
return guardVersion(params, version, null)
|
|
279
|
-
.map(params => handler(params, payload => send(enumValue(version, payload)), interrupt))
|
|
280
|
-
.orTee(interrupt)
|
|
281
|
-
.unwrapOr(() => {
|
|
282
|
-
/* empty */
|
|
283
|
-
});
|
|
284
|
-
});
|
|
209
|
+
return handleV1Subscription(handleAccountConnectionStatusSubscribeSlot, handler);
|
|
285
210
|
},
|
|
286
211
|
handleAccountGet(handler) {
|
|
287
|
-
|
|
288
|
-
return handleAccountGetSlot.update(async (params) => {
|
|
289
|
-
const version = 'v1';
|
|
290
|
-
const error = new RequestCredentialsErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
291
|
-
return guardVersion(params, version, error)
|
|
292
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
293
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
294
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
295
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
296
|
-
});
|
|
212
|
+
return handleV1Request(handleAccountGetSlot, () => new RequestCredentialsErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
297
213
|
},
|
|
298
214
|
handleAccountGetAlias(handler) {
|
|
299
|
-
|
|
300
|
-
return handleAccountGetAliasSlot.update(async (params) => {
|
|
301
|
-
const version = 'v1';
|
|
302
|
-
const error = new RequestCredentialsErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
303
|
-
return guardVersion(params, version, error)
|
|
304
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
305
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
306
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
307
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
308
|
-
});
|
|
215
|
+
return handleV1Request(handleAccountGetAliasSlot, () => new RequestCredentialsErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
309
216
|
},
|
|
310
217
|
handleAccountCreateProof(handler) {
|
|
311
|
-
|
|
312
|
-
return handleAccountCreateProofSlot.update(async (params) => {
|
|
313
|
-
const version = 'v1';
|
|
314
|
-
const error = new CreateProofErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
315
|
-
return guardVersion(params, version, error)
|
|
316
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
317
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
318
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
319
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
320
|
-
});
|
|
218
|
+
return handleV1Request(handleAccountCreateProofSlot, () => new CreateProofErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
321
219
|
},
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
return handleGetNonProductAccountsSlot.update(async (params) => {
|
|
325
|
-
const version = 'v1';
|
|
326
|
-
const error = new RequestCredentialsErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
327
|
-
return guardVersion(params, version, error)
|
|
328
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
329
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
330
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
331
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
332
|
-
});
|
|
220
|
+
handleGetLegacyAccounts(handler) {
|
|
221
|
+
return handleV1Request(handleGetLegacyAccountsSlot, () => new RequestCredentialsErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
333
222
|
},
|
|
334
223
|
handleCreateTransaction(handler) {
|
|
335
|
-
|
|
336
|
-
return handleCreateTransactionSlot.update(async (params) => {
|
|
337
|
-
const version = 'v1';
|
|
338
|
-
const error = new CreateTransactionErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
339
|
-
return guardVersion(params, version, error)
|
|
340
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
341
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
342
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
343
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
344
|
-
});
|
|
224
|
+
return handleV1Request(handleCreateTransactionSlot, () => new CreateTransactionErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
345
225
|
},
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
return handleCreateTransactionWithNonProductAccountSlot.update(async (params) => {
|
|
349
|
-
const version = 'v1';
|
|
350
|
-
const error = new CreateTransactionErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
351
|
-
return guardVersion(params, version, error)
|
|
352
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
353
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
354
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
355
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
356
|
-
});
|
|
226
|
+
handleCreateTransactionWithLegacyAccount(handler) {
|
|
227
|
+
return handleV1Request(handleCreateTransactionWithLegacyAccountSlot, () => new CreateTransactionErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
357
228
|
},
|
|
358
229
|
handleSignRaw(handler) {
|
|
359
|
-
|
|
360
|
-
return handleSignRawSlot.update(async (params) => {
|
|
361
|
-
const version = 'v1';
|
|
362
|
-
const error = new SigningErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
363
|
-
return guardVersion(params, version, error)
|
|
364
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
365
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
366
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
367
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
368
|
-
});
|
|
230
|
+
return handleV1Request(handleSignRawSlot, () => new SigningErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
369
231
|
},
|
|
370
232
|
handleSignPayload(handler) {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
379
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
380
|
-
});
|
|
233
|
+
return handleV1Request(handleSignPayloadSlot, () => new SigningErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
234
|
+
},
|
|
235
|
+
handleSignRawWithLegacyAccount(handler) {
|
|
236
|
+
return handleV1Request(handleSignRawWithLegacyAccountSlot, () => new SigningErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
237
|
+
},
|
|
238
|
+
handleSignPayloadWithLegacyAccount(handler) {
|
|
239
|
+
return handleV1Request(handleSignPayloadWithLegacyAccountSlot, () => new SigningErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
381
240
|
},
|
|
382
241
|
handleChatCreateRoom(handler) {
|
|
383
|
-
|
|
384
|
-
return handleChatCreateRoomSlot.update(async (params) => {
|
|
385
|
-
const version = 'v1';
|
|
386
|
-
const error = new ChatRoomRegistrationErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
387
|
-
return guardVersion(params, version, error)
|
|
388
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
389
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
390
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
391
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
392
|
-
});
|
|
242
|
+
return handleV1Request(handleChatCreateRoomSlot, () => new ChatRoomRegistrationErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
393
243
|
},
|
|
394
244
|
handleChatBotRegistration(handler) {
|
|
395
|
-
|
|
396
|
-
return handleChatBotRegistrationSlot.update(async (params) => {
|
|
397
|
-
const version = 'v1';
|
|
398
|
-
const error = new ChatBotRegistrationErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
399
|
-
return guardVersion(params, version, error)
|
|
400
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
401
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
402
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
403
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
404
|
-
});
|
|
245
|
+
return handleV1Request(handleChatBotRegistrationSlot, () => new ChatBotRegistrationErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
405
246
|
},
|
|
406
247
|
handleChatListSubscribe(handler) {
|
|
407
|
-
|
|
408
|
-
return handleChatListSubscribeSlot((params, send, interrupt) => {
|
|
409
|
-
const version = 'v1';
|
|
410
|
-
return guardVersion(params, version, null)
|
|
411
|
-
.map(params => handler(params, payload => send(enumValue(version, payload)), interrupt))
|
|
412
|
-
.orTee(interrupt)
|
|
413
|
-
.unwrapOr(() => {
|
|
414
|
-
/* empty */
|
|
415
|
-
});
|
|
416
|
-
});
|
|
248
|
+
return handleV1Subscription(handleChatListSubscribeSlot, handler);
|
|
417
249
|
},
|
|
418
250
|
handleChatPostMessage(handler) {
|
|
419
|
-
|
|
420
|
-
return handleChatPostMessageSlot.update(async (params) => {
|
|
421
|
-
const version = 'v1';
|
|
422
|
-
const error = new ChatMessagePostingErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
423
|
-
return guardVersion(params, version, error)
|
|
424
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
425
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
426
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
427
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
428
|
-
});
|
|
251
|
+
return handleV1Request(handleChatPostMessageSlot, () => new ChatMessagePostingErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
429
252
|
},
|
|
430
253
|
handleChatActionSubscribe(handler) {
|
|
431
|
-
|
|
432
|
-
return handleChatActionSubscribeSlot((params, send, interrupt) => {
|
|
433
|
-
const version = 'v1';
|
|
434
|
-
return guardVersion(params, version, null)
|
|
435
|
-
.map(params => handler(params, payload => send(enumValue(version, payload)), interrupt))
|
|
436
|
-
.orTee(interrupt)
|
|
437
|
-
.unwrapOr(() => {
|
|
438
|
-
/* empty */
|
|
439
|
-
});
|
|
440
|
-
});
|
|
254
|
+
return handleV1Subscription(handleChatActionSubscribeSlot, handler);
|
|
441
255
|
},
|
|
442
256
|
renderChatCustomMessage({ messageId, messageType, payload }, callback) {
|
|
443
257
|
init();
|
|
@@ -448,64 +262,31 @@ export function createContainer(provider) {
|
|
|
448
262
|
});
|
|
449
263
|
},
|
|
450
264
|
handleStatementStoreSubscribe(handler) {
|
|
451
|
-
|
|
452
|
-
return handleStatementStoreSubscribeSlot((params, send, interrupt) => {
|
|
453
|
-
const version = 'v1';
|
|
454
|
-
return guardVersion(params, version, null)
|
|
455
|
-
.map(params => handler(params, payload => send(enumValue(version, payload)), interrupt))
|
|
456
|
-
.orTee(interrupt)
|
|
457
|
-
.unwrapOr(() => {
|
|
458
|
-
/* empty */
|
|
459
|
-
});
|
|
460
|
-
});
|
|
265
|
+
return handleV1Subscription(handleStatementStoreSubscribeSlot, handler);
|
|
461
266
|
},
|
|
462
267
|
handleStatementStoreCreateProof(handler) {
|
|
463
|
-
|
|
464
|
-
return handleStatementStoreCreateProofSlot.update(async (params) => {
|
|
465
|
-
const version = 'v1';
|
|
466
|
-
const error = new StatementProofErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
467
|
-
return guardVersion(params, version, error)
|
|
468
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
469
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
470
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
471
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
472
|
-
});
|
|
268
|
+
return handleV1Request(handleStatementStoreCreateProofSlot, () => new StatementProofErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
473
269
|
},
|
|
474
270
|
handleStatementStoreSubmit(handler) {
|
|
475
|
-
|
|
476
|
-
return handleStatementStoreSubmitSlot.update(async (params) => {
|
|
477
|
-
const version = 'v1';
|
|
478
|
-
const error = new GenericError({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR });
|
|
479
|
-
return guardVersion(params, version, error)
|
|
480
|
-
.asyncMap(async (params) => handler(params, { ok: (okAsync), err: (errAsync) }))
|
|
481
|
-
.andThen(r => r.map(r => enumValue(version, resultOk(r))))
|
|
482
|
-
.orElse(r => ok(enumValue(version, resultErr(r))))
|
|
483
|
-
.unwrapOr(enumValue(version, resultErr(error)));
|
|
484
|
-
});
|
|
271
|
+
return handleV1Request(handleStatementStoreSubmitSlot, () => new GenericError({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
485
272
|
},
|
|
486
273
|
handlePreimageLookupSubscribe(handler) {
|
|
487
|
-
|
|
488
|
-
return handlePreimageLookupSubscribeSlot((params, send, interrupt) => {
|
|
489
|
-
const version = 'v1';
|
|
490
|
-
return guardVersion(params, version, null)
|
|
491
|
-
.map(params => handler(params, payload => send(enumValue(version, payload)), interrupt))
|
|
492
|
-
.orTee(interrupt)
|
|
493
|
-
.unwrapOr(() => {
|
|
494
|
-
/* empty */
|
|
495
|
-
});
|
|
496
|
-
});
|
|
274
|
+
return handleV1Subscription(handlePreimageLookupSubscribeSlot, handler);
|
|
497
275
|
},
|
|
498
276
|
handlePreimageSubmit(handler) {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
});
|
|
277
|
+
return handleV1Request(handlePreimageSubmitSlot, () => new PreimageSubmitErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
278
|
+
},
|
|
279
|
+
handlePaymentBalanceSubscribe(handler) {
|
|
280
|
+
return handleV1Subscription(handlePaymentBalanceSubscribeSlot, handler);
|
|
281
|
+
},
|
|
282
|
+
handlePaymentTopUp(handler) {
|
|
283
|
+
return handleV1Request(handlePaymentTopUpSlot, () => new PaymentTopUpErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
284
|
+
},
|
|
285
|
+
handlePaymentRequest(handler) {
|
|
286
|
+
return handleV1Request(handlePaymentRequestSlot, () => new PaymentRequestErr.Unknown({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR }), handler);
|
|
287
|
+
},
|
|
288
|
+
handlePaymentStatusSubscribe(handler) {
|
|
289
|
+
return handleV1Subscription(handlePaymentStatusSubscribeSlot, handler);
|
|
509
290
|
},
|
|
510
291
|
// chain interaction
|
|
511
292
|
handleChainConnection(factory) {
|
|
@@ -744,7 +525,7 @@ export function createContainer(provider) {
|
|
|
744
525
|
}
|
|
745
526
|
const { genesisHash, transaction } = message.value;
|
|
746
527
|
try {
|
|
747
|
-
const permissionResponse = await handleRemotePermissionSlot.call(enumValue('v1', enumValue('
|
|
528
|
+
const permissionResponse = await handleRemotePermissionSlot.call(enumValue('v1', [enumValue('ChainSubmit', undefined)]));
|
|
748
529
|
const permissionGranted = isEnumVariant(permissionResponse, 'v1') &&
|
|
749
530
|
permissionResponse.value.success === true &&
|
|
750
531
|
permissionResponse.value.value === true;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { createWebviewProvider } from './createWebviewProvider.js';
|
|
2
2
|
export { createIframeProvider } from './createIframeProvider.js';
|
|
3
3
|
export { createContainer } from './createContainer.js';
|
|
4
|
-
export type { Container } from './types.js';
|
|
4
|
+
export type { Container, ContainerHandlerOf } from './types.js';
|
|
5
|
+
export { deriveProductEntropy } from './deriveEntropy.js';
|
|
5
6
|
export { createRateLimiter } from './rateLimiter.js';
|
|
6
7
|
export type { CreateRateLimiterConfig, RateLimiter, RateLimiterConfig, RateLimiterStrategy } from './rateLimiter.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { createWebviewProvider } from './createWebviewProvider.js';
|
|
2
2
|
export { createIframeProvider } from './createIframeProvider.js';
|
|
3
3
|
export { createContainer } from './createContainer.js';
|
|
4
|
+
export { deriveProductEntropy } from './deriveEntropy.js';
|
|
4
5
|
export { createRateLimiter } from './rateLimiter.js';
|
package/dist/rateLimiter.d.ts
CHANGED
package/dist/rateLimiter.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GenericError } from '@novasamatech/host-api';
|
|
2
|
-
|
|
2
|
+
const RATE_LIMITED_MESSAGE = 'Request rate limited';
|
|
3
3
|
function createQueueStrategy(config) {
|
|
4
4
|
const state = {
|
|
5
5
|
remainingTokens: config.maxRequestsPerInterval,
|
|
@@ -25,7 +25,7 @@ function createQueueStrategy(config) {
|
|
|
25
25
|
state.remainingTokens -= 1;
|
|
26
26
|
try {
|
|
27
27
|
const result = task.execute();
|
|
28
|
-
if (result
|
|
28
|
+
if (result instanceof Promise) {
|
|
29
29
|
result.then(task.resolve).catch(task.reject);
|
|
30
30
|
}
|
|
31
31
|
else {
|
|
@@ -51,7 +51,7 @@ function createQueueStrategy(config) {
|
|
|
51
51
|
state.remainingTokens -= 1;
|
|
52
52
|
try {
|
|
53
53
|
const result = execute();
|
|
54
|
-
if (result
|
|
54
|
+
if (result instanceof Promise) {
|
|
55
55
|
return result;
|
|
56
56
|
}
|
|
57
57
|
return Promise.resolve(result);
|
|
@@ -103,7 +103,7 @@ function createDropStrategy(config) {
|
|
|
103
103
|
state.remainingTokens -= 1;
|
|
104
104
|
try {
|
|
105
105
|
const result = execute();
|
|
106
|
-
if (result
|
|
106
|
+
if (result instanceof Promise) {
|
|
107
107
|
return result;
|
|
108
108
|
}
|
|
109
109
|
return Promise.resolve(result);
|
package/dist/types.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Codec, CodecType, ConnectionStatus, HexString, HostApiProtocol, Subscription, VersionedProtocolRequest, VersionedProtocolSubscription } from '@novasamatech/host-api';
|
|
2
2
|
import { CustomRendererNode } from '@novasamatech/host-api';
|
|
3
|
-
import type { JsonRpcProvider } from '@polkadot-api/json-rpc-provider';
|
|
4
3
|
import type { ResultAsync, errAsync } from 'neverthrow';
|
|
5
4
|
import { okAsync } from 'neverthrow';
|
|
5
|
+
import type { JsonRpcProvider } from 'polkadot-api';
|
|
6
6
|
type SuccessResponse<T> = T extends {
|
|
7
7
|
success: true;
|
|
8
8
|
value: infer U;
|
|
@@ -11,23 +11,23 @@ type ErrorResponse<T> = T extends {
|
|
|
11
11
|
success: false;
|
|
12
12
|
value: infer U;
|
|
13
13
|
} ? U : never;
|
|
14
|
-
type
|
|
14
|
+
export type CodecValue<T extends Codec<any> | Codec<never>> = T extends Codec<any> ? CodecType<T> : unknown;
|
|
15
15
|
type OrPromise<T> = T | Promise<T>;
|
|
16
16
|
type ExtractEnumValue<T> = T extends {
|
|
17
17
|
tag: string;
|
|
18
18
|
value: infer V;
|
|
19
19
|
} ? V : never;
|
|
20
|
-
type WithVersion<V extends string, T> = ExtractEnumValue<Extract<T, {
|
|
20
|
+
export type WithVersion<V extends string, T> = ExtractEnumValue<Extract<T, {
|
|
21
21
|
tag: V;
|
|
22
22
|
}>>;
|
|
23
|
-
type UnwrapSuccessResponse<V extends string, T> = T extends {
|
|
23
|
+
export type UnwrapSuccessResponse<V extends string, T> = T extends {
|
|
24
24
|
tag: infer Tag;
|
|
25
25
|
value: infer Value;
|
|
26
26
|
} ? WithVersion<V, {
|
|
27
27
|
tag: Tag;
|
|
28
28
|
value: SuccessResponse<Value>;
|
|
29
29
|
}> : never;
|
|
30
|
-
type UnwrapErrorResponse<V extends string, T> = T extends {
|
|
30
|
+
export type UnwrapErrorResponse<V extends string, T> = T extends {
|
|
31
31
|
tag: infer Tag;
|
|
32
32
|
value: infer Value;
|
|
33
33
|
} ? WithVersion<V, {
|
|
@@ -44,30 +44,38 @@ type UnwrapVersionedResult<V extends string, T> = T extends {
|
|
|
44
44
|
tag: Tag;
|
|
45
45
|
value: ErrorResponse<Value>;
|
|
46
46
|
}>> : never;
|
|
47
|
-
type
|
|
48
|
-
ok: typeof okAsync<UnwrapSuccessResponse<V,
|
|
49
|
-
err: typeof errAsync<never, UnwrapErrorResponse<V,
|
|
50
|
-
}) => OrPromise<UnwrapVersionedResult<V,
|
|
51
|
-
type
|
|
47
|
+
export type ContainerRequestHandler<V extends string, T extends VersionedProtocolRequest> = (params: WithVersion<V, CodecValue<T['request']>>, helpers: {
|
|
48
|
+
ok: typeof okAsync<UnwrapSuccessResponse<V, CodecValue<T['response']>>>;
|
|
49
|
+
err: typeof errAsync<never, UnwrapErrorResponse<V, CodecValue<T['response']>>>;
|
|
50
|
+
}) => OrPromise<UnwrapVersionedResult<V, CodecValue<T['response']>>>;
|
|
51
|
+
type InferRequestHandler<V extends string, T extends VersionedProtocolRequest> = (callback: ContainerRequestHandler<V, T>) => VoidFunction;
|
|
52
|
+
type InferSubscribeHandler<V extends string, T extends VersionedProtocolSubscription> = (callback: (params: WithVersion<V, CodecValue<T['start']>>, send: (payload: WithVersion<V, CodecValue<T['receive']>>) => void, interrupt: VoidFunction) => VoidFunction) => VoidFunction;
|
|
52
53
|
type InferHandler<V extends string, T extends VersionedProtocolRequest | VersionedProtocolSubscription> = T extends VersionedProtocolRequest ? InferRequestHandler<V, T> : T extends VersionedProtocolSubscription ? InferSubscribeHandler<V, T> : never;
|
|
54
|
+
export type ContainerHandlerOf<T extends (...args: any[]) => any> = Parameters<T>[0];
|
|
53
55
|
export type Container = {
|
|
54
56
|
handleFeatureSupported: InferHandler<'v1', HostApiProtocol['host_feature_supported']>;
|
|
55
57
|
handleDevicePermission: InferHandler<'v1', HostApiProtocol['host_device_permission']>;
|
|
56
58
|
handlePermission: InferHandler<'v1', HostApiProtocol['remote_permission']>;
|
|
57
59
|
handlePushNotification: InferHandler<'v1', HostApiProtocol['host_push_notification']>;
|
|
58
60
|
handleNavigateTo: InferHandler<'v1', HostApiProtocol['host_navigate_to']>;
|
|
61
|
+
handleDeriveEntropy: InferHandler<'v1', HostApiProtocol['host_derive_entropy']>;
|
|
59
62
|
handleLocalStorageRead: InferHandler<'v1', HostApiProtocol['host_local_storage_read']>;
|
|
60
63
|
handleLocalStorageWrite: InferHandler<'v1', HostApiProtocol['host_local_storage_write']>;
|
|
61
64
|
handleLocalStorageClear: InferHandler<'v1', HostApiProtocol['host_local_storage_clear']>;
|
|
65
|
+
handleAccountGetRoot: InferHandler<'v1', HostApiProtocol['host_account_get_root']>;
|
|
66
|
+
handleRequestLogin: InferHandler<'v1', HostApiProtocol['host_request_login']>;
|
|
62
67
|
handleAccountConnectionStatusSubscribe: InferHandler<'v1', HostApiProtocol['host_account_connection_status_subscribe']>;
|
|
68
|
+
handleThemeSubscribe: InferHandler<'v1', HostApiProtocol['host_theme_subscribe']>;
|
|
63
69
|
handleAccountGet: InferHandler<'v1', HostApiProtocol['host_account_get']>;
|
|
64
70
|
handleAccountGetAlias: InferHandler<'v1', HostApiProtocol['host_account_get_alias']>;
|
|
65
71
|
handleAccountCreateProof: InferHandler<'v1', HostApiProtocol['host_account_create_proof']>;
|
|
66
|
-
|
|
72
|
+
handleGetLegacyAccounts: InferHandler<'v1', HostApiProtocol['host_get_legacy_accounts']>;
|
|
67
73
|
handleCreateTransaction: InferHandler<'v1', HostApiProtocol['host_create_transaction']>;
|
|
68
|
-
|
|
74
|
+
handleCreateTransactionWithLegacyAccount: InferHandler<'v1', HostApiProtocol['host_create_transaction_with_legacy_account']>;
|
|
69
75
|
handleSignRaw: InferHandler<'v1', HostApiProtocol['host_sign_raw']>;
|
|
70
76
|
handleSignPayload: InferHandler<'v1', HostApiProtocol['host_sign_payload']>;
|
|
77
|
+
handleSignRawWithLegacyAccount: InferHandler<'v1', HostApiProtocol['host_sign_raw_with_legacy_account']>;
|
|
78
|
+
handleSignPayloadWithLegacyAccount: InferHandler<'v1', HostApiProtocol['host_sign_payload_with_legacy_account']>;
|
|
71
79
|
handleChatCreateRoom: InferHandler<'v1', HostApiProtocol['host_chat_create_room']>;
|
|
72
80
|
handleChatBotRegistration: InferHandler<'v1', HostApiProtocol['host_chat_register_bot']>;
|
|
73
81
|
handleChatListSubscribe: InferHandler<'v1', HostApiProtocol['host_chat_list_subscribe']>;
|
|
@@ -83,6 +91,10 @@ export type Container = {
|
|
|
83
91
|
handleStatementStoreSubmit: InferHandler<'v1', HostApiProtocol['remote_statement_store_submit']>;
|
|
84
92
|
handlePreimageLookupSubscribe: InferHandler<'v1', HostApiProtocol['remote_preimage_lookup_subscribe']>;
|
|
85
93
|
handlePreimageSubmit: InferHandler<'v1', HostApiProtocol['remote_preimage_submit']>;
|
|
94
|
+
handlePaymentBalanceSubscribe: InferHandler<'v1', HostApiProtocol['host_payment_balance_subscribe']>;
|
|
95
|
+
handlePaymentTopUp: InferHandler<'v1', HostApiProtocol['host_payment_top_up']>;
|
|
96
|
+
handlePaymentRequest: InferHandler<'v1', HostApiProtocol['host_payment_request']>;
|
|
97
|
+
handlePaymentStatusSubscribe: InferHandler<'v1', HostApiProtocol['host_payment_status_subscribe']>;
|
|
86
98
|
handleChainConnection: (factory: (genesisHash: HexString) => JsonRpcProvider | null) => VoidFunction;
|
|
87
99
|
isReady(): Promise<boolean>;
|
|
88
100
|
dispose(): void;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@novasamatech/host-container",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.0-1",
|
|
5
5
|
"description": "Host container for hosting and managing products within the Polkadot ecosystem.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"repository": {
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
"README.md"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@
|
|
29
|
-
"
|
|
30
|
-
"@novasamatech/host-api": "0.
|
|
31
|
-
"nanoid": "5.1.
|
|
28
|
+
"@noble/hashes": "2.2.0",
|
|
29
|
+
"polkadot-api": ">=2",
|
|
30
|
+
"@novasamatech/host-api": "0.7.0-1",
|
|
31
|
+
"nanoid": "5.1.9"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"electron": "^41.
|
|
34
|
+
"electron": "^41.2.0"
|
|
35
35
|
},
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public"
|