@novasamatech/host-papp 0.5.0-8 → 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.
Files changed (152) hide show
  1. package/.papi/descriptors/dist/common-types.d.ts +8667 -0
  2. package/.papi/descriptors/dist/common.d.ts +1 -0
  3. package/.papi/descriptors/dist/descriptors-UUEW32EL.mjs +27 -0
  4. package/.papi/descriptors/dist/descriptors.d.ts +1 -0
  5. package/.papi/descriptors/dist/index.d.ts +10 -0
  6. package/.papi/descriptors/dist/index.js +237 -0
  7. package/.papi/descriptors/dist/index.mjs +148 -0
  8. package/.papi/descriptors/dist/metadataTypes-E4AQJDJR.mjs +6 -0
  9. package/.papi/descriptors/dist/metadataTypes.d.ts +2 -0
  10. package/.papi/descriptors/dist/people_lite.d.ts +7757 -0
  11. package/.papi/descriptors/dist/people_lite_metadata-EIVHV27X.mjs +6 -0
  12. package/.papi/descriptors/dist/people_lite_metadata.d.ts +2 -0
  13. package/.papi/descriptors/generated.json +1 -0
  14. package/.papi/descriptors/package.json +24 -0
  15. package/.papi/metadata/people_lite.scale +0 -0
  16. package/.papi/polkadot-api.json +15 -0
  17. package/dist/constants.d.ts +2 -2
  18. package/dist/constants.js +2 -2
  19. package/dist/{modules/crypto.d.ts → crypto.d.ts} +14 -12
  20. package/dist/crypto.js +87 -0
  21. package/dist/helpers/abortError.d.ts +0 -1
  22. package/dist/helpers/abortError.js +0 -3
  23. package/dist/{modules → helpers}/state.d.ts +1 -1
  24. package/dist/{modules → helpers}/state.js +5 -4
  25. package/dist/helpers/zipWith.d.ts +4 -0
  26. package/dist/helpers/zipWith.js +11 -0
  27. package/dist/identity/impl.d.ts +6 -0
  28. package/dist/identity/impl.js +68 -0
  29. package/dist/identity/rpcAdapter.d.ts +3 -0
  30. package/dist/identity/rpcAdapter.js +46 -0
  31. package/dist/identity/types.d.ts +21 -0
  32. package/dist/index.d.ts +7 -4
  33. package/dist/index.js +2 -7
  34. package/dist/papp.d.ts +24 -13
  35. package/dist/papp.js +19 -38
  36. package/dist/sso/auth/attestationService.d.ts +18 -0
  37. package/dist/sso/auth/attestationService.js +171 -0
  38. package/dist/sso/auth/impl.d.ts +79 -0
  39. package/dist/sso/auth/impl.js +186 -0
  40. package/dist/{components/auth/codec.d.ts → sso/auth/scale/handshake.d.ts} +3 -3
  41. package/dist/{components/auth/codec.js → sso/auth/scale/handshake.js} +3 -3
  42. package/dist/sso/auth/types.d.ts +28 -0
  43. package/dist/sso/sessionManager/impl.d.ts +22 -0
  44. package/dist/sso/sessionManager/impl.js +71 -0
  45. package/dist/sso/sessionManager/scale/hex.d.ts +1 -0
  46. package/dist/sso/sessionManager/scale/hex.js +3 -0
  47. package/dist/sso/sessionManager/scale/remoteMessage.d.ts +41 -0
  48. package/dist/sso/sessionManager/scale/remoteMessage.js +13 -0
  49. package/dist/sso/sessionManager/scale/signPayloadRequest.d.ts +20 -0
  50. package/dist/sso/sessionManager/scale/signPayloadRequest.js +20 -0
  51. package/dist/sso/sessionManager/scale/signPayloadResponse.d.ts +14 -0
  52. package/dist/sso/sessionManager/scale/signPayloadResponse.js +10 -0
  53. package/dist/{components/user → sso/sessionManager}/types.d.ts +1 -1
  54. package/dist/sso/sessionManager/userSession.d.ts +22 -0
  55. package/dist/sso/sessionManager/userSession.js +116 -0
  56. package/dist/sso/ssoSessionProver.d.ts +4 -0
  57. package/dist/sso/ssoSessionProver.js +35 -0
  58. package/dist/sso/userSecretRepository.d.ts +17 -0
  59. package/dist/sso/userSecretRepository.js +45 -0
  60. package/dist/sso/userSessionRepository.d.ts +18 -0
  61. package/dist/sso/userSessionRepository.js +26 -0
  62. package/package.json +13 -8
  63. package/dist/adapters/identity/rpc.d.ts +0 -6
  64. package/dist/adapters/identity/rpc.js +0 -101
  65. package/dist/adapters/identity/types.d.ts +0 -10
  66. package/dist/adapters/lazyClient/papi.d.ts +0 -3
  67. package/dist/adapters/lazyClient/papi.js +0 -17
  68. package/dist/adapters/lazyClient/types.d.ts +0 -5
  69. package/dist/adapters/statement/rpc.d.ts +0 -3
  70. package/dist/adapters/statement/rpc.js +0 -93
  71. package/dist/adapters/statement/types.d.ts +0 -9
  72. package/dist/adapters/storage/localStorage.d.ts +0 -2
  73. package/dist/adapters/storage/localStorage.js +0 -34
  74. package/dist/adapters/storage/memory.d.ts +0 -2
  75. package/dist/adapters/storage/memory.js +0 -22
  76. package/dist/adapters/storage/types.d.ts +0 -7
  77. package/dist/adapters/storage/types.js +0 -1
  78. package/dist/adapters/transport/rpc.d.ts +0 -3
  79. package/dist/adapters/transport/rpc.js +0 -51
  80. package/dist/adapters/transport/types.d.ts +0 -6
  81. package/dist/adapters/transport/types.js +0 -1
  82. package/dist/components/auth/codecs.d.ts +0 -9
  83. package/dist/components/auth/codecs.js +0 -10
  84. package/dist/components/auth/index.d.ts +0 -36
  85. package/dist/components/auth/index.js +0 -150
  86. package/dist/components/auth/types.d.ts +0 -15
  87. package/dist/components/auth/types.js +0 -1
  88. package/dist/components/session.d.ts +0 -34
  89. package/dist/components/session.js +0 -54
  90. package/dist/components/transport.d.ts +0 -27
  91. package/dist/components/transport.js +0 -57
  92. package/dist/components/user/codec.d.ts +0 -16
  93. package/dist/components/user/codec.js +0 -13
  94. package/dist/components/user/index.d.ts +0 -22
  95. package/dist/components/user/index.js +0 -58
  96. package/dist/components/user/ssoMessageStream.d.ts +0 -10
  97. package/dist/components/user/ssoMessageStream.js +0 -8
  98. package/dist/components/user/ssoSession.d.ts +0 -5
  99. package/dist/components/user/ssoSession.js +0 -5
  100. package/dist/components/user/storage.d.ts +0 -27
  101. package/dist/components/user/storage.js +0 -143
  102. package/dist/components/user/types.js +0 -1
  103. package/dist/components/user/userSessionStorage.d.ts +0 -20
  104. package/dist/components/user/userSessionStorage.js +0 -24
  105. package/dist/components/user.d.ts +0 -74
  106. package/dist/components/user.js +0 -188
  107. package/dist/helpers/result.d.ts +0 -12
  108. package/dist/helpers/result.js +0 -15
  109. package/dist/helpers/result.spec.d.ts +0 -1
  110. package/dist/helpers/result.spec.js +0 -23
  111. package/dist/helpers.d.ts +0 -1
  112. package/dist/helpers.js +0 -3
  113. package/dist/modules/accounts.d.ts +0 -1
  114. package/dist/modules/accounts.js +0 -2
  115. package/dist/modules/crypto.js +0 -84
  116. package/dist/modules/secretStorage.d.ts +0 -12
  117. package/dist/modules/secretStorage.js +0 -40
  118. package/dist/modules/session/helpers.d.ts +0 -5
  119. package/dist/modules/session/helpers.js +0 -29
  120. package/dist/modules/session/session.d.ts +0 -12
  121. package/dist/modules/session/session.js +0 -46
  122. package/dist/modules/session/types.d.ts +0 -12
  123. package/dist/modules/session/types.js +0 -1
  124. package/dist/modules/signIn.d.ts +0 -67
  125. package/dist/modules/signIn.js +0 -188
  126. package/dist/modules/statementStore.d.ts +0 -12
  127. package/dist/modules/statementStore.js +0 -20
  128. package/dist/modules/statementTopic.d.ts +0 -34
  129. package/dist/modules/statementTopic.js +0 -46
  130. package/dist/modules/storageView.d.ts +0 -25
  131. package/dist/modules/storageView.js +0 -51
  132. package/dist/modules/syncStorage.d.ts +0 -25
  133. package/dist/modules/syncStorage.js +0 -76
  134. package/dist/modules/transport/codec.d.ts +0 -24
  135. package/dist/modules/transport/codec.js +0 -36
  136. package/dist/modules/transport/crypto.d.ts +0 -2
  137. package/dist/modules/transport/crypto.js +0 -18
  138. package/dist/modules/transport/transport.d.ts +0 -27
  139. package/dist/modules/transport/transport.js +0 -56
  140. package/dist/modules/user.d.ts +0 -67
  141. package/dist/modules/user.js +0 -188
  142. package/dist/modules/userManager.d.ts +0 -15
  143. package/dist/modules/userManager.js +0 -105
  144. package/dist/modules/userStorage.d.ts +0 -19
  145. package/dist/modules/userStorage.js +0 -108
  146. package/dist/modules/userStore.d.ts +0 -15
  147. package/dist/modules/userStore.js +0 -105
  148. package/dist/structs.d.ts +0 -24
  149. package/dist/structs.js +0 -36
  150. /package/dist/{adapters/identity → identity}/types.js +0 -0
  151. /package/dist/{adapters/lazyClient → sso/auth}/types.js +0 -0
  152. /package/dist/{adapters/statement → sso/sessionManager}/types.js +0 -0
