@novasamatech/host-papp 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/.papi/descriptors/dist/common-types.d.ts +8667 -0
- package/.papi/descriptors/dist/common.d.ts +1 -0
- package/.papi/descriptors/dist/descriptors-UUEW32EL.mjs +27 -0
- package/.papi/descriptors/dist/descriptors.d.ts +1 -0
- package/.papi/descriptors/dist/index.d.ts +10 -0
- package/.papi/descriptors/dist/index.js +237 -0
- package/.papi/descriptors/dist/index.mjs +148 -0
- package/.papi/descriptors/dist/metadataTypes-E4AQJDJR.mjs +6 -0
- package/.papi/descriptors/dist/metadataTypes.d.ts +2 -0
- package/.papi/descriptors/dist/people_lite.d.ts +7757 -0
- package/.papi/descriptors/dist/people_lite_metadata-EIVHV27X.mjs +6 -0
- package/.papi/descriptors/dist/people_lite_metadata.d.ts +2 -0
- package/.papi/descriptors/generated.json +1 -0
- package/.papi/descriptors/package.json +24 -0
- package/.papi/metadata/people_lite.scale +0 -0
- package/.papi/polkadot-api.json +15 -0
- package/dist/constants.d.ts +2 -2
- package/dist/constants.js +2 -2
- package/dist/crypto.d.ts +11 -5
- package/dist/crypto.js +47 -11
- package/dist/helpers/abortError.d.ts +0 -1
- package/dist/helpers/abortError.js +0 -3
- package/dist/identity/rpcAdapter.js +13 -5
- package/dist/identity/types.d.ts +3 -4
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1 -0
- package/dist/papp.js +3 -3
- package/dist/sso/auth/attestationService.d.ts +18 -0
- package/dist/sso/auth/attestationService.js +171 -0
- package/dist/sso/auth/impl.d.ts +36 -5
- package/dist/sso/auth/impl.js +94 -56
- package/dist/sso/auth/types.d.ts +15 -2
- package/dist/sso/sessionManager/scale/hex.d.ts +1 -0
- package/dist/sso/sessionManager/scale/hex.js +3 -0
- package/dist/sso/sessionManager/scale/remoteMessage.d.ts +30 -12
- package/dist/sso/sessionManager/scale/remoteMessage.js +10 -11
- package/dist/sso/sessionManager/scale/signPayloadRequest.d.ts +20 -0
- package/dist/sso/sessionManager/scale/signPayloadRequest.js +20 -0
- package/dist/sso/sessionManager/scale/signPayloadResponse.d.ts +14 -0
- package/dist/sso/sessionManager/scale/signPayloadResponse.js +10 -0
- package/dist/sso/sessionManager/userSession.d.ts +5 -7
- package/dist/sso/sessionManager/userSession.js +53 -12
- package/dist/sso/userSecretRepository.d.ts +1 -0
- package/dist/sso/userSecretRepository.js +2 -1
- package/dist/sso/userSessionRepository.js +0 -1
- package/package.json +12 -9
- 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/repository/ssoSessionRepository.d.ts +0 -22
- package/dist/sso/sessionManager/repository/ssoSessionRepository.js +0 -27
- 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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"cliVersion":"0.18.0","whitelist":null,"chains":{"people_lite":"0x50b8c73c2a3438eeddf39175bda7d60b"}}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.1.0-autogenerated.16231069504393689218",
|
|
3
|
+
"name": "@polkadot-api/descriptors",
|
|
4
|
+
"files": [
|
|
5
|
+
"dist"
|
|
6
|
+
],
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"module": "./dist/index.mjs",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"module": "./dist/index.mjs",
|
|
18
|
+
"browser": "./dist/index.mjs",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"polkadot-api": ">=1.21.0"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 0,
|
|
3
|
+
"descriptorPath": ".papi/descriptors",
|
|
4
|
+
"options": {
|
|
5
|
+
"noDescriptorsPackage": true
|
|
6
|
+
},
|
|
7
|
+
"entries": {
|
|
8
|
+
"people_lite": {
|
|
9
|
+
"wsUrl": "wss://pop3-testnet.parity-lab.parity.io:443/7912",
|
|
10
|
+
"metadata": ".papi/metadata/people_lite.scale",
|
|
11
|
+
"genesis": "0x41412e46623c200d788ab7ef1c507c43490fda2ca7b48c19f86ea9a46cf9caa8",
|
|
12
|
+
"codeHash": "0xe6895843ad86452552f9ec62c9793f457e04ab0c23ca1be6e8837c8b4b6d6be9"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const
|
|
2
|
-
export declare const
|
|
1
|
+
export declare const SS_UNSTABLE_STAGE_ENDPOINTS: string[];
|
|
2
|
+
export declare const SS_STABLE_STAGE_ENDPOINTS: string[];
|
package/dist/constants.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export const
|
|
2
|
-
export const
|
|
1
|
+
export const SS_UNSTABLE_STAGE_ENDPOINTS = ['wss://pop-testnet.parity-lab.parity.io:443/9910'];
|
|
2
|
+
export const SS_STABLE_STAGE_ENDPOINTS = [
|
|
3
3
|
'wss://pop3-testnet.parity-lab.parity.io:443/7911',
|
|
4
4
|
'wss://pop3-testnet.parity-lab.parity.io:443/7912',
|
|
5
5
|
];
|
package/dist/crypto.d.ts
CHANGED
|
@@ -11,13 +11,19 @@ export declare const SsPubKey: Codec<SsPublicKey>;
|
|
|
11
11
|
export declare const EncrPubKey: Codec<EncrPublicKey>;
|
|
12
12
|
export declare function stringToBytes(str: string): Uint8Array<ArrayBuffer>;
|
|
13
13
|
export declare function bytesToString(bytes: Uint8Array): string;
|
|
14
|
-
export declare
|
|
15
|
-
export declare function
|
|
16
|
-
export declare function createSsHardDerivation(secret: SsSecret, derivation: string | number): SsSecret;
|
|
14
|
+
export declare function createSsSecret(entropy: Uint8Array): SsSecret;
|
|
15
|
+
export declare function createSsDerivation(secret: SsSecret, derivation: string): SsSecret;
|
|
17
16
|
export declare function getSsPub(secret: SsSecret): SsPublicKey;
|
|
18
17
|
export declare function signWithSsSecret(secret: SsSecret, message: Uint8Array): Uint8Array<ArrayBufferLike>;
|
|
19
18
|
export declare function verifyWithSsSecret(message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean;
|
|
20
|
-
export
|
|
21
|
-
|
|
19
|
+
export type DerivedSr25519Account = {
|
|
20
|
+
secret: SsSecret;
|
|
21
|
+
publicKey: SsPublicKey;
|
|
22
|
+
entropy: Uint8Array;
|
|
23
|
+
sign(message: Uint8Array): Uint8Array;
|
|
24
|
+
verify(message: Uint8Array, signature: Uint8Array): boolean;
|
|
25
|
+
};
|
|
26
|
+
export declare function deriveSr25519Account(mnemonic: string, derivation: string): DerivedSr25519Account;
|
|
27
|
+
export declare function createEncrSecret(entropy: Uint8Array): EncrSecret;
|
|
22
28
|
export declare function getEncrPub(secret: EncrSecret): EncrPublicKey;
|
|
23
29
|
export declare function createSharedSecret(secret: EncrSecret, publicKey: Uint8Array): SharedSecret;
|
package/dist/crypto.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { p256 } from '@noble/curves/nist.js';
|
|
2
|
-
import {
|
|
2
|
+
import { entropyToMiniSecret, mnemonicToEntropy } from '@polkadot-labs/hdkd-helpers';
|
|
3
3
|
import { HDKD as sr25519HDKD, getPublicKey as sr25519GetPublicKey, secretFromSeed as sr25519SecretFromSeed, sign as sr25519Sign, verify as sr25519Verify, } from '@scure/sr25519';
|
|
4
|
-
import { Bytes, str
|
|
4
|
+
import { Bytes, str } from 'scale-ts';
|
|
5
5
|
// schemas
|
|
6
6
|
export function BrandedBytesCodec(length) {
|
|
7
7
|
return Bytes(length);
|
|
@@ -17,15 +17,37 @@ export function stringToBytes(str) {
|
|
|
17
17
|
export function bytesToString(bytes) {
|
|
18
18
|
return textDecoder.decode(bytes);
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
function parseDerivations(derivationsStr) {
|
|
21
|
+
const DERIVATION_RE = /(\/{1,2})([^/]+)/g;
|
|
22
|
+
const derivations = [];
|
|
23
|
+
for (const [, type, code] of derivationsStr.matchAll(DERIVATION_RE)) {
|
|
24
|
+
if (code) {
|
|
25
|
+
derivations.push([type === '//' ? 'hard' : 'soft', code]);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return derivations;
|
|
24
29
|
}
|
|
25
|
-
|
|
30
|
+
function createChainCode(derivation) {
|
|
26
31
|
const chainCode = new Uint8Array(32);
|
|
27
|
-
chainCode.set(
|
|
28
|
-
return
|
|
32
|
+
chainCode.set(str.enc(derivation));
|
|
33
|
+
return chainCode;
|
|
34
|
+
}
|
|
35
|
+
// statement store key pair
|
|
36
|
+
export function createSsSecret(entropy) {
|
|
37
|
+
const miniSecret = entropyToMiniSecret(entropy);
|
|
38
|
+
return sr25519SecretFromSeed(miniSecret);
|
|
39
|
+
}
|
|
40
|
+
export function createSsDerivation(secret, derivation) {
|
|
41
|
+
const derivations = parseDerivations(derivation);
|
|
42
|
+
return derivations.reduce((secret, [type, derivation]) => {
|
|
43
|
+
const chainCode = createChainCode(derivation);
|
|
44
|
+
switch (type) {
|
|
45
|
+
case 'hard':
|
|
46
|
+
return sr25519HDKD.secretHard(secret, chainCode);
|
|
47
|
+
case 'soft':
|
|
48
|
+
return sr25519HDKD.secretSoft(secret, chainCode);
|
|
49
|
+
}
|
|
50
|
+
}, secret);
|
|
29
51
|
}
|
|
30
52
|
export function getSsPub(secret) {
|
|
31
53
|
return sr25519GetPublicKey(secret);
|
|
@@ -36,9 +58,23 @@ export function signWithSsSecret(secret, message) {
|
|
|
36
58
|
export function verifyWithSsSecret(message, signature, publicKey) {
|
|
37
59
|
return sr25519Verify(message, signature, publicKey);
|
|
38
60
|
}
|
|
61
|
+
export function deriveSr25519Account(mnemonic, derivation) {
|
|
62
|
+
const entropy = mnemonicToEntropy(mnemonic);
|
|
63
|
+
const secret = createSsDerivation(createSsSecret(entropy), derivation);
|
|
64
|
+
const publicKey = getSsPub(secret);
|
|
65
|
+
return {
|
|
66
|
+
secret,
|
|
67
|
+
publicKey,
|
|
68
|
+
entropy,
|
|
69
|
+
sign: message => signWithSsSecret(secret, message),
|
|
70
|
+
verify: (message, signature) => verifyWithSsSecret(message, signature, publicKey),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
39
73
|
// encryption key pair
|
|
40
|
-
export
|
|
41
|
-
|
|
74
|
+
export function createEncrSecret(entropy) {
|
|
75
|
+
const miniSecret = entropyToMiniSecret(entropy);
|
|
76
|
+
const seed = new Uint8Array(48);
|
|
77
|
+
seed.set(miniSecret);
|
|
42
78
|
const { secretKey } = p256.keygen(seed);
|
|
43
79
|
return secretKey;
|
|
44
80
|
}
|
|
@@ -8,11 +8,11 @@ export function createIdentityRpcAdapter(lazyClient) {
|
|
|
8
8
|
readIdentities(accounts) {
|
|
9
9
|
const client = lazyClient.getClient();
|
|
10
10
|
const unsafeApi = client.getUnsafeApi();
|
|
11
|
-
const method = unsafeApi.query.Resources
|
|
11
|
+
const method = unsafeApi.query.Resources.Consumers;
|
|
12
12
|
if (!method) {
|
|
13
13
|
return errAsync(new Error('Method Resources.Consumers not found'));
|
|
14
14
|
}
|
|
15
|
-
const results = fromPromise(method.getValues(
|
|
15
|
+
const results = fromPromise(method.getValues(accounts.map(x => [accCodec.dec(x)])), toError);
|
|
16
16
|
return results.andThen(results => {
|
|
17
17
|
if (!results) {
|
|
18
18
|
return ok({});
|
|
@@ -21,14 +21,22 @@ export function createIdentityRpcAdapter(lazyClient) {
|
|
|
21
21
|
if (!raw) {
|
|
22
22
|
return [accountId, null];
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
const credibility = raw.credibility.type == 'Lite'
|
|
25
|
+
? {
|
|
26
|
+
type: 'Lite',
|
|
27
|
+
}
|
|
28
|
+
: {
|
|
29
|
+
type: 'Person',
|
|
30
|
+
alias: raw.credibility.value.alias.asHex(),
|
|
31
|
+
lastUpdate: raw.credibility.value.last_update.toString(),
|
|
32
|
+
};
|
|
25
33
|
return [
|
|
26
34
|
accountId,
|
|
27
35
|
{
|
|
28
36
|
accountId: accountId,
|
|
29
37
|
fullUsername: raw.full_username ? raw.full_username.asText() : null,
|
|
30
|
-
liteUsername: raw.lite_username
|
|
31
|
-
credibility
|
|
38
|
+
liteUsername: raw.lite_username.asText(),
|
|
39
|
+
credibility,
|
|
32
40
|
},
|
|
33
41
|
];
|
|
34
42
|
})));
|
package/dist/identity/types.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { ResultAsync } from 'neverthrow';
|
|
2
|
-
type Credibility = {
|
|
2
|
+
export type Credibility = {
|
|
3
3
|
type: 'Lite';
|
|
4
4
|
} | {
|
|
5
5
|
type: 'Person';
|
|
6
|
-
alias:
|
|
7
|
-
lastUpdate:
|
|
6
|
+
alias: `0x${string}`;
|
|
7
|
+
lastUpdate: string;
|
|
8
8
|
};
|
|
9
9
|
export type Identity = {
|
|
10
10
|
accountId: string;
|
|
@@ -19,4 +19,3 @@ export type IdentityRepository = {
|
|
|
19
19
|
getIdentity(accountId: string): ResultAsync<Identity | null, Error>;
|
|
20
20
|
getIdentities(accounts: string[]): ResultAsync<Record<string, Identity | null>, Error>;
|
|
21
21
|
};
|
|
22
|
-
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
export { SS_STABLE_STAGE_ENDPOINTS, SS_UNSTABLE_STAGE_ENDPOINTS } from './constants.js';
|
|
1
2
|
export type { PappAdapter } from './papp.js';
|
|
2
3
|
export { createPappAdapter } from './papp.js';
|
|
3
|
-
export type {
|
|
4
|
+
export type { AttestationStatus, PairingStatus } from './sso/auth/types.js';
|
|
4
5
|
export type { UserSession } from './sso/sessionManager/userSession.js';
|
|
5
6
|
export type { Identity } from './identity/types.js';
|
|
7
|
+
export type { SignPayloadRequest } from './sso/sessionManager/scale/signPayloadRequest.js';
|
|
8
|
+
export type { SignPayloadResponse } from './sso/sessionManager/scale/signPayloadResponse.js';
|
package/dist/index.js
CHANGED
package/dist/papp.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLazyClient, createPapiStatementStoreAdapter } from '@novasamatech/statement-store';
|
|
2
2
|
import { createLocalStorageAdapter } from '@novasamatech/storage-adapter';
|
|
3
3
|
import { getWsProvider } from '@polkadot-api/ws-provider';
|
|
4
|
-
import {
|
|
4
|
+
import { SS_STABLE_STAGE_ENDPOINTS } from './constants.js';
|
|
5
5
|
import { createIdentityRepository } from './identity/impl.js';
|
|
6
6
|
import { createIdentityRpcAdapter } from './identity/rpcAdapter.js';
|
|
7
7
|
import { createAuth } from './sso/auth/impl.js';
|
|
@@ -9,14 +9,14 @@ import { createSsoSessionManager } from './sso/sessionManager/impl.js';
|
|
|
9
9
|
import { createUserSecretRepository } from './sso/userSecretRepository.js';
|
|
10
10
|
import { createUserSessionRepository } from './sso/userSessionRepository.js';
|
|
11
11
|
export function createPappAdapter({ appId, metadata, adapters }) {
|
|
12
|
-
const lazyClient = adapters?.lazyClient ?? createLazyClient(getWsProvider(
|
|
12
|
+
const lazyClient = adapters?.lazyClient ?? createLazyClient(getWsProvider(SS_STABLE_STAGE_ENDPOINTS));
|
|
13
13
|
const statementStore = adapters?.statementStore ?? createPapiStatementStoreAdapter(lazyClient);
|
|
14
14
|
const identities = adapters?.identities ?? createIdentityRpcAdapter(lazyClient);
|
|
15
15
|
const storage = adapters?.storage ?? createLocalStorageAdapter(appId);
|
|
16
16
|
const ssoSessionRepository = createUserSessionRepository(storage);
|
|
17
17
|
const userSecretRepository = createUserSecretRepository(appId, storage);
|
|
18
18
|
return {
|
|
19
|
-
sso: createAuth({ metadata, statementStore, ssoSessionRepository, userSecretRepository }),
|
|
19
|
+
sso: createAuth({ metadata, statementStore, ssoSessionRepository, userSecretRepository, lazyClient }),
|
|
20
20
|
sessions: createSsoSessionManager({ storage, statementStore, ssoSessionRepository, userSecretRepository }),
|
|
21
21
|
identity: createIdentityRepository({ adapter: identities, storage }),
|
|
22
22
|
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { LazyClient } from '@novasamatech/statement-store';
|
|
2
|
+
import type { ResultAsync } from 'neverthrow';
|
|
3
|
+
import type { DerivedSr25519Account } from '../../crypto.js';
|
|
4
|
+
export declare function createAliceVerifier(): DerivedSr25519Account;
|
|
5
|
+
export declare const createAttestationService: (lazyClient: LazyClient) => {
|
|
6
|
+
claimUsername(): string;
|
|
7
|
+
grantVerifierAllowance(verifier: DerivedSr25519Account): ResultAsync<void, Error>;
|
|
8
|
+
getRingRfKey(candidate: DerivedSr25519Account): Uint8Array<ArrayBufferLike>;
|
|
9
|
+
getProofMessage(candidate: DerivedSr25519Account, ringVrfKey: Uint8Array): Uint8Array<ArrayBufferLike>;
|
|
10
|
+
deriveAttestationParams(username: string, candidate: DerivedSr25519Account, verifier: DerivedSr25519Account): ResultAsync<{
|
|
11
|
+
candidateSignature: Uint8Array<ArrayBufferLike>;
|
|
12
|
+
ringVrfKey: Uint8Array<ArrayBufferLike>;
|
|
13
|
+
proofOfOwnership: Uint8Array<ArrayBufferLike>;
|
|
14
|
+
identifierKey: import("../../crypto.js").EncrPublicKey;
|
|
15
|
+
consumerRegistrationSignature: Uint8Array<ArrayBufferLike>;
|
|
16
|
+
}, never>;
|
|
17
|
+
registerLitePerson(username: string, candidate: DerivedSr25519Account, verifier: DerivedSr25519Account): ResultAsync<void, Error>;
|
|
18
|
+
};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { createAccountId } from '@novasamatech/statement-store';
|
|
2
|
+
import { mergeUint8 } from '@polkadot-api/utils';
|
|
3
|
+
import { blake2b256 } from '@polkadot-labs/hdkd-helpers';
|
|
4
|
+
import { customAlphabet } from 'nanoid';
|
|
5
|
+
import { errAsync, fromAsyncThrowable, fromPromise, okAsync } from 'neverthrow';
|
|
6
|
+
import { AccountId, Binary } from 'polkadot-api';
|
|
7
|
+
import { getPolkadotSigner } from 'polkadot-api/signer';
|
|
8
|
+
import { Bytes, Option, Tuple, str } from 'scale-ts';
|
|
9
|
+
import { member_from_entropy, sign } from 'verifiablejs/bundler';
|
|
10
|
+
import { deriveSr25519Account, getEncrPub, stringToBytes } from '../../crypto.js';
|
|
11
|
+
import { toError } from '../../helpers/utils.js';
|
|
12
|
+
const accountId = AccountId();
|
|
13
|
+
export function createAliceVerifier() {
|
|
14
|
+
return deriveSr25519Account('bottom drive obey lake curtain smoke basket hold race lonely fit walk', '//Alice');
|
|
15
|
+
}
|
|
16
|
+
export const createAttestationService = (lazyClient) => {
|
|
17
|
+
const service = {
|
|
18
|
+
claimUsername() {
|
|
19
|
+
const nameSuffixFactory = customAlphabet('abcdefghijklmnopqrstuvwxyz', 4);
|
|
20
|
+
return `guest${nameSuffixFactory()}.${createNumericSuffix(4)}`;
|
|
21
|
+
},
|
|
22
|
+
grantVerifierAllowance(verifier) {
|
|
23
|
+
const client = lazyClient.getClient();
|
|
24
|
+
const api = client.getUnsafeApi();
|
|
25
|
+
const verifierAddress = accountId.dec(verifier.publicKey);
|
|
26
|
+
if (!api.query.PeopleLite || !api.query.PeopleLite.AttestationAllowance) {
|
|
27
|
+
return errAsync(new Error('Query PeopleLite.AttestationAllowance not found.'));
|
|
28
|
+
}
|
|
29
|
+
const verifierAllowance = fromPromise(api.query.PeopleLite.AttestationAllowance.getValue(verifierAddress), toError);
|
|
30
|
+
const getAllowance = fromAsyncThrowable(async () => {
|
|
31
|
+
const increaseAllowanceCall = api.tx.PeopleLite.increase_attestation_allowance({
|
|
32
|
+
account: verifierAddress,
|
|
33
|
+
count: 10,
|
|
34
|
+
});
|
|
35
|
+
const sudoCall = api.tx.Sudo.sudo({
|
|
36
|
+
call: increaseAllowanceCall.decodedCall,
|
|
37
|
+
});
|
|
38
|
+
return sudoCall.signAndSubmit(createPeopleSigner(verifier)).then(() => undefined);
|
|
39
|
+
}, toError);
|
|
40
|
+
return verifierAllowance.andThen(verifierAllowance => (verifierAllowance > 0 ? okAsync() : getAllowance()));
|
|
41
|
+
},
|
|
42
|
+
getRingRfKey(candidate) {
|
|
43
|
+
const verifiableEntropy = blake2b256(candidate.entropy);
|
|
44
|
+
return member_from_entropy(verifiableEntropy);
|
|
45
|
+
},
|
|
46
|
+
getProofMessage(candidate, ringVrfKey) {
|
|
47
|
+
return mergeUint8([stringToBytes('pop:people-lite:register using'), candidate.publicKey, ringVrfKey]);
|
|
48
|
+
},
|
|
49
|
+
deriveAttestationParams(username, candidate, verifier) {
|
|
50
|
+
const verifiableEntropy = blake2b256(candidate.entropy);
|
|
51
|
+
const ringVrfKey = service.getRingRfKey(candidate);
|
|
52
|
+
const identifierKey = getEncrPub(blake2b256(candidate.secret));
|
|
53
|
+
const message = service.getProofMessage(candidate, ringVrfKey);
|
|
54
|
+
// Extract username without the `.` separator and any following digits
|
|
55
|
+
// For lite person usernames like "ceainnhgidpj.39642086", we only use "ceainnhgidpj"
|
|
56
|
+
const usernameWithoutDigits = username.split('.')[0] ?? username;
|
|
57
|
+
const candidateSignature = candidate.sign(message);
|
|
58
|
+
const proofOfOwnership = sign(verifiableEntropy, message);
|
|
59
|
+
const ResourceSignatureCodec = Tuple(
|
|
60
|
+
// candidate PublicKey (32 bytes)
|
|
61
|
+
Bytes(32),
|
|
62
|
+
// verifier AccountId (32 bytes)
|
|
63
|
+
Bytes(32),
|
|
64
|
+
// identifierKey
|
|
65
|
+
Bytes(65),
|
|
66
|
+
// username without digits
|
|
67
|
+
str,
|
|
68
|
+
// reserved_username
|
|
69
|
+
Option(Bytes()));
|
|
70
|
+
const resourcesSignatureData = ResourceSignatureCodec.enc([
|
|
71
|
+
candidate.publicKey,
|
|
72
|
+
createAccountId(verifier.publicKey),
|
|
73
|
+
identifierKey,
|
|
74
|
+
usernameWithoutDigits,
|
|
75
|
+
undefined,
|
|
76
|
+
]);
|
|
77
|
+
const consumerRegistrationSignature = candidate.sign(resourcesSignatureData);
|
|
78
|
+
return okAsync({
|
|
79
|
+
candidateSignature: candidateSignature,
|
|
80
|
+
ringVrfKey,
|
|
81
|
+
proofOfOwnership,
|
|
82
|
+
identifierKey,
|
|
83
|
+
consumerRegistrationSignature,
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
registerLitePerson(username, candidate, verifier) {
|
|
87
|
+
const client = lazyClient.getClient();
|
|
88
|
+
const api = client.getUnsafeApi();
|
|
89
|
+
return service
|
|
90
|
+
.deriveAttestationParams(username, candidate, verifier)
|
|
91
|
+
.andThen(params => {
|
|
92
|
+
const attestCall = api.tx.PeopleLite.attest({
|
|
93
|
+
candidate: accountId.dec(candidate.publicKey),
|
|
94
|
+
candidate_signature: {
|
|
95
|
+
type: 'Sr25519',
|
|
96
|
+
value: Binary.fromBytes(params.candidateSignature),
|
|
97
|
+
},
|
|
98
|
+
ring_vrf_key: Binary.fromBytes(params.ringVrfKey),
|
|
99
|
+
proof_of_ownership: Binary.fromBytes(params.proofOfOwnership),
|
|
100
|
+
consumer_registration: {
|
|
101
|
+
signature: {
|
|
102
|
+
type: 'Sr25519',
|
|
103
|
+
value: Binary.fromBytes(params.consumerRegistrationSignature),
|
|
104
|
+
},
|
|
105
|
+
account: accountId.dec(candidate.publicKey),
|
|
106
|
+
identifier_key: Binary.fromBytes(params.identifierKey),
|
|
107
|
+
username: Binary.fromText(username),
|
|
108
|
+
reserved_username: undefined,
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
return fromPromise(new Promise((resolve, reject) => {
|
|
112
|
+
const subscription = attestCall.signSubmitAndWatch(createPeopleSigner(verifier)).subscribe({
|
|
113
|
+
next(event) {
|
|
114
|
+
if (event.type === 'finalized') {
|
|
115
|
+
// Check if transaction was successful
|
|
116
|
+
if (event.ok) {
|
|
117
|
+
subscription.unsubscribe();
|
|
118
|
+
resolve();
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// Extract error details
|
|
122
|
+
let errorMessage = 'Transaction failed';
|
|
123
|
+
if (event.dispatchError?.type === 'Module') {
|
|
124
|
+
const moduleError = event.dispatchError.value;
|
|
125
|
+
errorMessage = `${moduleError.type}.${moduleError.value?.type || 'Unknown'}`;
|
|
126
|
+
}
|
|
127
|
+
subscription.unsubscribe();
|
|
128
|
+
reject(errorMessage);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
error: reject,
|
|
133
|
+
});
|
|
134
|
+
}), toError).map(() => undefined);
|
|
135
|
+
})
|
|
136
|
+
.andTee(() => console.log(`Attestation for ${accountId.dec(candidate.publicKey)} successfully passed.`));
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
return service;
|
|
140
|
+
};
|
|
141
|
+
function createNumericSuffix(length) {
|
|
142
|
+
let suffix = '';
|
|
143
|
+
for (let i = 0; i < length; i++) {
|
|
144
|
+
suffix += (Math.random() * 9).toFixed();
|
|
145
|
+
}
|
|
146
|
+
return suffix;
|
|
147
|
+
}
|
|
148
|
+
function createPeopleSigner(verifier) {
|
|
149
|
+
const baseSigner = getPolkadotSigner(verifier.publicKey, 'Sr25519', verifier.sign);
|
|
150
|
+
return {
|
|
151
|
+
publicKey: baseSigner.publicKey,
|
|
152
|
+
signBytes: baseSigner.signBytes,
|
|
153
|
+
signTx: async (callData, signedExtensions, metadata, atBlockNumber, hasher) => {
|
|
154
|
+
// Add People chain custom signed extensions
|
|
155
|
+
const extensionsWithCustom = {
|
|
156
|
+
...signedExtensions,
|
|
157
|
+
VerifyMultiSignature: {
|
|
158
|
+
identifier: 'VerifyMultiSignature',
|
|
159
|
+
value: new Uint8Array([1]), // 1u8 = Option::Some with empty data
|
|
160
|
+
additionalSigned: new Uint8Array([]), // Empty additional data
|
|
161
|
+
},
|
|
162
|
+
AsPerson: {
|
|
163
|
+
identifier: 'AsPerson',
|
|
164
|
+
value: new Uint8Array([0]), // 0u8 = Option::None
|
|
165
|
+
additionalSigned: new Uint8Array([]), // Empty additional data
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
return baseSigner.signTx(callData, extensionsWithCustom, metadata, atBlockNumber, hasher);
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
package/dist/sso/auth/impl.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { StatementStoreAdapter } from '@novasamatech/statement-store';
|
|
1
|
+
import type { LazyClient, StatementStoreAdapter } from '@novasamatech/statement-store';
|
|
2
2
|
import { ResultAsync } from 'neverthrow';
|
|
3
3
|
import type { UserSecretRepository } from '../userSecretRepository.js';
|
|
4
4
|
import type { StoredUserSession, UserSessionRepository } from '../userSessionRepository.js';
|
|
@@ -8,18 +8,21 @@ type Params = {
|
|
|
8
8
|
statementStore: StatementStoreAdapter;
|
|
9
9
|
ssoSessionRepository: UserSessionRepository;
|
|
10
10
|
userSecretRepository: UserSecretRepository;
|
|
11
|
+
lazyClient: LazyClient;
|
|
11
12
|
};
|
|
12
|
-
export declare function createAuth({ metadata, statementStore, ssoSessionRepository, userSecretRepository }: Params): {
|
|
13
|
-
|
|
13
|
+
export declare function createAuth({ metadata, statementStore, ssoSessionRepository, userSecretRepository, lazyClient, }: Params): {
|
|
14
|
+
pairingStatus: {
|
|
14
15
|
read: () => {
|
|
15
16
|
step: "none";
|
|
16
17
|
} | {
|
|
17
18
|
step: "initial";
|
|
19
|
+
} | {
|
|
20
|
+
step: "attestation";
|
|
18
21
|
} | {
|
|
19
22
|
step: "pairing";
|
|
20
23
|
payload: string;
|
|
21
24
|
} | {
|
|
22
|
-
step: "
|
|
25
|
+
step: "pairingError";
|
|
23
26
|
message: string;
|
|
24
27
|
} | {
|
|
25
28
|
step: "finished";
|
|
@@ -29,11 +32,13 @@ export declare function createAuth({ metadata, statementStore, ssoSessionReposit
|
|
|
29
32
|
step: "none";
|
|
30
33
|
} | {
|
|
31
34
|
step: "initial";
|
|
35
|
+
} | {
|
|
36
|
+
step: "attestation";
|
|
32
37
|
} | {
|
|
33
38
|
step: "pairing";
|
|
34
39
|
payload: string;
|
|
35
40
|
} | {
|
|
36
|
-
step: "
|
|
41
|
+
step: "pairingError";
|
|
37
42
|
message: string;
|
|
38
43
|
} | {
|
|
39
44
|
step: "finished";
|
|
@@ -42,6 +47,32 @@ export declare function createAuth({ metadata, statementStore, ssoSessionReposit
|
|
|
42
47
|
onFirstSubscribe: (callback: VoidFunction) => import("nanoevents").Unsubscribe;
|
|
43
48
|
onLastUnsubscribe: (callback: VoidFunction) => import("nanoevents").Unsubscribe;
|
|
44
49
|
};
|
|
50
|
+
attestationStatus: {
|
|
51
|
+
read: () => {
|
|
52
|
+
step: "none";
|
|
53
|
+
} | {
|
|
54
|
+
step: "attestation";
|
|
55
|
+
username: string;
|
|
56
|
+
} | {
|
|
57
|
+
step: "attestationError";
|
|
58
|
+
message: string;
|
|
59
|
+
} | {
|
|
60
|
+
step: "finished";
|
|
61
|
+
};
|
|
62
|
+
subscribe: (fn: (value: {
|
|
63
|
+
step: "none";
|
|
64
|
+
} | {
|
|
65
|
+
step: "attestation";
|
|
66
|
+
username: string;
|
|
67
|
+
} | {
|
|
68
|
+
step: "attestationError";
|
|
69
|
+
message: string;
|
|
70
|
+
} | {
|
|
71
|
+
step: "finished";
|
|
72
|
+
}) => void) => () => void;
|
|
73
|
+
onFirstSubscribe: (callback: VoidFunction) => import("nanoevents").Unsubscribe;
|
|
74
|
+
onLastUnsubscribe: (callback: VoidFunction) => import("nanoevents").Unsubscribe;
|
|
75
|
+
};
|
|
45
76
|
authenticate(): ResultAsync<StoredUserSession | null, Error>;
|
|
46
77
|
abortAuthentication(): void;
|
|
47
78
|
};
|