@novasamatech/host-papp 0.5.0-17 → 0.5.0-19
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/.papi/descriptors/generated.json +1 -0
- package/dist/crypto.d.ts +2 -2
- package/dist/crypto.js +8 -7
- package/dist/helpers/abortError.d.ts +0 -1
- package/dist/helpers/abortError.js +0 -3
- package/dist/index.d.ts +1 -1
- package/dist/papp.js +2 -2
- package/dist/sso/auth/attestationService.js +1 -1
- package/dist/sso/auth/impl.d.ts +29 -3
- package/dist/sso/auth/impl.js +60 -35
- package/dist/sso/auth/types.d.ts +13 -2
- package/dist/sso/userSecretRepository.d.ts +1 -1
- package/dist/sso/userSecretRepository.js +2 -2
- package/package.json +5 -5
- package/dist/adapters/identity/rpc.d.ts +0 -6
- package/dist/adapters/identity/rpc.js +0 -101
- package/dist/adapters/identity/types.d.ts +0 -10
- package/dist/adapters/identity/types.js +0 -1
- package/dist/adapters/lazyClient/papi.d.ts +0 -3
- package/dist/adapters/lazyClient/papi.js +0 -17
- package/dist/adapters/lazyClient/types.d.ts +0 -5
- package/dist/adapters/lazyClient/types.js +0 -1
- package/dist/adapters/statement/rpc.d.ts +0 -3
- package/dist/adapters/statement/rpc.js +0 -93
- package/dist/adapters/statement/types.d.ts +0 -9
- package/dist/adapters/statement/types.js +0 -1
- package/dist/adapters/storage/localStorage.d.ts +0 -2
- package/dist/adapters/storage/localStorage.js +0 -34
- package/dist/adapters/storage/memory.d.ts +0 -2
- package/dist/adapters/storage/memory.js +0 -22
- package/dist/adapters/storage/types.d.ts +0 -7
- package/dist/adapters/storage/types.js +0 -1
- package/dist/adapters/transport/rpc.d.ts +0 -3
- package/dist/adapters/transport/rpc.js +0 -51
- package/dist/adapters/transport/types.d.ts +0 -6
- package/dist/adapters/transport/types.js +0 -1
- package/dist/components/auth/codec.d.ts +0 -9
- package/dist/components/auth/codec.js +0 -10
- package/dist/components/auth/codecs.d.ts +0 -9
- package/dist/components/auth/codecs.js +0 -10
- package/dist/components/auth/index.d.ts +0 -36
- package/dist/components/auth/index.js +0 -150
- package/dist/components/auth/types.d.ts +0 -15
- package/dist/components/auth/types.js +0 -1
- package/dist/components/session.d.ts +0 -34
- package/dist/components/session.js +0 -54
- package/dist/components/sso/index.d.ts +0 -36
- package/dist/components/sso/index.js +0 -150
- package/dist/components/sso/scale/handshake.d.ts +0 -9
- package/dist/components/sso/scale/handshake.js +0 -10
- package/dist/components/sso/types.d.ts +0 -15
- package/dist/components/sso/types.js +0 -1
- package/dist/components/transport.d.ts +0 -27
- package/dist/components/transport.js +0 -57
- package/dist/components/user/codec.d.ts +0 -16
- package/dist/components/user/codec.js +0 -13
- package/dist/components/user/index.d.ts +0 -22
- package/dist/components/user/index.js +0 -58
- package/dist/components/user/ssoMessageStream.d.ts +0 -10
- package/dist/components/user/ssoMessageStream.js +0 -8
- package/dist/components/user/ssoSession.d.ts +0 -5
- package/dist/components/user/ssoSession.js +0 -5
- package/dist/components/user/storage.d.ts +0 -27
- package/dist/components/user/storage.js +0 -143
- package/dist/components/user/types.d.ts +0 -6
- package/dist/components/user/types.js +0 -1
- package/dist/components/user/userSessionStorage.d.ts +0 -20
- package/dist/components/user/userSessionStorage.js +0 -24
- package/dist/components/user.d.ts +0 -74
- package/dist/components/user.js +0 -188
- package/dist/helpers/result.d.ts +0 -12
- package/dist/helpers/result.js +0 -15
- package/dist/helpers/result.spec.d.ts +0 -1
- package/dist/helpers/result.spec.js +0 -23
- package/dist/helpers.d.ts +0 -1
- package/dist/helpers.js +0 -3
- package/dist/modules/accounts.d.ts +0 -1
- package/dist/modules/accounts.js +0 -2
- package/dist/modules/crypto.d.ts +0 -23
- package/dist/modules/crypto.js +0 -51
- package/dist/modules/secretStorage.d.ts +0 -15
- package/dist/modules/secretStorage.js +0 -44
- package/dist/modules/session/helpers.d.ts +0 -5
- package/dist/modules/session/helpers.js +0 -29
- package/dist/modules/session/session.d.ts +0 -12
- package/dist/modules/session/session.js +0 -50
- package/dist/modules/session/types.d.ts +0 -12
- package/dist/modules/session/types.js +0 -1
- package/dist/modules/signIn.d.ts +0 -67
- package/dist/modules/signIn.js +0 -188
- package/dist/modules/state.d.ts +0 -16
- package/dist/modules/state.js +0 -50
- package/dist/modules/statementStore.d.ts +0 -12
- package/dist/modules/statementStore.js +0 -22
- package/dist/modules/statementTopic.d.ts +0 -34
- package/dist/modules/statementTopic.js +0 -46
- package/dist/modules/storageView.d.ts +0 -25
- package/dist/modules/storageView.js +0 -51
- package/dist/modules/syncStorage.d.ts +0 -25
- package/dist/modules/syncStorage.js +0 -76
- package/dist/modules/transport/codec.d.ts +0 -24
- package/dist/modules/transport/codec.js +0 -36
- package/dist/modules/transport/crypto.d.ts +0 -2
- package/dist/modules/transport/crypto.js +0 -20
- package/dist/modules/transport/transport.d.ts +0 -42
- package/dist/modules/transport/transport.js +0 -66
- package/dist/modules/user.d.ts +0 -67
- package/dist/modules/user.js +0 -188
- package/dist/modules/userManager.d.ts +0 -15
- package/dist/modules/userManager.js +0 -105
- package/dist/modules/userStorage.d.ts +0 -19
- package/dist/modules/userStorage.js +0 -108
- package/dist/modules/userStore.d.ts +0 -15
- package/dist/modules/userStore.js +0 -105
- package/dist/sso/session/impl.d.ts +0 -23
- package/dist/sso/session/impl.js +0 -57
- package/dist/sso/session/scale/remoteMessage.d.ts +0 -10
- package/dist/sso/session/scale/remoteMessage.js +0 -13
- package/dist/sso/session/sessionManager.d.ts +0 -23
- package/dist/sso/session/sessionManager.js +0 -58
- package/dist/sso/session/ssoSession.d.ts +0 -8
- package/dist/sso/session/ssoSession.js +0 -5
- package/dist/sso/session/ssoSessionStorage.d.ts +0 -21
- package/dist/sso/session/ssoSessionStorage.js +0 -20
- package/dist/sso/session/types.d.ts +0 -6
- package/dist/sso/session/types.js +0 -1
- package/dist/sso/session/userSessionStorage.d.ts +0 -21
- package/dist/sso/session/userSessionStorage.js +0 -20
- package/dist/sso/sessionManager/attestationService.d.ts +0 -5
- package/dist/sso/sessionManager/attestationService.js +0 -15
- package/dist/sso/sessionManager/repository/ssoSessionRepository.d.ts +0 -22
- package/dist/sso/sessionManager/repository/ssoSessionRepository.js +0 -27
- package/dist/sso/sessionManager/scale/signRequest.d.ts +0 -19
- package/dist/sso/sessionManager/scale/signRequest.js +0 -19
- package/dist/sso/sessionManager/scale/signResponse.d.ts +0 -6
- package/dist/sso/sessionManager/scale/signResponse.js +0 -5
- package/dist/sso/sessionManager/ssoSession.d.ts +0 -23
- package/dist/sso/sessionManager/ssoSession.js +0 -69
- package/dist/sso/sessionManager/ssoSessionProver.d.ts +0 -4
- package/dist/sso/sessionManager/ssoSessionProver.js +0 -35
- package/dist/sso/ssoSessionRepository.d.ts +0 -18
- package/dist/sso/ssoSessionRepository.js +0 -27
- package/dist/structs.d.ts +0 -24
- package/dist/structs.js +0 -36
package/dist/modules/signIn.js
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import { toHex } from '@polkadot-api/utils';
|
|
2
|
-
import { Bytes, Enum, Tuple, str } from 'scale-ts';
|
|
3
|
-
import { err, fromPromise, ok, seq } from '../helpers/result.js';
|
|
4
|
-
import { isAbortError, toError } from '../helpers/utils.js';
|
|
5
|
-
import { ENCR_SECRET_SEED_SIZE, EncrPubKey, SS_SECRET_SEED_SIZE, SsPubKey, createEncrSecret, createRandomSeed, createSharedSecret, createSsSecret, createSymmetricKey, decrypt, getEncrPub, getSsPub, khash, mergeBytes, stringToBytes, } from './crypto.js';
|
|
6
|
-
import { createSecretStorage } from './secretStorage.js';
|
|
7
|
-
import { createSession } from './statementStore.js';
|
|
8
|
-
import { createSyncStorage } from './syncStorage.js';
|
|
9
|
-
import { createUserManager } from './userManager.js';
|
|
10
|
-
// codecs
|
|
11
|
-
export const HandshakeData = Enum({
|
|
12
|
-
V1: Tuple(SsPubKey, EncrPubKey, str),
|
|
13
|
-
});
|
|
14
|
-
export const HandshakeResponsePayload = Enum({
|
|
15
|
-
// [encrypted, tmp_key]
|
|
16
|
-
V1: Tuple(Bytes(), Bytes(65)),
|
|
17
|
-
});
|
|
18
|
-
export const HandshakeResponseSensitiveData = Tuple(Bytes(65), Bytes(32));
|
|
19
|
-
export function createSignInFlow({ appId, metadata, statements, storage }) {
|
|
20
|
-
const userManager = createUserManager(appId, storage);
|
|
21
|
-
const secretStorage = createSecretStorage(appId, storage);
|
|
22
|
-
const signInStatus = createSyncStorage({ step: 'none' });
|
|
23
|
-
let signInPromise = null;
|
|
24
|
-
let abort = null;
|
|
25
|
-
async function handshake(signal) {
|
|
26
|
-
signInStatus.write({ step: 'initial' });
|
|
27
|
-
const secrets = await getSecretKeys(appId, secretStorage);
|
|
28
|
-
return secrets.andThenPromise(async ({ ssPublicKey, encrPublicKey, encrSecret }) => {
|
|
29
|
-
const handshakeTopic = createHandshakeTopic({ encrPublicKey, ssPublicKey });
|
|
30
|
-
const handshakePayload = createHandshakePayloadV1({ ssPublicKey, encrPublicKey, metadata });
|
|
31
|
-
signInStatus.write({ step: 'pairing', payload: createDeeplink(handshakePayload) });
|
|
32
|
-
const statementStoreResponse = fromPromise(waitForStatements(statements, handshakeTopic, signal, (statements, resolve) => {
|
|
33
|
-
for (const statement of [...statements].reverse()) {
|
|
34
|
-
if (!statement.data)
|
|
35
|
-
continue;
|
|
36
|
-
const { sessionTopic, accountId } = retrieveSessionTopic({
|
|
37
|
-
payload: statement.data.asBytes(),
|
|
38
|
-
encrSecret,
|
|
39
|
-
ssPublicKey,
|
|
40
|
-
});
|
|
41
|
-
resolve({ sessionTopic, accountId: toHex(accountId) });
|
|
42
|
-
break;
|
|
43
|
-
}
|
|
44
|
-
}), toError);
|
|
45
|
-
return statementStoreResponse
|
|
46
|
-
.then(x => x.andThenPromise(userManager.createUser))
|
|
47
|
-
.then(async (result) => result
|
|
48
|
-
.map(user => {
|
|
49
|
-
signInStatus.write({ step: 'finished', user });
|
|
50
|
-
return user;
|
|
51
|
-
})
|
|
52
|
-
.orElse(e => {
|
|
53
|
-
const error = toError(e);
|
|
54
|
-
if (isAbortError(error)) {
|
|
55
|
-
signInStatus.write({ step: 'none' });
|
|
56
|
-
return ok(null);
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
signInStatus.write({ step: 'error', message: error.message });
|
|
60
|
-
return err(error);
|
|
61
|
-
}
|
|
62
|
-
}));
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
const signInFlow = {
|
|
66
|
-
signInStatus,
|
|
67
|
-
users: userManager,
|
|
68
|
-
async signIn() {
|
|
69
|
-
if (signInPromise) {
|
|
70
|
-
return signInPromise;
|
|
71
|
-
}
|
|
72
|
-
abort = new AbortController();
|
|
73
|
-
signInPromise = handshake(abort.signal);
|
|
74
|
-
return signInPromise;
|
|
75
|
-
},
|
|
76
|
-
abortSignIn() {
|
|
77
|
-
if (abort) {
|
|
78
|
-
signInPromise = null;
|
|
79
|
-
signInStatus.reset();
|
|
80
|
-
abort.abort();
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
return signInFlow;
|
|
85
|
-
}
|
|
86
|
-
function createHandshakeTopic({ encrPublicKey, ssPublicKey, }) {
|
|
87
|
-
return khash(ssPublicKey, mergeBytes(encrPublicKey, stringToBytes('topic')));
|
|
88
|
-
}
|
|
89
|
-
function createHandshakePayloadV1({ encrPublicKey, ssPublicKey, metadata, }) {
|
|
90
|
-
return HandshakeData.enc({
|
|
91
|
-
tag: 'V1',
|
|
92
|
-
value: [ssPublicKey, encrPublicKey, metadata],
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
function parseHandshakePayload(payload) {
|
|
96
|
-
const decoded = HandshakeResponsePayload.dec(payload);
|
|
97
|
-
switch (decoded.tag) {
|
|
98
|
-
case 'V1':
|
|
99
|
-
return {
|
|
100
|
-
encrypted: decoded.value[0],
|
|
101
|
-
tmpKey: decoded.value[1],
|
|
102
|
-
};
|
|
103
|
-
default:
|
|
104
|
-
throw new Error('Unsupported handshake payload version');
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
function retrieveSessionTopic({ payload, encrSecret, ssPublicKey, }) {
|
|
108
|
-
const { encrypted, tmpKey } = parseHandshakePayload(payload);
|
|
109
|
-
const symmetricKey = createSymmetricKey(createSharedSecret(encrSecret, tmpKey));
|
|
110
|
-
const decrypted = decrypt(symmetricKey, encrypted);
|
|
111
|
-
const [pappEncrPublicKey, userPublicKey] = HandshakeResponseSensitiveData.dec(decrypted);
|
|
112
|
-
const sharedSecret = createSharedSecret(encrSecret, pappEncrPublicKey);
|
|
113
|
-
const session = createSession({
|
|
114
|
-
sharedSecret: sharedSecret,
|
|
115
|
-
accountA: ssPublicKey,
|
|
116
|
-
accountB: pappEncrPublicKey,
|
|
117
|
-
});
|
|
118
|
-
return {
|
|
119
|
-
accountId: userPublicKey,
|
|
120
|
-
sessionTopic: session.a,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
async function getSsKeys(appId, secretStorage) {
|
|
124
|
-
return (await secretStorage.readSsSecret())
|
|
125
|
-
.andThenPromise(async (ssSecret) => {
|
|
126
|
-
if (ssSecret) {
|
|
127
|
-
return ok(ssSecret);
|
|
128
|
-
}
|
|
129
|
-
const seed = createRandomSeed(appId, SS_SECRET_SEED_SIZE);
|
|
130
|
-
const newSsSecret = createSsSecret(seed);
|
|
131
|
-
const write = await secretStorage.writeSsSecret(newSsSecret);
|
|
132
|
-
return write.map(() => newSsSecret);
|
|
133
|
-
})
|
|
134
|
-
.then(x => x.map(ssSecret => ({
|
|
135
|
-
ssSecret: ssSecret,
|
|
136
|
-
ssPublicKey: getSsPub(ssSecret),
|
|
137
|
-
})));
|
|
138
|
-
}
|
|
139
|
-
async function getEncrKeys(appId, secretStorage) {
|
|
140
|
-
return (await secretStorage.readEncrSecret())
|
|
141
|
-
.andThenPromise(async (encrSecret) => {
|
|
142
|
-
if (encrSecret) {
|
|
143
|
-
return ok(encrSecret);
|
|
144
|
-
}
|
|
145
|
-
const seed = createRandomSeed(appId, ENCR_SECRET_SEED_SIZE);
|
|
146
|
-
const newEncrSecret = createEncrSecret(seed);
|
|
147
|
-
const write = await secretStorage.writeEncrSecret(newEncrSecret);
|
|
148
|
-
return write.map(() => newEncrSecret);
|
|
149
|
-
})
|
|
150
|
-
.then(x => x.map(encrSecret => ({
|
|
151
|
-
encrSecret,
|
|
152
|
-
encrPublicKey: getEncrPub(encrSecret),
|
|
153
|
-
})));
|
|
154
|
-
}
|
|
155
|
-
async function getSecretKeys(appId, secretStorage) {
|
|
156
|
-
return seq(await getSsKeys(appId, secretStorage), await getEncrKeys(appId, secretStorage)).map(([ss, encr]) => ({
|
|
157
|
-
...ss,
|
|
158
|
-
...encr,
|
|
159
|
-
}));
|
|
160
|
-
}
|
|
161
|
-
function createDeeplink(payload) {
|
|
162
|
-
return `polkadotapp://pair?handshake=${toHex(payload)}`;
|
|
163
|
-
}
|
|
164
|
-
function waitForStatements(transport, topic, abortSignal, callback) {
|
|
165
|
-
return new Promise((resolve, reject) => {
|
|
166
|
-
const unsubscribe = transport.subscribeStatements([topic], statements => {
|
|
167
|
-
if (abortSignal?.aborted) {
|
|
168
|
-
unsubscribe();
|
|
169
|
-
try {
|
|
170
|
-
abortSignal.throwIfAborted();
|
|
171
|
-
}
|
|
172
|
-
catch (e) {
|
|
173
|
-
reject(e);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
try {
|
|
177
|
-
callback(statements, value => {
|
|
178
|
-
unsubscribe();
|
|
179
|
-
resolve(value);
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
catch (e) {
|
|
183
|
-
unsubscribe();
|
|
184
|
-
reject(e);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
}
|
package/dist/modules/state.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
type State<T> = ReturnType<typeof createState<T>>;
|
|
2
|
-
export declare function createState<T>(initial: T): {
|
|
3
|
-
read(): T;
|
|
4
|
-
write(value: T): T;
|
|
5
|
-
reset(): void;
|
|
6
|
-
subscribe(fn: (value: T) => void): () => void;
|
|
7
|
-
onFirstSubscribe(callback: VoidFunction): import("nanoevents").Unsubscribe;
|
|
8
|
-
onLastUnsubscribe(callback: VoidFunction): import("nanoevents").Unsubscribe;
|
|
9
|
-
};
|
|
10
|
-
export declare function readonly<T>(state: State<T>): {
|
|
11
|
-
read: () => T;
|
|
12
|
-
subscribe: (fn: (value: T) => void) => () => void;
|
|
13
|
-
onFirstSubscribe: (callback: VoidFunction) => import("nanoevents").Unsubscribe;
|
|
14
|
-
onLastUnsubscribe: (callback: VoidFunction) => import("nanoevents").Unsubscribe;
|
|
15
|
-
};
|
|
16
|
-
export {};
|
package/dist/modules/state.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { createNanoEvents } from 'nanoevents';
|
|
2
|
-
export function createState(initial) {
|
|
3
|
-
const events = createNanoEvents();
|
|
4
|
-
let currentValue = initial;
|
|
5
|
-
return {
|
|
6
|
-
read() {
|
|
7
|
-
return currentValue;
|
|
8
|
-
},
|
|
9
|
-
write(value) {
|
|
10
|
-
if (currentValue !== value) {
|
|
11
|
-
currentValue = value;
|
|
12
|
-
events.emit('value', value);
|
|
13
|
-
}
|
|
14
|
-
return value;
|
|
15
|
-
},
|
|
16
|
-
reset() {
|
|
17
|
-
if (currentValue !== initial) {
|
|
18
|
-
currentValue = initial;
|
|
19
|
-
events.emit('value', initial);
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
subscribe(fn) {
|
|
23
|
-
if (!events.events.value || events.events.value.length === 0) {
|
|
24
|
-
events.emit('first');
|
|
25
|
-
}
|
|
26
|
-
const unsubscribe = events.on('value', fn);
|
|
27
|
-
fn(currentValue);
|
|
28
|
-
return () => {
|
|
29
|
-
unsubscribe();
|
|
30
|
-
if (!events.events.value || events.events.value.length === 0) {
|
|
31
|
-
events.emit('last');
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
},
|
|
35
|
-
onFirstSubscribe(callback) {
|
|
36
|
-
return events.on('first', callback);
|
|
37
|
-
},
|
|
38
|
-
onLastUnsubscribe(callback) {
|
|
39
|
-
return events.on('last', callback);
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
export function readonly(state) {
|
|
44
|
-
return {
|
|
45
|
-
read: state.read,
|
|
46
|
-
subscribe: state.subscribe,
|
|
47
|
-
onFirstSubscribe: state.onFirstSubscribe,
|
|
48
|
-
onLastUnsubscribe: state.onLastUnsubscribe,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { UserSession } from '../sso/session/ssoSessionStorage.js';
|
|
2
|
-
import type { SsSecret } from './crypto.js';
|
|
3
|
-
import type { Account } from './session/types.js';
|
|
4
|
-
export declare function createUserSession(hostAccount: Account, peerAccount: Account): UserSession;
|
|
5
|
-
type StatementPayload = {
|
|
6
|
-
priority: number;
|
|
7
|
-
channel: Uint8Array;
|
|
8
|
-
topics: Uint8Array[];
|
|
9
|
-
data: Uint8Array;
|
|
10
|
-
};
|
|
11
|
-
export declare function createStatement(secret: SsSecret, payload: StatementPayload): import("neverthrow").ResultAsync<import("@polkadot-api/sdk-statement").SignedStatement, Error>;
|
|
12
|
-
export {};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { getStatementSigner } from '@polkadot-api/sdk-statement';
|
|
2
|
-
import { Binary } from '@polkadot-api/substrate-bindings';
|
|
3
|
-
import { nanoid } from 'nanoid';
|
|
4
|
-
import { fromPromise } from 'neverthrow';
|
|
5
|
-
import { toError } from '../helpers/utils.js';
|
|
6
|
-
import { getSsPub, signWithSsSecret } from './crypto.js';
|
|
7
|
-
export function createUserSession(hostAccount, peerAccount) {
|
|
8
|
-
return {
|
|
9
|
-
id: nanoid(12),
|
|
10
|
-
peer: peerAccount,
|
|
11
|
-
host: hostAccount,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
export function createStatement(secret, payload) {
|
|
15
|
-
const signer = getStatementSigner(getSsPub(secret), 'sr25519', data => signWithSsSecret(secret, data));
|
|
16
|
-
return fromPromise(signer.sign({
|
|
17
|
-
priority: payload.priority,
|
|
18
|
-
channel: Binary.fromBytes(payload.channel),
|
|
19
|
-
topics: payload.topics.map(Binary.fromBytes),
|
|
20
|
-
data: Binary.fromBytes(payload.data),
|
|
21
|
-
}), toError);
|
|
22
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { Statement } from '@polkadot-api/sdk-statement';
|
|
2
|
-
import type { StatementAdapter } from '../adapters/statement/types.js';
|
|
3
|
-
import type { StorageAdapter } from '../adapters/storage/types.js';
|
|
4
|
-
import type { Callback } from '../types.js';
|
|
5
|
-
import type { SsSecret } from './crypto.js';
|
|
6
|
-
export declare function createSession({ sharedSecret, accountA, accountB, pinA, pinB, }: {
|
|
7
|
-
sharedSecret: Uint8Array;
|
|
8
|
-
accountA: Uint8Array;
|
|
9
|
-
accountB: Uint8Array;
|
|
10
|
-
pinA?: string;
|
|
11
|
-
pinB?: string;
|
|
12
|
-
}): {
|
|
13
|
-
a: Uint8Array<ArrayBufferLike>;
|
|
14
|
-
b: Uint8Array<ArrayBufferLike>;
|
|
15
|
-
};
|
|
16
|
-
export declare function createRequestChannel(session: Uint8Array): Uint8Array<ArrayBufferLike>;
|
|
17
|
-
export declare function createResponseChannel(session: Uint8Array): Uint8Array<ArrayBufferLike>;
|
|
18
|
-
type StatementPayload = {
|
|
19
|
-
priority: number;
|
|
20
|
-
channel: Uint8Array;
|
|
21
|
-
topics: Uint8Array[];
|
|
22
|
-
data: Uint8Array;
|
|
23
|
-
};
|
|
24
|
-
export declare function createStatement(secret: SsSecret, payload: StatementPayload): Promise<import("@polkadot-api/sdk-statement").SignedStatement>;
|
|
25
|
-
type Params = {
|
|
26
|
-
topic: Uint8Array;
|
|
27
|
-
statement: StatementAdapter;
|
|
28
|
-
storage: StorageAdapter;
|
|
29
|
-
};
|
|
30
|
-
export declare function createStatementTopic({ topic, statement }: Params): {
|
|
31
|
-
subscribe(callback: Callback<Statement, boolean>): VoidFunction;
|
|
32
|
-
submit(): void;
|
|
33
|
-
};
|
|
34
|
-
export {};
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { getStatementSigner } from '@polkadot-api/sdk-statement';
|
|
2
|
-
import { Binary } from '@polkadot-api/substrate-bindings';
|
|
3
|
-
import { getSsPub, khash, mergeBytes, signWithSsSecret, stringToBytes } from './crypto.js';
|
|
4
|
-
export function createSession({ sharedSecret, accountA, accountB, pinA, pinB, }) {
|
|
5
|
-
const sessionPrefix = stringToBytes('session');
|
|
6
|
-
const pinSeparator = stringToBytes('/');
|
|
7
|
-
function makePin(pin) {
|
|
8
|
-
return pin ? mergeBytes(pinSeparator, stringToBytes(pin)) : pinSeparator;
|
|
9
|
-
}
|
|
10
|
-
const accountASessionParams = mergeBytes(sessionPrefix, accountA, accountB, makePin(pinA), makePin(pinB));
|
|
11
|
-
const accountBSessionParams = mergeBytes(sessionPrefix, accountB, accountA, makePin(pinB), makePin(pinA));
|
|
12
|
-
return {
|
|
13
|
-
a: khash(sharedSecret, accountASessionParams),
|
|
14
|
-
b: khash(sharedSecret, accountBSessionParams),
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
export function createRequestChannel(session) {
|
|
18
|
-
return khash(session, stringToBytes('request'));
|
|
19
|
-
}
|
|
20
|
-
export function createResponseChannel(session) {
|
|
21
|
-
return khash(session, stringToBytes('response'));
|
|
22
|
-
}
|
|
23
|
-
export function createStatement(secret, payload) {
|
|
24
|
-
const signer = getStatementSigner(getSsPub(secret), 'sr25519', data => signWithSsSecret(secret, data));
|
|
25
|
-
return signer.sign({
|
|
26
|
-
priority: payload.priority,
|
|
27
|
-
channel: Binary.fromBytes(payload.channel),
|
|
28
|
-
topics: payload.topics.map(Binary.fromBytes),
|
|
29
|
-
data: Binary.fromBytes(payload.data),
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
export function createStatementTopic({ topic, statement }) {
|
|
33
|
-
return {
|
|
34
|
-
subscribe(callback) {
|
|
35
|
-
return statement.subscribeStatements([topic], statements => {
|
|
36
|
-
for (const statement of statements) {
|
|
37
|
-
const processed = callback(statement);
|
|
38
|
-
if (processed) {
|
|
39
|
-
// TODO save anywhere
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
},
|
|
44
|
-
submit() { },
|
|
45
|
-
};
|
|
46
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { ResultAsync } from 'neverthrow';
|
|
2
|
-
import type { StorageAdapter } from '../adapters/storage/types.js';
|
|
3
|
-
type Params<T> = {
|
|
4
|
-
storage: StorageAdapter;
|
|
5
|
-
key: string;
|
|
6
|
-
initial: T;
|
|
7
|
-
autosync?: boolean;
|
|
8
|
-
from(value: string): T;
|
|
9
|
-
to(value: T): string | null;
|
|
10
|
-
};
|
|
11
|
-
export declare function storageView<T>({ storage, initial, key, from, to, autosync }: Params<T>): {
|
|
12
|
-
read(): any;
|
|
13
|
-
write(value: T): any;
|
|
14
|
-
clear(): any;
|
|
15
|
-
subscribe(fn: (value: T) => void): () => void;
|
|
16
|
-
};
|
|
17
|
-
export declare function storageListView<T>(params: Params<T[]>): {
|
|
18
|
-
add(value: T): ResultAsync<T, Error>;
|
|
19
|
-
mutate(fn: (value: T[]) => T[]): ResultAsync<T[], Error>;
|
|
20
|
-
read(): any;
|
|
21
|
-
write(value: T[]): any;
|
|
22
|
-
clear(): any;
|
|
23
|
-
subscribe(fn: (value: T[]) => void): () => void;
|
|
24
|
-
};
|
|
25
|
-
export {};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { okAsync } from 'neverthrow';
|
|
2
|
-
import { nonNullable } from '../helpers/utils.js';
|
|
3
|
-
import { createState } from './state.js';
|
|
4
|
-
export function storageView({ storage, initial, key, from, to, autosync = true }) {
|
|
5
|
-
const state = createState(to(initial));
|
|
6
|
-
const enhancedStorage = {
|
|
7
|
-
read() {
|
|
8
|
-
return storage
|
|
9
|
-
.read(key)
|
|
10
|
-
.map(state.write)
|
|
11
|
-
.map(x => (nonNullable(x) ? from(x) : initial));
|
|
12
|
-
},
|
|
13
|
-
write(value) {
|
|
14
|
-
const data = to(value);
|
|
15
|
-
if (data !== null) {
|
|
16
|
-
return storage
|
|
17
|
-
.write(key, data)
|
|
18
|
-
.map(() => state.write(data))
|
|
19
|
-
.map(() => value);
|
|
20
|
-
}
|
|
21
|
-
return okAsync(null);
|
|
22
|
-
},
|
|
23
|
-
clear() {
|
|
24
|
-
return storage.clear(key).map(() => state.reset());
|
|
25
|
-
},
|
|
26
|
-
subscribe(fn) {
|
|
27
|
-
return state.subscribe(x => fn(nonNullable(x) ? from(x) : initial));
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
if (autosync) {
|
|
31
|
-
enhancedStorage.read();
|
|
32
|
-
}
|
|
33
|
-
state.onFirstSubscribe(() => enhancedStorage.read());
|
|
34
|
-
return enhancedStorage;
|
|
35
|
-
}
|
|
36
|
-
export function storageListView(params) {
|
|
37
|
-
const view = storageView(params);
|
|
38
|
-
const listView = {
|
|
39
|
-
...view,
|
|
40
|
-
add(value) {
|
|
41
|
-
return listView.mutate(list => list.concat(value)).map(() => value);
|
|
42
|
-
},
|
|
43
|
-
mutate(fn) {
|
|
44
|
-
return listView.read().andThen(list => {
|
|
45
|
-
const result = fn(list);
|
|
46
|
-
return listView.write(result).map(() => result);
|
|
47
|
-
});
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
return listView;
|
|
51
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { StorageAdapter } from '../adapters/storage/types.js';
|
|
2
|
-
export declare function createSyncStorage<T>(initial: T): {
|
|
3
|
-
touched(): boolean;
|
|
4
|
-
read(): T;
|
|
5
|
-
write(value: T): T;
|
|
6
|
-
reset(): void;
|
|
7
|
-
subscribe(fn: (value: T) => void): () => void;
|
|
8
|
-
onFirstSubscribe(callback: VoidFunction): import("nanoevents").Unsubscribe;
|
|
9
|
-
onLastUnsubscribe(callback: VoidFunction): import("nanoevents").Unsubscribe;
|
|
10
|
-
};
|
|
11
|
-
type ReactiveStorageParams<T> = {
|
|
12
|
-
storage: StorageAdapter;
|
|
13
|
-
key: string;
|
|
14
|
-
initial: T;
|
|
15
|
-
autosync: boolean;
|
|
16
|
-
from(value: string): T;
|
|
17
|
-
to(value: T): string | null;
|
|
18
|
-
};
|
|
19
|
-
export declare function reactiveStorage<T>({ storage, initial, key, autosync, from, to }: ReactiveStorageParams<T>): {
|
|
20
|
-
read(): Promise<import("../helpers/result.js").Result<T, Error>>;
|
|
21
|
-
write(value: T): Promise<import("../helpers/result.js").Result<null, Error> | import("../helpers/result.js").Result<T, Error>>;
|
|
22
|
-
clear(): Promise<import("../helpers/result.js").Result<void, Error>>;
|
|
23
|
-
subscribe(fn: (value: T | null) => void): () => void;
|
|
24
|
-
};
|
|
25
|
-
export {};
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { createNanoEvents } from 'nanoevents';
|
|
2
|
-
import { ok } from '../helpers/result.js';
|
|
3
|
-
export function createSyncStorage(initial) {
|
|
4
|
-
const events = createNanoEvents();
|
|
5
|
-
let touched = false;
|
|
6
|
-
let currentValue = initial;
|
|
7
|
-
return {
|
|
8
|
-
touched() {
|
|
9
|
-
return touched;
|
|
10
|
-
},
|
|
11
|
-
read() {
|
|
12
|
-
return currentValue;
|
|
13
|
-
},
|
|
14
|
-
write(value) {
|
|
15
|
-
if (currentValue !== value) {
|
|
16
|
-
touched = true;
|
|
17
|
-
currentValue = value;
|
|
18
|
-
events.emit('value', value);
|
|
19
|
-
}
|
|
20
|
-
return value;
|
|
21
|
-
},
|
|
22
|
-
reset() {
|
|
23
|
-
if (currentValue !== initial) {
|
|
24
|
-
touched = true;
|
|
25
|
-
currentValue = initial;
|
|
26
|
-
events.emit('value', initial);
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
subscribe(fn) {
|
|
30
|
-
if (!events.events.value || events.events.value.length === 0) {
|
|
31
|
-
events.emit('first');
|
|
32
|
-
}
|
|
33
|
-
const unsubscribe = events.on('value', fn);
|
|
34
|
-
return () => {
|
|
35
|
-
unsubscribe();
|
|
36
|
-
if (!events.events.value || events.events.value.length === 0) {
|
|
37
|
-
events.emit('last');
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
},
|
|
41
|
-
onFirstSubscribe(callback) {
|
|
42
|
-
return events.on('first', callback);
|
|
43
|
-
},
|
|
44
|
-
onLastUnsubscribe(callback) {
|
|
45
|
-
return events.on('last', callback);
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
export function reactiveStorage({ storage, initial, key, autosync, from, to }) {
|
|
50
|
-
const sync = createSyncStorage(initial);
|
|
51
|
-
const enhancedStorage = {
|
|
52
|
-
async read() {
|
|
53
|
-
const result = await storage.read(key);
|
|
54
|
-
return result.map(x => sync.write(x === null ? initial : from(x)));
|
|
55
|
-
},
|
|
56
|
-
async write(value) {
|
|
57
|
-
const data = to(value);
|
|
58
|
-
if (data !== null) {
|
|
59
|
-
const result = await storage.write(key, data);
|
|
60
|
-
return result.map(() => sync.write(value));
|
|
61
|
-
}
|
|
62
|
-
return ok(null);
|
|
63
|
-
},
|
|
64
|
-
async clear() {
|
|
65
|
-
const result = await storage.clear(key);
|
|
66
|
-
return result.map(() => sync.reset());
|
|
67
|
-
},
|
|
68
|
-
subscribe(fn) {
|
|
69
|
-
return sync.subscribe(fn);
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
if (autosync) {
|
|
73
|
-
sync.onFirstSubscribe(() => enhancedStorage.read());
|
|
74
|
-
}
|
|
75
|
-
return enhancedStorage;
|
|
76
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { Codec } from 'scale-ts';
|
|
2
|
-
export type TransportError = 'decryptionFailed' | 'decodingFailed' | 'unknown';
|
|
3
|
-
export declare const TransportErrorCodec: Codec<TransportError>;
|
|
4
|
-
export declare const Request: <T>(data: Codec<T>) => Codec<{
|
|
5
|
-
requestId: string;
|
|
6
|
-
data: T[];
|
|
7
|
-
}>;
|
|
8
|
-
export declare const Response: Codec<{
|
|
9
|
-
requestId: string;
|
|
10
|
-
responseCode: TransportError;
|
|
11
|
-
}>;
|
|
12
|
-
export declare const StatementData: <T>(data: Codec<T>) => Codec<{
|
|
13
|
-
tag: "request";
|
|
14
|
-
value: {
|
|
15
|
-
requestId: string;
|
|
16
|
-
data: T[];
|
|
17
|
-
};
|
|
18
|
-
} | {
|
|
19
|
-
tag: "response";
|
|
20
|
-
value: {
|
|
21
|
-
requestId: string;
|
|
22
|
-
responseCode: TransportError;
|
|
23
|
-
};
|
|
24
|
-
}>;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { Enum, Struct, Vector, enhanceCodec, str, u8 } from 'scale-ts';
|
|
2
|
-
export const TransportErrorCodec = enhanceCodec(u8, error => {
|
|
3
|
-
switch (error) {
|
|
4
|
-
case 'decryptionFailed':
|
|
5
|
-
return 1;
|
|
6
|
-
case 'decodingFailed':
|
|
7
|
-
return 2;
|
|
8
|
-
case 'unknown':
|
|
9
|
-
return 255;
|
|
10
|
-
}
|
|
11
|
-
}, code => {
|
|
12
|
-
switch (code) {
|
|
13
|
-
case 1:
|
|
14
|
-
return 'decryptionFailed';
|
|
15
|
-
case 2:
|
|
16
|
-
return 'decodingFailed';
|
|
17
|
-
default:
|
|
18
|
-
return 'unknown';
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
export const Request = (data) => {
|
|
22
|
-
return Struct({
|
|
23
|
-
requestId: str,
|
|
24
|
-
data: Vector(data),
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
export const Response = Struct({
|
|
28
|
-
requestId: str,
|
|
29
|
-
responseCode: TransportErrorCodec,
|
|
30
|
-
});
|
|
31
|
-
export const StatementData = (data) => {
|
|
32
|
-
return Enum({
|
|
33
|
-
request: Request(data),
|
|
34
|
-
response: Response,
|
|
35
|
-
});
|
|
36
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { gcm } from '@noble/ciphers/aes.js';
|
|
2
|
-
import { hkdf } from '@noble/hashes/hkdf.js';
|
|
3
|
-
import { sha256 } from '@noble/hashes/sha2.js';
|
|
4
|
-
import { randomBytes } from '@noble/hashes/utils.js';
|
|
5
|
-
import { mergeBytes } from '../crypto.js';
|
|
6
|
-
export function encrypt(secret, cipherText) {
|
|
7
|
-
const nonce = randomBytes(12);
|
|
8
|
-
const salt = new Uint8Array(); // secure enough since P256 random keys provide enough entropy
|
|
9
|
-
const info = new Uint8Array(); // no need to introduce any context
|
|
10
|
-
const aesKey = hkdf(sha256, secret, salt, info, 32);
|
|
11
|
-
const aes = gcm(aesKey, nonce);
|
|
12
|
-
return aes.encrypt(mergeBytes(nonce, cipherText));
|
|
13
|
-
}
|
|
14
|
-
export function decrypt(secret, message) {
|
|
15
|
-
const nonce = message.slice(0, 12);
|
|
16
|
-
const cipherText = message.slice(12);
|
|
17
|
-
const aesKey = hkdf(sha256, secret, new Uint8Array(), new Uint8Array(), 32);
|
|
18
|
-
const aes = gcm(aesKey, nonce);
|
|
19
|
-
return aes.decrypt(cipherText);
|
|
20
|
-
}
|