@@ -0,0 +1,20 @@
1
+ import { Option, Struct, Vector, bool, str, u32 } from 'scale-ts';
2
+ import { hexCodec } from './hex.js';
3
+ export const SignPayloadRequestCodec = Struct({
4
+ address: str,
5
+ blockHash: hexCodec,
6
+ blockNumber: hexCodec,
7
+ era: hexCodec,
8
+ genesisHash: hexCodec,
9
+ method: hexCodec,
10
+ nonce: hexCodec,
11
+ specVersion: hexCodec,
12
+ tip: hexCodec,
13
+ transactionVersion: hexCodec,
14
+ signedExtensions: Vector(str),
15
+ version: u32,
16
+ assetId: Option(hexCodec),
17
+ metadataHash: Option(hexCodec),
18
+ mode: Option(u32),
19
+ withSignedTransaction: Option(bool),
20
+ });
@@ -0,0 +1,14 @@
1
+ import type { CodecType } from 'scale-ts';
2
+ export type SignPayloadResponseData = CodecType<typeof SignPayloadResponseDataCodec>;
3
+ export declare const SignPayloadResponseDataCodec: import("scale-ts").Codec<{
4
+ signature: Uint8Array<ArrayBufferLike>;
5
+ signedTransaction: Uint8Array<ArrayBufferLike> | undefined;
6
+ }>;
7
+ export type SignPayloadResponse = CodecType<typeof SignPayloadResponseCodec>;
8
+ export declare const SignPayloadResponseCodec: import("scale-ts").Codec<{
9
+ respondingTo: string;
10
+ payload: import("scale-ts").ResultPayload<{
11
+ signature: Uint8Array<ArrayBufferLike>;
12
+ signedTransaction: Uint8Array<ArrayBufferLike> | undefined;
13
+ }, string>;
14
+ }>;
@@ -0,0 +1,10 @@
1
+ import { Bytes, Option, Result, Struct, str } from 'scale-ts';
2
+ export const SignPayloadResponseDataCodec = Struct({
3
+ signature: Bytes(),
4
+ signedTransaction: Option(Bytes()),
5
+ });
6
+ export const SignPayloadResponseCodec = Struct({
7
+ // referencing to RemoteMessage.messageId
8
+ respondingTo: str,
9
+ payload: Result(SignPayloadResponseDataCodec, str),
10
+ });
@@ -1,4 +1,4 @@
1
- import type { EncrSecret, SharedSecret, SsSecret } from '../../modules/crypto.js';
1
+ import type { EncrSecret, SharedSecret, SsSecret } from '../../crypto.js';
2
2
  export type UserSecrets = {
3
3
  sharedSecret: SharedSecret;
4
4
  encr: EncrSecret;
@@ -0,0 +1,22 @@
1
+ import type { Encryption, StatementProver, StatementStoreAdapter } from '@novasamatech/statement-store';
2
+ import type { StorageAdapter } from '@novasamatech/storage-adapter';
3
+ import { ResultAsync } from 'neverthrow';
4
+ import type { CodecType } from 'scale-ts';
5
+ import type { Callback } from '../../types.js';
6
+ import type { StoredUserSession } from '../userSessionRepository.js';
7
+ import { RemoteMessageCodec } from './scale/remoteMessage.js';
8
+ import type { SignPayloadRequest } from './scale/signPayloadRequest.js';
9
+ import type { SignPayloadResponseData } from './scale/signPayloadResponse.js';
10
+ export type UserSession = StoredUserSession & {
11
+ sendDisconnectMessage(): ResultAsync<void, Error>;
12
+ signPayload(payload: SignPayloadRequest): ResultAsync<SignPayloadResponseData, Error>;
13
+ subscribe(callback: Callback<CodecType<typeof RemoteMessageCodec>, ResultAsync<boolean, Error>>): VoidFunction;
14
+ dispose(): void;
15
+ };
16
+ export declare function createUserSession({ userSession, statementStore, encryption, storage, prover, }: {
17
+ userSession: StoredUserSession;
18
+ statementStore: StatementStoreAdapter;
19
+ encryption: Encryption;
20
+ storage: StorageAdapter;
21
+ prover: StatementProver;
22
+ }): UserSession;
@@ -0,0 +1,116 @@
1
+ import { createSession } from '@novasamatech/statement-store';
2
+ import { fieldListView } from '@novasamatech/storage-adapter';
3
+ import { AccountId } from '@polkadot-api/substrate-bindings';
4
+ import { toHex } from '@polkadot-api/utils';
5
+ import { nanoid } from 'nanoid';
6
+ import { ResultAsync, err, errAsync, ok, okAsync } from 'neverthrow';
7
+ import { RemoteMessageCodec } from './scale/remoteMessage.js';
8
+ export function createUserSession({ userSession, statementStore, encryption, storage, prover, }) {
9
+ const session = createSession({
10
+ localAccount: userSession.localAccount,
11
+ remoteAccount: userSession.remoteAccount,
12
+ statementStore,
13
+ encryption,
14
+ prover,
15
+ });
16
+ const processedMessages = fieldListView({
17
+ storage,
18
+ key: `sso_processed_${userSession.id}`,
19
+ from: JSON.parse,
20
+ to: JSON.stringify,
21
+ });
22
+ return {
23
+ id: userSession.id,
24
+ localAccount: userSession.localAccount,
25
+ remoteAccount: userSession.remoteAccount,
26
+ signPayload(payload) {
27
+ const accountId = AccountId();
28
+ if (toHex(accountId.enc(payload.address)) !== toHex(userSession.remoteAccount.accountId)) {
29
+ return errAsync(new Error(`Invalid address, got ${payload.address}`));
30
+ }
31
+ const messageId = nanoid();
32
+ const request = session.request(RemoteMessageCodec, {
33
+ messageId,
34
+ data: {
35
+ tag: 'v1',
36
+ value: {
37
+ tag: 'SignRequest',
38
+ value: payload,
39
+ },
40
+ },
41
+ });
42
+ const responseFilter = (message) => {
43
+ return (message.data.tag === 'v1' &&
44
+ message.data.value.tag === 'SignResponse' &&
45
+ message.data.value.value.respondingTo === messageId);
46
+ };
47
+ return request
48
+ .andThen(() => session.waitForRequestMessage(RemoteMessageCodec, responseFilter))
49
+ .andThen(message => {
50
+ const { data } = message.payload;
51
+ switch (data.tag) {
52
+ case 'v1': {
53
+ switch (data.value.tag) {
54
+ case 'SignResponse':
55
+ if (data.value.value.payload.success) {
56
+ return ok(data.value.value.payload.value);
57
+ }
58
+ else {
59
+ return err(new Error(data.value.value.payload.value));
60
+ }
61
+ default:
62
+ return err(new Error(`Incorrect sign response: ${data.value.tag}`));
63
+ }
64
+ }
65
+ default:
66
+ return err(new Error(`Unsupported message version ${data.tag}`));
67
+ }
68
+ });
69
+ },
70
+ sendDisconnectMessage() {
71
+ return session
72
+ .submitRequestMessage(RemoteMessageCodec, {
73
+ messageId: nanoid(),
74
+ data: {
75
+ tag: 'v1',
76
+ value: {
77
+ tag: 'Disconnected',
78
+ value: undefined,
79
+ },
80
+ },
81
+ })
82
+ .map(() => undefined);
83
+ },
84
+ subscribe(callback) {
85
+ return session.subscribe(RemoteMessageCodec, messages => {
86
+ processedMessages.read().andThen(processed => {
87
+ const results = messages.map(message => {
88
+ if (message.type === 'request') {
89
+ const isMessageProcessed = processed.includes(message.payload.messageId);
90
+ if (isMessageProcessed) {
91
+ return okAsync({ processed: false });
92
+ }
93
+ return callback(message.payload)
94
+ .orTee(error => {
95
+ console.error('Error while processing sso messsage:', error);
96
+ })
97
+ .orElse(() => okAsync(false))
98
+ .map(processed => (processed ? { processed, message: message.payload } : { processed }));
99
+ }
100
+ return okAsync({ processed: false });
101
+ });
102
+ return ResultAsync.combine(results).andThen(results => {
103
+ const newMessages = results.filter(x => x.processed).map(x => x.message.messageId);
104
+ if (newMessages.length > 0) {
105
+ return processedMessages.mutate(x => x.concat(newMessages));
106
+ }
107
+ return okAsync();
108
+ });
109
+ });
110
+ });
111
+ },
112
+ dispose() {
113
+ return session.dispose();
114
+ },
115
+ };
116
+ }
@@ -0,0 +1,4 @@
1
+ import type { StatementProver } from '@novasamatech/statement-store';
2
+ import type { UserSecretRepository } from './userSecretRepository.js';
3
+ import type { StoredUserSession } from './userSessionRepository.js';
4
+ export declare function createSsoStatementProver(userSession: StoredUserSession, userSecretRepository: UserSecretRepository): StatementProver;
@@ -0,0 +1,35 @@
1
+ import { getStatementSigner, statementCodec } from '@polkadot-api/sdk-statement';
2
+ import { err, errAsync, fromThrowable, ok, okAsync } from 'neverthrow';
3
+ import { compact } from 'scale-ts';
4
+ import { getSsPub, signWithSsSecret, verifyWithSsSecret } from '../crypto.js';
5
+ import { toError } from '../helpers/utils.js';
6
+ const verify = fromThrowable(verifyWithSsSecret, toError);
7
+ export function createSsoStatementProver(userSession, userSecretRepository) {
8
+ const secret = userSecretRepository
9
+ .read(userSession.id)
10
+ .andThen(secrets => (secrets ? ok(secrets) : err(new Error(`Secrets for session ${userSession.id} not found.`))))
11
+ .map(x => x.ssSecret);
12
+ return {
13
+ generateMessageProof(statement) {
14
+ return secret.map(secret => {
15
+ const signer = getStatementSigner(getSsPub(secret), 'sr25519', data => signWithSsSecret(secret, data));
16
+ return signer.sign(statement);
17
+ });
18
+ },
19
+ verifyMessageProof(statement) {
20
+ const { proof, ...unsigned } = statement;
21
+ if (!proof) {
22
+ // TODO should we pass check when proof is not presented?
23
+ return okAsync(true);
24
+ }
25
+ const encoded = statementCodec.enc(unsigned);
26
+ const compactLen = compact.enc(compact.dec(encoded)).length;
27
+ switch (proof.type) {
28
+ case 'sr25519':
29
+ return verify(encoded.slice(compactLen), proof.value.signature.asBytes(), proof.value.signer.asBytes()).asyncAndThen(x => okAsync(x));
30
+ default:
31
+ return errAsync(new Error(`Proof type ${proof.type} is not supported.`));
32
+ }
33
+ },
34
+ };
35
+ }
@@ -0,0 +1,17 @@
1
+ import type { StorageAdapter } from '@novasamatech/storage-adapter';
2
+ import type { ResultAsync } from 'neverthrow';
3
+ import type { CodecType } from 'scale-ts';
4
+ import type { EncrSecret, SsSecret } from '../crypto.js';
5
+ type StoredUserSecrets = CodecType<typeof StoredUserSecretsCodec>;
6
+ declare const StoredUserSecretsCodec: import("scale-ts").Codec<{
7
+ ssSecret: SsSecret;
8
+ encrSecret: EncrSecret;
9
+ entropy: Uint8Array<ArrayBufferLike>;
10
+ }>;
11
+ export type UserSecretRepository = ReturnType<typeof createUserSecretRepository>;
12
+ export declare function createUserSecretRepository(salt: string, storage: StorageAdapter): {
13
+ read(sessionId: string): ResultAsync<StoredUserSecrets | null, Error>;
14
+ write(sessionId: string, value: StoredUserSecrets): ResultAsync<void, Error>;
15
+ clear(sessionId: string): ResultAsync<void, Error>;
16
+ };
17
+ export {};
@@ -0,0 +1,45 @@
1
+ import { gcm } from '@noble/ciphers/aes.js';
2
+ import { blake2b } from '@noble/hashes/blake2.js';
3
+ import { fromHex, toHex } from '@polkadot-api/utils';
4
+ import { fromThrowable } from 'neverthrow';
5
+ import { Bytes, Struct } from 'scale-ts';
6
+ import { BrandedBytesCodec, stringToBytes } from '../crypto.js';
7
+ import { toError } from '../helpers/utils.js';
8
+ const StoredUserSecretsCodec = Struct({
9
+ ssSecret: BrandedBytesCodec(),
10
+ encrSecret: BrandedBytesCodec(),
11
+ entropy: Bytes(),
12
+ });
13
+ export function createUserSecretRepository(salt, storage) {
14
+ const baseKey = 'UserSecrets';
15
+ const encode = fromThrowable(StoredUserSecretsCodec.enc, toError);
16
+ const decode = fromThrowable((value) => (value ? StoredUserSecretsCodec.dec(value) : null), toError);
17
+ const encrypt = fromThrowable((value) => {
18
+ const aes = getAes(salt);
19
+ return toHex(aes.encrypt(value));
20
+ }, toError);
21
+ const decrypt = fromThrowable((value) => {
22
+ if (value === null) {
23
+ return null;
24
+ }
25
+ const aes = getAes(salt);
26
+ return aes.decrypt(fromHex(value));
27
+ }, toError);
28
+ return {
29
+ read(sessionId) {
30
+ return storage.read(createKey(baseKey, sessionId)).andThen(decrypt).andThen(decode);
31
+ },
32
+ write(sessionId, value) {
33
+ return encode(value)
34
+ .andThen(encrypt)
35
+ .asyncAndThen(value => storage.write(createKey(baseKey, sessionId), value));
36
+ },
37
+ clear(sessionId) {
38
+ return storage.clear(createKey(baseKey, sessionId));
39
+ },
40
+ };
41
+ }
42
+ const createKey = (key, context) => `${key}_${context}`;
43
+ function getAes(salt) {
44
+ return gcm(blake2b(stringToBytes(salt), { dkLen: 16 }), blake2b(stringToBytes('nonce'), { dkLen: 32 }));
45
+ }
@@ -0,0 +1,18 @@
1
+ import type { LocalSessionAccount, RemoteSessionAccount } from '@novasamatech/statement-store';
2
+ import type { StorageAdapter } from '@novasamatech/storage-adapter';
3
+ export type UserSessionRepository = ReturnType<typeof createUserSessionRepository>;
4
+ export type StoredUserSession = {
5
+ id: string;
6
+ localAccount: LocalSessionAccount;
7
+ remoteAccount: RemoteSessionAccount;
8
+ };
9
+ export declare function createStoredUserSession(localAccount: LocalSessionAccount, remoteAccount: RemoteSessionAccount): StoredUserSession;
10
+ export declare const createUserSessionRepository: (storage: StorageAdapter) => {
11
+ add(value: StoredUserSession): import("neverthrow").ResultAsync<StoredUserSession, Error>;
12
+ filter(fn: (value: StoredUserSession) => boolean): import("neverthrow").ResultAsync<StoredUserSession[], Error>;
13
+ mutate(fn: (value: StoredUserSession[]) => StoredUserSession[]): import("neverthrow").ResultAsync<StoredUserSession[], Error>;
14
+ read(): import("neverthrow").ResultAsync<StoredUserSession[], Error>;
15
+ write(value: StoredUserSession[]): import("neverthrow").ResultAsync<StoredUserSession[], Error> | import("neverthrow").ResultAsync<null, Error>;
16
+ clear(): import("neverthrow").ResultAsync<void, Error>;
17
+ subscribe(fn: (value: StoredUserSession[]) => void): VoidFunction;
18
+ };
@@ -0,0 +1,26 @@
1
+ import { LocalSessionAccountCodec, RemoteSessionAccountCodec } from '@novasamatech/statement-store';
2
+ import { fieldListView } from '@novasamatech/storage-adapter';
3
+ import { fromHex, toHex } from '@polkadot-api/utils';
4
+ import { nanoid } from 'nanoid';
5
+ import { Struct, Vector, str } from 'scale-ts';
6
+ const storedUserSessionCodec = Struct({
7
+ id: str,
8
+ localAccount: LocalSessionAccountCodec,
9
+ remoteAccount: RemoteSessionAccountCodec,
10
+ });
11
+ export function createStoredUserSession(localAccount, remoteAccount) {
12
+ return {
13
+ id: nanoid(12),
14
+ localAccount: localAccount,
15
+ remoteAccount: remoteAccount,
16
+ };
17
+ }
18
+ export const createUserSessionRepository = (storage) => {
19
+ const codec = Vector(storedUserSessionCodec);
20
+ return fieldListView({
21
+ storage,
22
+ key: 'SsoSessions',
23
+ from: x => codec.dec(fromHex(x)),
24
+ to: x => toHex(codec.enc(x)),
25
+ });
26
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@novasamatech/host-papp",
3
3
  "type": "module",
4
- "version": "0.5.0-8",
4
+ "version": "0.5.0",
5
5
  "description": "Polkadot app integration",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -21,20 +21,25 @@
21
21
  },
22
22
  "files": [
23
23
  "dist",
24
+ ".papi",
24
25
  "README.md"
25
26
  ],
26
27
  "dependencies": {
27
- "@polkadot-api/sdk-statement": "^0.2.0",
28
- "@polkadot-api/substrate-bindings": "^0.16.5",
29
- "@scure/sr25519": "1.0.0",
28
+ "@noble/ciphers": "2.1.1",
30
29
  "@noble/curves": "2.0.1",
31
30
  "@noble/hashes": "2.0.1",
32
- "@noble/ciphers": "2.1.1",
33
- "polkadot-api": "^1.23.1",
31
+ "@novasamatech/host-api": "0.5.0",
32
+ "@novasamatech/statement-store": "0.5.0",
33
+ "@novasamatech/storage-adapter": "0.5.0",
34
+ "@polkadot-api/substrate-bindings": "^0.16.5",
35
+ "@polkadot-labs/hdkd-helpers": "^0.0.27",
36
+ "@scure/sr25519": "1.0.0",
34
37
  "nanoevents": "9.1.0",
35
38
  "nanoid": "5.1.6",
36
- "neverthrow": "8.2.0",
37
- "scale-ts": "1.6.1"
39
+ "neverthrow": "^8.2.0",
40
+ "polkadot-api": "^1.23.2",
41
+ "scale-ts": "1.6.1",
42
+ "verifiablejs": "1.1.0"
38
43
  },
39
44
  "publishConfig": {
40
45
  "access": "public"
@@ -1,6 +0,0 @@
1
- import { ResultAsync } from 'neverthrow';
2
- import type { LazyClientAdapter } from '../lazyClient/types.js';
3
- import type { StorageAdapter } from '../storage/types.js';
4
- import type { Identity, IdentityAdapter } from './types.js';
5
- export declare function createCachedIdentityRequester(storage: StorageAdapter, getKey: (accountId: string) => string, request: (accounts: string[]) => ResultAsync<(Identity | null)[], Error>): (accounts: string[]) => ResultAsync<Record<string, Identity | null>, Error>;
6
- export declare function createIdentityRpcAdapter(lazyClient: LazyClientAdapter, storage: StorageAdapter): IdentityAdapter;
@@ -1,101 +0,0 @@
1
- import { Result, ResultAsync, err, errAsync, fromPromise, ok, okAsync } from 'neverthrow';
2
- import { AccountId } from 'polkadot-api';
3
- import { toError } from '../../helpers/utils.js';
4
- function zipWith(arrays, iteratee) {
5
- if (arrays.length === 0)
6
- return [];
7
- const minLength = Math.min(...arrays.map(arr => arr.length));
8
- const result = [];
9
- for (let i = 0; i < minLength; i++) {
10
- const values = arrays.map(arr => arr[i]);
11
- result.push(iteratee(values));
12
- }
13
- return result;
14
- }
15
- export function createCachedIdentityRequester(storage, getKey, request) {
16
- function readSingleCacheRecord(accountId) {
17
- return storage.read(getKey(accountId)).andThen(raw => {
18
- if (!raw) {
19
- return ok(null);
20
- }
21
- try {
22
- return ok(JSON.parse(raw));
23
- }
24
- catch (e) {
25
- return err(toError(e));
26
- }
27
- });
28
- }
29
- function writeSingleCacheRecord(accountId, identity) {
30
- if (identity === null) {
31
- return okAsync(undefined);
32
- }
33
- return storage.write(getKey(accountId), JSON.stringify(identity));
34
- }
35
- function readCache(accounts) {
36
- if (accounts.length === 0) {
37
- return okAsync({});
38
- }
39
- const identities = ResultAsync.combine(accounts.map(readSingleCacheRecord));
40
- return identities.map(identities => {
41
- return Object.fromEntries(identities.map((x, i) => {
42
- const accountId = accounts.at(i);
43
- if (!accountId) {
44
- throw new Error(`Identity not found`);
45
- }
46
- return [accountId, x];
47
- }));
48
- });
49
- }
50
- function writeCache(identities) {
51
- return ResultAsync.combine(Object.entries(identities).map(args => writeSingleCacheRecord(...args))).map(() => identities);
52
- }
53
- return (accounts) => {
54
- return readCache(accounts).andThen(existing => {
55
- const emptyIdentities = Object.entries(existing)
56
- .filter(([, identity]) => identity === null)
57
- .map(([accountId]) => accountId);
58
- if (emptyIdentities.length === 0) {
59
- return okAsync(existing);
60
- }
61
- return request(accounts)
62
- .map(response => Object.fromEntries(zipWith([accounts, response], x => x)))
63
- .andThen(writeCache)
64
- .map(fetched => ({
65
- ...existing,
66
- ...fetched,
67
- }));
68
- });
69
- };
70
- }
71
- export function createIdentityRpcAdapter(lazyClient, storage) {
72
- const requester = createCachedIdentityRequester(storage, (accountId) => `identity_${accountId}`, accounts => {
73
- const client = lazyClient.getClient();
74
- const unsafeApi = client.getUnsafeApi();
75
- const method = unsafeApi.query.Resources?.Consumers;
76
- if (!method) {
77
- return errAsync(new Error('Method Resources:Consumers not found'));
78
- }
79
- const results = fromPromise(method.getValues([accounts.map(accCodec.dec)]), toError);
80
- return results.andThen(results => {
81
- if (!results) {
82
- return ok(accounts.map(() => null));
83
- }
84
- return ok(zipWith([accounts, results], x => x).map(([accountId, raw]) => {
85
- if (!raw) {
86
- return null;
87
- }
88
- return {
89
- accountId: accountId,
90
- fullUsername: raw.full_username ? raw.full_username.asText() : null,
91
- liteUsername: raw.lite_username ? raw.lite_username.asText() : null,
92
- credibility: raw.credibility.type,
93
- };
94
- }));
95
- });
96
- });
97
- const accCodec = AccountId();
98
- return {
99
- readIdentities: requester,
100
- };
101
- }
@@ -1,10 +0,0 @@
1
- import type { ResultAsync } from 'neverthrow';
2
- export type Identity = {
3
- accountId: string;
4
- fullUsername: string | null;
5
- liteUsername: string;
6
- credibility: string;
7
- };
8
- export type IdentityAdapter = {
9
- readIdentities(accounts: string[]): ResultAsync<Record<string, Identity | null>, Error>;
10
- };
@@ -1,3 +0,0 @@
1
- import type { JsonRpcProvider } from '@polkadot-api/json-rpc-provider';
2
- import type { LazyClientAdapter } from './types.js';
3
- export declare const createPapiLazyClient: (provider: JsonRpcProvider) => LazyClientAdapter;
@@ -1,17 +0,0 @@
1
- import { createClient } from 'polkadot-api';
2
- export const createPapiLazyClient = (provider) => {
3
- let client = null;
4
- return {
5
- getClient() {
6
- if (!client) {
7
- client = createClient(provider);
8
- }
9
- return client;
10
- },
11
- disconnect() {
12
- if (client) {
13
- client.destroy();
14
- }
15
- },
16
- };
17
- };
@@ -1,5 +0,0 @@
1
- import type { PolkadotClient } from 'polkadot-api';
2
- export type LazyClientAdapter = {
3
- getClient(): PolkadotClient;
4
- disconnect(): void;
5
- };
@@ -1,3 +0,0 @@
1
- import type { LazyClientAdapter } from '../lazyClient/types.js';
2
- import type { StatementAdapter } from './types.js';
3
- export declare function createPapiStatementAdapter(lazyClient: LazyClientAdapter): StatementAdapter;
@@ -1,93 +0,0 @@
1
- import { createStatementSdk } from '@polkadot-api/sdk-statement';
2
- import { Binary } from '@polkadot-api/substrate-bindings';
3
- import { toHex } from '@polkadot-api/utils';
4
- import { fromPromise } from 'neverthrow';
5
- import { toError } from '../../helpers/utils.js';
6
- const POLLING_INTERVAL = 1000;
7
- function createKey(topics) {
8
- return topics.map(toHex).sort().join('');
9
- }
10
- export function createPapiStatementAdapter(lazyClient) {
11
- const sdk = createStatementSdk((method, params) => {
12
- const client = lazyClient.getClient();
13
- return client._request(method, params);
14
- });
15
- const pollings = new Map();
16
- const subscriptions = new Map();
17
- function addSubscription(key, subscription) {
18
- let subs = subscriptions.get(key);
19
- if (!subs) {
20
- subs = [];
21
- subscriptions.set(key, subs);
22
- }
23
- subs.push(subscription);
24
- return subs;
25
- }
26
- function removeSubscription(key, subscription) {
27
- let subs = subscriptions.get(key);
28
- if (!subs) {
29
- return [];
30
- }
31
- subs = subs.filter(x => x !== subscription);
32
- return subs;
33
- }
34
- const transportProvider = {
35
- queryStatements(topics, destination) {
36
- return fromPromise(sdk.getStatements({
37
- topics: topics.map(t => Binary.fromBytes(t)),
38
- dest: destination ? Binary.fromBytes(destination) : null,
39
- }), toError);
40
- },
41
- subscribeStatements(topics, callback) {
42
- const key = createKey(topics);
43
- const callbacks = addSubscription(key, callback);
44
- if (callbacks.length === 1) {
45
- const unsub = polling(POLLING_INTERVAL, () => transportProvider.queryStatements(topics), statements => {
46
- const list = subscriptions.get(key);
47
- if (list) {
48
- for (const fn of list) {
49
- fn(statements);
50
- }
51
- }
52
- });
53
- pollings.set(key, unsub);
54
- }
55
- return () => {
56
- const callbacks = removeSubscription(key, callback);
57
- if (callbacks.length === 0) {
58
- const stopPolling = pollings.get(key);
59
- stopPolling?.();
60
- pollings.delete(key);
61
- }
62
- };
63
- },
64
- submitStatement(statement) {
65
- return fromPromise(sdk.submit(statement), toError);
66
- },
67
- };
68
- return transportProvider;
69
- }
70
- function polling(interval, request, callback) {
71
- let active = true;
72
- let tm = null;
73
- function createCycle() {
74
- tm = setTimeout(() => {
75
- if (!active) {
76
- return;
77
- }
78
- request().match(data => {
79
- callback(data);
80
- createCycle();
81
- }, () => {
82
- createCycle();
83
- });
84
- }, interval);
85
- }
86
- createCycle();
87
- return () => {
88
- active = false;
89
- if (tm !== null) {
90
- clearTimeout(tm);
91
- }
92
- };
93
- }
@@ -1,9 +0,0 @@
1
- import type { SignedStatement, Statement } from '@polkadot-api/sdk-statement';
2
- import type { ResultAsync } from 'neverthrow';
3
- import type { Callback } from '../../types.js';
4
- export type StatementsCallback = Callback<Statement[]>;
5
- export type StatementAdapter = {
6
- queryStatements(topics: Uint8Array[], destination?: Uint8Array): ResultAsync<Statement[], Error>;
7
- subscribeStatements(topics: Uint8Array[], callback: StatementsCallback): VoidFunction;
8
- submitStatement(statement: SignedStatement): ResultAsync<void, Error>;
9
- };
@@ -1,2 +0,0 @@
1
- import type { StorageAdapter } from './types.js';
2
- export declare function createLocalStorageAdapter(prefix: string): StorageAdapter;