@novasamatech/host-api 0.5.0-9 → 0.5.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/README.md +103 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/helpers.d.ts +33 -0
- package/dist/helpers.js +46 -0
- package/dist/hostApi.d.ts +31 -0
- package/dist/hostApi.js +345 -0
- package/dist/index.d.ts +18 -7
- package/dist/index.js +14 -6
- package/dist/protocol/commonCodecs.d.ts +42 -0
- package/dist/protocol/commonCodecs.js +64 -0
- package/dist/protocol/commonCodecs.spec.d.ts +1 -0
- package/dist/protocol/commonCodecs.spec.js +72 -0
- package/dist/protocol/impl.d.ts +93 -0
- package/dist/protocol/impl.js +97 -0
- package/dist/protocol/messageCodec.d.ts +1245 -0
- package/dist/protocol/messageCodec.js +24 -0
- package/dist/protocol/types.d.ts +1 -0
- package/dist/protocol/types.js +1 -0
- package/dist/protocol/v1/accounts.d.ts +265 -0
- package/dist/protocol/v1/accounts.js +51 -0
- package/dist/protocol/v1/chat.d.ts +341 -0
- package/dist/protocol/v1/chat.js +71 -0
- package/dist/protocol/v1/createTransaction.d.ts +238 -0
- package/dist/protocol/v1/createTransaction.js +58 -0
- package/dist/protocol/v1/feature.d.ts +15 -0
- package/dist/protocol/v1/feature.js +7 -0
- package/dist/protocol/v1/handshake.d.ts +85 -0
- package/dist/protocol/v1/handshake.js +12 -0
- package/dist/protocol/v1/jsonRpc.d.ts +10 -0
- package/dist/protocol/v1/jsonRpc.js +6 -0
- package/dist/protocol/v1/permission.d.ts +90 -0
- package/dist/protocol/v1/permission.js +18 -0
- package/dist/protocol/v1/sign.d.ts +152 -0
- package/dist/protocol/v1/sign.js +43 -0
- package/dist/protocol/v1/statementStore.d.ts +175 -0
- package/dist/protocol/v1/statementStore.js +47 -0
- package/dist/protocol/v1/storage.d.ts +87 -0
- package/dist/protocol/v1/storage.js +16 -0
- package/dist/provider.d.ts +8 -0
- package/dist/provider.js +1 -0
- package/dist/transport.d.ts +3 -0
- package/dist/transport.js +248 -0
- package/dist/types.d.ts +15 -15
- package/package.json +2 -4
- package/dist/commonEncoders.d.ts +0 -9
- package/dist/commonEncoders.js +0 -14
- package/dist/createTransport.d.ts +0 -6
- package/dist/createTransport.js +0 -183
- package/dist/createTransportEncoder.d.ts +0 -7
- package/dist/createTransportEncoder.js +0 -5
- package/dist/interactions/accounts.d.ts +0 -12
- package/dist/interactions/accounts.js +0 -39
- package/dist/interactions/features.d.ts +0 -13
- package/dist/interactions/features.js +0 -13
- package/dist/interactions/handshake.d.ts +0 -2
- package/dist/interactions/handshake.js +0 -3
- package/dist/interactions/papiProvider.d.ts +0 -8
- package/dist/interactions/papiProvider.js +0 -9
- package/dist/interactions/sign.d.ts +0 -101
- package/dist/interactions/sign.js +0 -169
- package/dist/messageEncoder.d.ts +0 -217
- package/dist/messageEncoder.js +0 -37
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { createNanoEvents } from 'nanoevents';
|
|
2
|
+
import { HANDSHAKE_INTERVAL, HANDSHAKE_TIMEOUT, JAM_CODEC_PROTOCOL_ID } from './constants.js';
|
|
3
|
+
import { composeAction, createRequestId, delay, enumValue, errResult, isEnumVariant, okResult, promiseWithResolvers, } from './helpers.js';
|
|
4
|
+
import { Message } from './protocol/messageCodec.js';
|
|
5
|
+
import { HandshakeErr } from './protocol/v1/handshake.js';
|
|
6
|
+
const isConnected = (status) => status === 'connected';
|
|
7
|
+
export function createTransport(provider) {
|
|
8
|
+
let codecVersion = JAM_CODEC_PROTOCOL_ID;
|
|
9
|
+
const handshakeAbortController = new AbortController();
|
|
10
|
+
let handshakePromise = null;
|
|
11
|
+
let connectionStatusResolved = false;
|
|
12
|
+
let connectionStatus = 'disconnected';
|
|
13
|
+
let disposed = false;
|
|
14
|
+
const events = createNanoEvents();
|
|
15
|
+
events.on('connectionStatus', value => {
|
|
16
|
+
connectionStatus = value;
|
|
17
|
+
});
|
|
18
|
+
function changeConnectionStatus(status) {
|
|
19
|
+
events.emit('connectionStatus', status);
|
|
20
|
+
}
|
|
21
|
+
function throwIfDisposed() {
|
|
22
|
+
if (disposed) {
|
|
23
|
+
throw new Error('Transport is disposed');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function throwIfIncorrectEnvironment() {
|
|
27
|
+
if (!provider.isCorrectEnvironment()) {
|
|
28
|
+
throw new Error('Environment is not correct');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function throwIfInvalidCodecVersion() {
|
|
32
|
+
if (codecVersion !== JAM_CODEC_PROTOCOL_ID) {
|
|
33
|
+
throw new Error(`Unsupported codec version: ${codecVersion}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function checks() {
|
|
37
|
+
throwIfDisposed();
|
|
38
|
+
throwIfIncorrectEnvironment();
|
|
39
|
+
throwIfInvalidCodecVersion();
|
|
40
|
+
}
|
|
41
|
+
const transport = {
|
|
42
|
+
provider,
|
|
43
|
+
isCorrectEnvironment() {
|
|
44
|
+
return provider.isCorrectEnvironment();
|
|
45
|
+
},
|
|
46
|
+
isReady() {
|
|
47
|
+
checks();
|
|
48
|
+
if (connectionStatusResolved) {
|
|
49
|
+
return Promise.resolve(isConnected(connectionStatus));
|
|
50
|
+
}
|
|
51
|
+
if (handshakePromise) {
|
|
52
|
+
return handshakePromise;
|
|
53
|
+
}
|
|
54
|
+
changeConnectionStatus('connecting');
|
|
55
|
+
const performHandshake = () => {
|
|
56
|
+
const id = createRequestId();
|
|
57
|
+
let resolved = false;
|
|
58
|
+
const cleanup = (interval, unsubscribe) => {
|
|
59
|
+
clearInterval(interval);
|
|
60
|
+
unsubscribe();
|
|
61
|
+
handshakeAbortController.signal.removeEventListener('abort', unsubscribe);
|
|
62
|
+
};
|
|
63
|
+
return new Promise(resolve => {
|
|
64
|
+
const unsubscribe = transport.listenMessages('handshake_response', responseId => {
|
|
65
|
+
if (responseId === id) {
|
|
66
|
+
cleanup(interval, unsubscribe);
|
|
67
|
+
resolved = true;
|
|
68
|
+
resolve(true);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
handshakeAbortController.signal.addEventListener('abort', unsubscribe, { once: true });
|
|
72
|
+
const interval = setInterval(() => {
|
|
73
|
+
if (handshakeAbortController.signal.aborted) {
|
|
74
|
+
clearInterval(interval);
|
|
75
|
+
resolve(false);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
transport.postMessage(id, enumValue('handshake_request', enumValue('v1', codecVersion)));
|
|
79
|
+
}, HANDSHAKE_INTERVAL);
|
|
80
|
+
}).then(success => {
|
|
81
|
+
if (!success && !resolved) {
|
|
82
|
+
handshakeAbortController.abort('Timeout');
|
|
83
|
+
}
|
|
84
|
+
return success;
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
const timedOutRequest = Promise.race([performHandshake(), delay(HANDSHAKE_TIMEOUT).then(() => false)]);
|
|
88
|
+
handshakePromise = timedOutRequest.then(result => {
|
|
89
|
+
handshakePromise = null;
|
|
90
|
+
connectionStatusResolved = true;
|
|
91
|
+
changeConnectionStatus(result ? 'connected' : 'disconnected');
|
|
92
|
+
return result;
|
|
93
|
+
});
|
|
94
|
+
return handshakePromise;
|
|
95
|
+
},
|
|
96
|
+
async request(method, payload, signal) {
|
|
97
|
+
checks();
|
|
98
|
+
if (!(await transport.isReady())) {
|
|
99
|
+
throw new Error('Polkadot host is not ready');
|
|
100
|
+
}
|
|
101
|
+
signal?.throwIfAborted();
|
|
102
|
+
const requestId = createRequestId();
|
|
103
|
+
const requestAction = composeAction(method, 'request');
|
|
104
|
+
const responseAction = composeAction(method, 'response');
|
|
105
|
+
const { resolve, reject, promise } = promiseWithResolvers();
|
|
106
|
+
const cleanup = () => {
|
|
107
|
+
unsubscribe();
|
|
108
|
+
signal?.removeEventListener('abort', onAbort);
|
|
109
|
+
};
|
|
110
|
+
const onAbort = () => {
|
|
111
|
+
cleanup();
|
|
112
|
+
reject(signal?.reason ?? new Error('Request aborted'));
|
|
113
|
+
};
|
|
114
|
+
const unsubscribe = transport.listenMessages(responseAction, (receivedId, payload) => {
|
|
115
|
+
if (receivedId === requestId) {
|
|
116
|
+
cleanup();
|
|
117
|
+
resolve(payload.value);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
121
|
+
const requestMessage = enumValue(requestAction, payload);
|
|
122
|
+
transport.postMessage(requestId, requestMessage);
|
|
123
|
+
return promise;
|
|
124
|
+
},
|
|
125
|
+
handleRequest(method, handler) {
|
|
126
|
+
checks();
|
|
127
|
+
const requestAction = composeAction(method, 'request');
|
|
128
|
+
const responseAction = composeAction(method, 'response');
|
|
129
|
+
return transport.listenMessages(requestAction, (requestId, payload) => {
|
|
130
|
+
handler(payload.value).then(result => {
|
|
131
|
+
const responseMessage = enumValue(responseAction, result);
|
|
132
|
+
transport.postMessage(requestId, responseMessage);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
},
|
|
136
|
+
subscribe(method, payload, callback) {
|
|
137
|
+
checks();
|
|
138
|
+
const events = createNanoEvents();
|
|
139
|
+
const requestId = createRequestId();
|
|
140
|
+
const startAction = composeAction(method, 'start');
|
|
141
|
+
const stopAction = composeAction(method, 'stop');
|
|
142
|
+
const interruptAction = composeAction(method, 'interrupt');
|
|
143
|
+
const receiveAction = composeAction(method, 'receive');
|
|
144
|
+
const unsubscribeReceive = transport.listenMessages(receiveAction, (receivedId, data) => {
|
|
145
|
+
if (receivedId === requestId) {
|
|
146
|
+
callback(data.value);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
const unsubscribeInterrupt = transport.listenMessages(interruptAction, receivedId => {
|
|
150
|
+
if (receivedId === requestId) {
|
|
151
|
+
events.emit('interrupt');
|
|
152
|
+
stopSubscription();
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
const stopSubscription = () => {
|
|
156
|
+
unsubscribeReceive();
|
|
157
|
+
unsubscribeInterrupt();
|
|
158
|
+
events.events = {};
|
|
159
|
+
};
|
|
160
|
+
const startPayload = enumValue(startAction, payload);
|
|
161
|
+
transport.postMessage(requestId, startPayload);
|
|
162
|
+
return {
|
|
163
|
+
unsubscribe() {
|
|
164
|
+
stopSubscription();
|
|
165
|
+
const stopPayload = enumValue(stopAction, undefined);
|
|
166
|
+
transport.postMessage(requestId, stopPayload);
|
|
167
|
+
},
|
|
168
|
+
onInterrupt(callback) {
|
|
169
|
+
return events.on('interrupt', callback);
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
handleSubscription(method, handler) {
|
|
174
|
+
checks();
|
|
175
|
+
const startAction = composeAction(method, 'start');
|
|
176
|
+
const stopAction = composeAction(method, 'stop');
|
|
177
|
+
const interruptAction = composeAction(method, 'interrupt');
|
|
178
|
+
const receiveAction = composeAction(method, 'receive');
|
|
179
|
+
const subscriptions = new Map();
|
|
180
|
+
const unsubStart = transport.listenMessages(startAction, (requestId, payload) => {
|
|
181
|
+
if (subscriptions.has(requestId))
|
|
182
|
+
return;
|
|
183
|
+
const unsubscribe = handler(payload.value, value => {
|
|
184
|
+
const receivePayload = enumValue(receiveAction, value);
|
|
185
|
+
transport.postMessage(requestId, receivePayload);
|
|
186
|
+
}, () => {
|
|
187
|
+
transport.postMessage(requestId, enumValue(interruptAction, undefined));
|
|
188
|
+
});
|
|
189
|
+
subscriptions.set(requestId, unsubscribe);
|
|
190
|
+
});
|
|
191
|
+
const unsubStop = transport.listenMessages(stopAction, requestId => {
|
|
192
|
+
subscriptions.get(requestId)?.();
|
|
193
|
+
});
|
|
194
|
+
return () => {
|
|
195
|
+
subscriptions.forEach(unsub => unsub());
|
|
196
|
+
unsubStart();
|
|
197
|
+
unsubStop();
|
|
198
|
+
};
|
|
199
|
+
},
|
|
200
|
+
postMessage(requestId, payload) {
|
|
201
|
+
checks();
|
|
202
|
+
const encoded = Message.enc({ requestId, payload });
|
|
203
|
+
provider.postMessage(encoded);
|
|
204
|
+
},
|
|
205
|
+
listenMessages(action, callback, onError) {
|
|
206
|
+
return provider.subscribe(message => {
|
|
207
|
+
try {
|
|
208
|
+
const result = Message.dec(message);
|
|
209
|
+
if (isEnumVariant(result.payload, action)) {
|
|
210
|
+
callback(result.requestId, result.payload);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (e) {
|
|
214
|
+
onError?.(e);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
},
|
|
218
|
+
onConnectionStatusChange(callback) {
|
|
219
|
+
callback(connectionStatus);
|
|
220
|
+
return events.on('connectionStatus', callback);
|
|
221
|
+
},
|
|
222
|
+
dispose() {
|
|
223
|
+
disposed = true;
|
|
224
|
+
provider.dispose();
|
|
225
|
+
changeConnectionStatus('disconnected');
|
|
226
|
+
events.events = {};
|
|
227
|
+
handshakeAbortController.abort('Transport disposed');
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
if (provider.isCorrectEnvironment()) {
|
|
231
|
+
transport.handleRequest('handshake', async (version) => {
|
|
232
|
+
switch (version.tag) {
|
|
233
|
+
case 'v1': {
|
|
234
|
+
codecVersion = version.value;
|
|
235
|
+
switch (version.value) {
|
|
236
|
+
case JAM_CODEC_PROTOCOL_ID:
|
|
237
|
+
return enumValue(version.tag, okResult(undefined));
|
|
238
|
+
default:
|
|
239
|
+
return enumValue(version.tag, errResult(new HandshakeErr.UnsupportedProtocolVersion(undefined)));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
default:
|
|
243
|
+
return enumValue(version.tag, errResult(new HandshakeErr.UnsupportedProtocolVersion(undefined)));
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
return transport;
|
|
248
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { ComposeMessageAction, MessageAction, MessagePayloadSchema, PickMessagePayload, PickMessagePayloadValue } from './protocol/messageCodec.js';
|
|
2
|
+
import type { Provider } from './provider.js';
|
|
3
3
|
export type Logger = Record<'info' | 'warn' | 'error' | 'log', (...args: unknown[]) => void>;
|
|
4
|
-
export type TransportProvider = {
|
|
5
|
-
logger: Logger;
|
|
6
|
-
isCorrectEnvironment(): boolean;
|
|
7
|
-
postMessage(message: Uint8Array): void;
|
|
8
|
-
subscribe(callback: (message: Uint8Array) => void): () => void;
|
|
9
|
-
dispose(): void;
|
|
10
|
-
};
|
|
11
4
|
export type ConnectionStatus = 'connecting' | 'connected' | 'disconnected';
|
|
5
|
+
export type RequestHandler<Method extends string> = (message: PickMessagePayloadValue<ComposeMessageAction<Method, 'request'>>) => PromiseLike<PickMessagePayloadValue<ComposeMessageAction<Method, 'response'>>>;
|
|
6
|
+
export type SubscriptionHandler<Method extends string> = (params: PickMessagePayloadValue<ComposeMessageAction<Method, 'start'>>, send: (value: PickMessagePayloadValue<ComposeMessageAction<Method, 'receive'>>) => void, interrupt: () => void) => VoidFunction;
|
|
7
|
+
export type Subscription = {
|
|
8
|
+
unsubscribe: VoidFunction;
|
|
9
|
+
onInterrupt(callback: VoidFunction): VoidFunction;
|
|
10
|
+
};
|
|
12
11
|
export type Transport = {
|
|
13
|
-
readonly provider:
|
|
12
|
+
readonly provider: Provider;
|
|
14
13
|
isCorrectEnvironment(): boolean;
|
|
15
14
|
isReady(): Promise<boolean>;
|
|
16
|
-
subscribeAny(callback: (id: string, payload: MessagePayloadSchema) => void): VoidFunction;
|
|
17
|
-
subscribe<const Type extends MessageType>(type: Type, callback: (id: string, payload: PickMessagePayloadValue<Type>) => void): VoidFunction;
|
|
18
|
-
postMessage(id: string, payload: MessagePayloadSchema): string;
|
|
19
|
-
request<Response extends MessageType>(payload: MessagePayloadSchema, response: Response, abortSignal?: AbortSignal): Promise<PickMessagePayloadValue<Response>>;
|
|
20
|
-
handleMessage<Request extends MessageType, Response extends MessageType>(type: Request, handler: (message: PickMessagePayloadValue<Request>) => Promise<PickMessagePayload<Response> | void>): VoidFunction;
|
|
21
15
|
onConnectionStatusChange(callback: (status: ConnectionStatus) => void): VoidFunction;
|
|
22
16
|
dispose(): void;
|
|
17
|
+
request<const Method extends string>(method: Method, payload: PickMessagePayloadValue<ComposeMessageAction<Method, 'request'>>, signal?: AbortSignal): Promise<PickMessagePayloadValue<ComposeMessageAction<Method, 'response'>>>;
|
|
18
|
+
handleRequest<const Method extends string>(method: Method, handler: RequestHandler<Method>): VoidFunction;
|
|
19
|
+
subscribe<const Method extends string>(method: Method, payload: PickMessagePayloadValue<ComposeMessageAction<Method, 'start'>>, callback: (payload: PickMessagePayloadValue<ComposeMessageAction<Method, 'receive'>>) => void): Subscription;
|
|
20
|
+
handleSubscription<const Method extends string>(method: Method, handler: SubscriptionHandler<Method>): VoidFunction;
|
|
21
|
+
postMessage(requestId: string, payload: MessagePayloadSchema): void;
|
|
22
|
+
listenMessages<const Action extends MessageAction>(action: Action, callback: (requestId: string, data: PickMessagePayload<Action>) => void, onError?: (error: unknown) => void): VoidFunction;
|
|
23
23
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@novasamatech/host-api",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.5.0
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"description": "Host API: transport implementation for host - product integration.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"repository": {
|
|
@@ -24,11 +24,9 @@
|
|
|
24
24
|
"@polkadot-api/utils": "^0.2.0",
|
|
25
25
|
"nanoevents": "9.1.0",
|
|
26
26
|
"nanoid": "5.1.6",
|
|
27
|
+
"neverthrow": "^8.2.0",
|
|
27
28
|
"scale-ts": "1.6.1"
|
|
28
29
|
},
|
|
29
|
-
"peerDependencies": {
|
|
30
|
-
"@polkadot-api/pjs-signer": "^0.6.17"
|
|
31
|
-
},
|
|
32
30
|
"publishConfig": {
|
|
33
31
|
"access": "public"
|
|
34
32
|
}
|
package/dist/commonEncoders.d.ts
DELETED
package/dist/commonEncoders.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { fromHex, toHex } from '@polkadot-api/utils';
|
|
2
|
-
import { Bytes, Enum, str } from 'scale-ts';
|
|
3
|
-
import { createTransportEncoder } from './createTransportEncoder.js';
|
|
4
|
-
export const hexEncoder = createTransportEncoder({
|
|
5
|
-
codec: Bytes(),
|
|
6
|
-
from: v => toHex(v),
|
|
7
|
-
to: fromHex,
|
|
8
|
-
});
|
|
9
|
-
export function responseEncoder(codec) {
|
|
10
|
-
return Enum({
|
|
11
|
-
success: codec,
|
|
12
|
-
error: str,
|
|
13
|
-
});
|
|
14
|
-
}
|
package/dist/createTransport.js
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import { createNanoEvents } from 'nanoevents';
|
|
2
|
-
import { nanoid } from 'nanoid';
|
|
3
|
-
import { HANDSHAKE_INTERVAL } from './constants.js';
|
|
4
|
-
import { delay, promiseWithResolvers } from './helpers.js';
|
|
5
|
-
import { messageEncoder } from './messageEncoder.js';
|
|
6
|
-
export function createTransport(provider, params) {
|
|
7
|
-
const handshakeTimeout = params?.handshakeTimeout ?? Number.POSITIVE_INFINITY;
|
|
8
|
-
const handshakeAbortController = new AbortController();
|
|
9
|
-
let handshakePromise = null;
|
|
10
|
-
let connectionStatusResolved = false;
|
|
11
|
-
let connectionStatus = 'disconnected';
|
|
12
|
-
let disposed = false;
|
|
13
|
-
const events = createNanoEvents();
|
|
14
|
-
events.on('connectionStatus', value => {
|
|
15
|
-
connectionStatus = value;
|
|
16
|
-
});
|
|
17
|
-
function changeConnectionStatus(status) {
|
|
18
|
-
events.emit('connectionStatus', status);
|
|
19
|
-
}
|
|
20
|
-
function throwIfDisposed() {
|
|
21
|
-
if (disposed) {
|
|
22
|
-
throw new Error('Transport is disposed');
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
function throwIfIncorrectEnvironment() {
|
|
26
|
-
if (!provider.isCorrectEnvironment()) {
|
|
27
|
-
throw new Error('Environment is not correct');
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
function connectionStatusToBoolean(connectionStatus) {
|
|
31
|
-
switch (connectionStatus) {
|
|
32
|
-
case 'disconnected':
|
|
33
|
-
case 'connecting':
|
|
34
|
-
return false;
|
|
35
|
-
case 'connected':
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
const transportInstance = {
|
|
40
|
-
provider,
|
|
41
|
-
isCorrectEnvironment() {
|
|
42
|
-
return provider.isCorrectEnvironment();
|
|
43
|
-
},
|
|
44
|
-
isReady() {
|
|
45
|
-
throwIfIncorrectEnvironment();
|
|
46
|
-
throwIfDisposed();
|
|
47
|
-
if (connectionStatusResolved) {
|
|
48
|
-
return Promise.resolve(connectionStatusToBoolean(connectionStatus));
|
|
49
|
-
}
|
|
50
|
-
if (handshakePromise) {
|
|
51
|
-
return handshakePromise;
|
|
52
|
-
}
|
|
53
|
-
changeConnectionStatus('connecting');
|
|
54
|
-
let resolved = false;
|
|
55
|
-
const request = new Promise(resolve => {
|
|
56
|
-
const id = nanoid();
|
|
57
|
-
const unsubscribe = transportInstance.subscribe('handshakeResponseV1', responseId => {
|
|
58
|
-
if (responseId !== id)
|
|
59
|
-
return;
|
|
60
|
-
clearInterval(interval);
|
|
61
|
-
unsubscribe();
|
|
62
|
-
handshakeAbortController.signal.removeEventListener('abort', unsubscribe);
|
|
63
|
-
resolved = true;
|
|
64
|
-
resolve(true);
|
|
65
|
-
});
|
|
66
|
-
handshakeAbortController.signal.addEventListener('abort', unsubscribe, { once: true });
|
|
67
|
-
const interval = setInterval(() => {
|
|
68
|
-
if (handshakeAbortController.signal.aborted) {
|
|
69
|
-
clearInterval(interval);
|
|
70
|
-
resolve(false);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
transportInstance.postMessage(id, { tag: 'handshakeRequestV1', value: undefined });
|
|
74
|
-
}, HANDSHAKE_INTERVAL);
|
|
75
|
-
});
|
|
76
|
-
const promise = handshakeTimeout === Number.POSITIVE_INFINITY
|
|
77
|
-
? request
|
|
78
|
-
: Promise.race([
|
|
79
|
-
request,
|
|
80
|
-
delay(handshakeTimeout).then(() => {
|
|
81
|
-
if (!resolved) {
|
|
82
|
-
handshakeAbortController.abort('Timeout');
|
|
83
|
-
}
|
|
84
|
-
return false;
|
|
85
|
-
}),
|
|
86
|
-
]);
|
|
87
|
-
handshakePromise = promise.then(result => {
|
|
88
|
-
handshakePromise = null;
|
|
89
|
-
connectionStatusResolved = true;
|
|
90
|
-
changeConnectionStatus(result ? 'connected' : 'disconnected');
|
|
91
|
-
return result;
|
|
92
|
-
});
|
|
93
|
-
return handshakePromise;
|
|
94
|
-
},
|
|
95
|
-
subscribeAny(callback) {
|
|
96
|
-
throwIfIncorrectEnvironment();
|
|
97
|
-
throwIfDisposed();
|
|
98
|
-
return provider.subscribe(message => {
|
|
99
|
-
let result;
|
|
100
|
-
try {
|
|
101
|
-
result = messageEncoder.dec(message);
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
callback(result.id, result.payload);
|
|
107
|
-
});
|
|
108
|
-
},
|
|
109
|
-
subscribe(type, callback) {
|
|
110
|
-
throwIfIncorrectEnvironment();
|
|
111
|
-
throwIfDisposed();
|
|
112
|
-
return transportInstance.subscribeAny((id, message) => {
|
|
113
|
-
if (message.tag == type) {
|
|
114
|
-
callback(id, message.value);
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
},
|
|
118
|
-
postMessage(id, payload) {
|
|
119
|
-
throwIfIncorrectEnvironment();
|
|
120
|
-
throwIfDisposed();
|
|
121
|
-
const encoded = messageEncoder.enc({ id, payload });
|
|
122
|
-
provider.postMessage(encoded);
|
|
123
|
-
return id;
|
|
124
|
-
},
|
|
125
|
-
async request(payload, response, abortSignal) {
|
|
126
|
-
throwIfIncorrectEnvironment();
|
|
127
|
-
throwIfDisposed();
|
|
128
|
-
const ready = await transportInstance.isReady();
|
|
129
|
-
if (!ready) {
|
|
130
|
-
throw new Error('Polkadot host is not ready');
|
|
131
|
-
}
|
|
132
|
-
abortSignal?.throwIfAborted();
|
|
133
|
-
const requestId = nanoid();
|
|
134
|
-
const { resolve, reject, promise } = promiseWithResolvers();
|
|
135
|
-
const unsubscribe = transportInstance.subscribe(response, (receivedId, payload) => {
|
|
136
|
-
if (receivedId === requestId) {
|
|
137
|
-
abortSignal?.removeEventListener('abort', stop);
|
|
138
|
-
unsubscribe();
|
|
139
|
-
resolve(payload);
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
const stop = () => {
|
|
143
|
-
unsubscribe();
|
|
144
|
-
reject(abortSignal?.reason ?? new Error('Request aborted'));
|
|
145
|
-
};
|
|
146
|
-
abortSignal?.addEventListener('abort', stop, { once: true });
|
|
147
|
-
transportInstance.postMessage(requestId, payload);
|
|
148
|
-
return promise;
|
|
149
|
-
},
|
|
150
|
-
handleMessage(type, handler) {
|
|
151
|
-
throwIfIncorrectEnvironment();
|
|
152
|
-
throwIfDisposed();
|
|
153
|
-
return transportInstance.subscribe(type, (id, payload) => {
|
|
154
|
-
handler(payload).then(result => {
|
|
155
|
-
if (!result)
|
|
156
|
-
return;
|
|
157
|
-
transportInstance.postMessage(id, result);
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
},
|
|
161
|
-
onConnectionStatusChange(callback) {
|
|
162
|
-
callback(connectionStatus);
|
|
163
|
-
return events.on('connectionStatus', callback);
|
|
164
|
-
},
|
|
165
|
-
dispose() {
|
|
166
|
-
disposed = true;
|
|
167
|
-
provider.dispose();
|
|
168
|
-
changeConnectionStatus('disconnected');
|
|
169
|
-
events.events = {};
|
|
170
|
-
handshakeAbortController.abort('Transport disposed');
|
|
171
|
-
},
|
|
172
|
-
};
|
|
173
|
-
if (provider.isCorrectEnvironment()) {
|
|
174
|
-
transportInstance.handleMessage('handshakeRequestV1', async () => ({
|
|
175
|
-
tag: 'handshakeResponseV1',
|
|
176
|
-
value: {
|
|
177
|
-
tag: 'success',
|
|
178
|
-
value: undefined,
|
|
179
|
-
},
|
|
180
|
-
}));
|
|
181
|
-
}
|
|
182
|
-
return transportInstance;
|
|
183
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Codec, CodecType } from 'scale-ts';
|
|
2
|
-
export type TransportEncoder<Public, Transported extends Codec<any>> = {
|
|
3
|
-
codec: Transported;
|
|
4
|
-
from: (decoded: CodecType<Transported>) => Public;
|
|
5
|
-
to: (value: Public) => CodecType<Transported>;
|
|
6
|
-
};
|
|
7
|
-
export declare function createTransportEncoder<Public, Transported extends Codec<any>>(encoder: TransportEncoder<Public, Transported>): Codec<Public>;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { InjectedAccount } from '@polkadot-api/pjs-signer';
|
|
2
|
-
import type { Codec, CodecType } from 'scale-ts';
|
|
3
|
-
/**
|
|
4
|
-
* @see {import('@polkadot/extension-inject/types').InjectedAccount}
|
|
5
|
-
*/
|
|
6
|
-
export type InjectedAccountSchema = CodecType<typeof injectedAccountEncoder>;
|
|
7
|
-
declare const injectedAccountEncoder: Codec<InjectedAccount>;
|
|
8
|
-
export declare const getAccountsRequestV1Encoder: Codec<undefined>;
|
|
9
|
-
export declare const getAccountsResponseV1Encoder: Codec<InjectedAccount[]>;
|
|
10
|
-
export declare const accountSubscriptionV1Encoder: Codec<undefined>;
|
|
11
|
-
export declare const accountUnsubscriptionV1Encoder: Codec<undefined>;
|
|
12
|
-
export {};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { Enum, Option, Struct, Vector, _void, str } from 'scale-ts';
|
|
2
|
-
import { createTransportEncoder } from '../createTransportEncoder.js';
|
|
3
|
-
const keypairCodec = Enum({
|
|
4
|
-
ed25519: _void,
|
|
5
|
-
sr25519: _void,
|
|
6
|
-
ecdsa: _void,
|
|
7
|
-
});
|
|
8
|
-
const keypairEncoder = createTransportEncoder({
|
|
9
|
-
codec: keypairCodec,
|
|
10
|
-
from: v => v.tag,
|
|
11
|
-
to: keypair => ({
|
|
12
|
-
tag: keypair,
|
|
13
|
-
value: undefined,
|
|
14
|
-
}),
|
|
15
|
-
});
|
|
16
|
-
const injectedAccountCodec = Struct({
|
|
17
|
-
address: str,
|
|
18
|
-
genesisHash: Option(str),
|
|
19
|
-
name: Option(str),
|
|
20
|
-
type: Option(keypairEncoder),
|
|
21
|
-
});
|
|
22
|
-
const injectedAccountEncoder = createTransportEncoder({
|
|
23
|
-
codec: injectedAccountCodec,
|
|
24
|
-
from(decoded) {
|
|
25
|
-
return decoded;
|
|
26
|
-
},
|
|
27
|
-
to(value) {
|
|
28
|
-
return {
|
|
29
|
-
address: value.address,
|
|
30
|
-
genesisHash: value.genesisHash ? value.genesisHash : undefined,
|
|
31
|
-
name: value.name,
|
|
32
|
-
type: value.type,
|
|
33
|
-
};
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
export const getAccountsRequestV1Encoder = _void;
|
|
37
|
-
export const getAccountsResponseV1Encoder = Vector(injectedAccountEncoder);
|
|
38
|
-
export const accountSubscriptionV1Encoder = _void;
|
|
39
|
-
export const accountUnsubscriptionV1Encoder = _void;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export declare const supportFeatureRequestV1Encoder: import("scale-ts").Codec<{
|
|
2
|
-
tag: "chain";
|
|
3
|
-
value: {
|
|
4
|
-
chainId: `0x${string}`;
|
|
5
|
-
};
|
|
6
|
-
}>;
|
|
7
|
-
export declare const supportFeatureResponseV1: import("scale-ts").Codec<{
|
|
8
|
-
tag: "chain";
|
|
9
|
-
value: {
|
|
10
|
-
chainId: `0x${string}`;
|
|
11
|
-
result: boolean;
|
|
12
|
-
};
|
|
13
|
-
}>;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Enum, Struct, bool } from 'scale-ts';
|
|
2
|
-
import { hexEncoder } from '../commonEncoders.js';
|
|
3
|
-
export const supportFeatureRequestV1Encoder = Enum({
|
|
4
|
-
chain: Struct({
|
|
5
|
-
chainId: hexEncoder,
|
|
6
|
-
}),
|
|
7
|
-
});
|
|
8
|
-
export const supportFeatureResponseV1 = Enum({
|
|
9
|
-
chain: Struct({
|
|
10
|
-
chainId: hexEncoder,
|
|
11
|
-
result: bool,
|
|
12
|
-
}),
|
|
13
|
-
});
|