@silencelaboratories/walletprovider-sdk 0.3.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -92
- package/dist/EOAauthentication.d.ts +14 -4
- package/dist/authentication.d.ts +35 -22
- package/dist/encoding.d.ts +1 -0
- package/dist/ephemeralAuthentication.d.ts +29 -6
- package/dist/index.cjs.js +6 -1
- package/dist/index.d.ts +24 -5
- package/dist/index.esm.js +6 -1
- package/dist/networkSigner.d.ts +31 -96
- package/dist/passkeyAuthentication.d.ts +3 -4
- package/dist/setupMessage.d.ts +70 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/validator.d.ts +4 -1
- package/dist/walletProviderServiceClient.d.ts +19 -8
- package/dist/walletProviderServiceClientInterface.d.ts +23 -7
- package/package.json +8 -6
package/README.md
CHANGED
|
@@ -1,104 +1,103 @@
|
|
|
1
1
|
# walletprovider-sdk
|
|
2
2
|
|
|
3
|
-
The
|
|
4
|
-
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
npm
|
|
3
|
+
The client library for Silent Network Wallet Provider Service.
|
|
4
|
+
|
|
5
|
+
- [Installing](#installing)
|
|
6
|
+
- [Quick start](#quick-start)
|
|
7
|
+
- [Documentation](#documentation)
|
|
8
|
+
- [Features](#features)
|
|
9
|
+
- [Overview](#overview)
|
|
10
|
+
- [Authentication](#authentication)
|
|
11
|
+
- [Keygen](#keygen)
|
|
12
|
+
- [Signing](#signing)
|
|
13
|
+
- [Development](#development)
|
|
14
|
+
- [Build the library](#build-the-library)
|
|
15
|
+
- [End to end tests](#end-to-end-tests)
|
|
16
|
+
- [Generate the documentation](#generate-the-documentation)
|
|
17
|
+
- [Lint the code](#lint-the-code)
|
|
18
|
+
|
|
19
|
+
# Installing
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
npm i @silencelaboratories/walletprovider-sdk
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
# Quick start
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Check the [demo](./demo/README.md) for a quick start guide.
|
|
28
28
|
|
|
29
|
-
#
|
|
29
|
+
# Documentation
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
For description of classes, interfaces, types, please refer to [documentation](./docs/walletprovider-sdk.md).
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
# Features
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
## The backend
|
|
35
|
+
- Authentication
|
|
36
|
+
- Keygen
|
|
37
|
+
- Signing
|
|
40
38
|
|
|
41
|
-
|
|
39
|
+
## Overview
|
|
42
40
|
|
|
43
|
-
|
|
41
|
+
The library provides API to authenticate, generate keys, and sign messages against the Silent Network. Before sending request for a distributed key or signature, users need to be authenticated to the Silent Network.
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
For description of classes, interfaces, types, please refer to [documentation](./docs/walletprovider-sdk.md).
|
|
43
|
+
Once authenticated, users register an ephemeral signing key pair and associate it with their identity. The ephemeral signing keys can later be used to authorize signing requests for duration of the session without the need for repeated user interaction, providing a seamless and secure authentication mechanism.
|
|
48
44
|
|
|
49
45
|
## Authentication
|
|
50
46
|
|
|
47
|
+
Users authenticate to Silent Network using 2 methods [Wallet-based](./docs/walletprovider-sdk.eoaauth.md) or [Passkey](./docs/walletprovider-sdk.passkeyauth.md).
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
Frontend can later use the ephemeral signing key pair to authorize **signing requests** for duration of the session without the need for repeated user interaction, providing a seamless and secure authentication mechanism.
|
|
49
|
+
- [Wallet-based](./docs/walletprovider-sdk.eoaauth.md) authenticate users using their digital wallet, it runs at the same time users start doing **keygen**.
|
|
55
50
|
|
|
56
|
-
|
|
57
|
-
- [EOAAuth](./docs/walletprovider-sdk.eoaauth.md) to authenticate the user **during keygen**. The `EOAAuth` object is created with the user's wallet address.
|
|
51
|
+
- [Passkey](./docs/walletprovider-sdk.passkeyauth.md) has 2 steps: **register** and **login**. The user registers a passkey with the network, then logs in with the passkey while starting the **keygen** process.
|
|
58
52
|
|
|
59
|
-
- [PasskeyAuth](./docs/walletprovider-sdk.passkeyauth.md) to authenticate the user **during keygen**. The `PasskeyAuth` object is created with the [PasskeyUser](./docs/walletprovider-sdk.passkeyuser.md), [RelyingPartyConfig](./docs/walletprovider-sdk.relyingpartyconfig.md).
|
|
60
53
|
|
|
61
|
-
|
|
54
|
+
The [ephemeral public claim](./docs/walletprovider-sdk.eoaauth.ephclaim.md) will be associated with both [EOAAuth](./docs/walletprovider-sdk.eoaauth.md) and [PasskeyAuth](./docs/walletprovider-sdk.passkeyauth.md) objects.
|
|
62
55
|
|
|
63
|
-
|
|
64
|
-
-
|
|
56
|
+
- Users will use [EphAuth](./docs/walletprovider-sdk.ephauth.md) to do non-interactive authenticate **during signing**.
|
|
57
|
+
- The library supports 2 signing algorithms for ephemeral signing keys: `secp256k1, ed25519`
|
|
65
58
|
|
|
66
59
|
## Keygen
|
|
67
60
|
|
|
68
|
-
|
|
69
|
-
The full working example is in the [demo](https://github.com/silence-laboratories/walletprovider-sdk/blob/a75d7a009fb4d3629d353d53f8c27c34190c9035/demo/src/routes/%2Bpage.svelte#L89).
|
|
61
|
+
The full working example is in the [demo](https://github.com/silence-laboratories/walletprovider-sdk/blob/main/demo/src/routes/%2Bpage.svelte#L172).
|
|
70
62
|
The core object to use is the [NetworkSigner](./docs/walletprovider-sdk.networksigner.md). It allows to generate keys and do signatures.
|
|
71
63
|
|
|
72
|
-
In order to create your keys, you need two other components. The [WalletProviderServiceClient](./docs/walletprovider-sdk.walletproviderserviceclient.md) that connects to the Backend part of the SDK, and the **
|
|
64
|
+
In order to create your keys, you need two other components. The [WalletProviderServiceClient](./docs/walletprovider-sdk.walletproviderserviceclient.md) that connects to the Backend part of the SDK, and the **authenticator module**.
|
|
73
65
|
|
|
74
66
|
### Authenticate with EOA wallet
|
|
75
67
|
We provide EOA authentication via [EOAAuth](./docs/walletprovider-sdk.eoaauth.md) module. Let's create the `NetworkSigner` with associated `EOAAuth` object.
|
|
76
68
|
|
|
77
69
|
```ts
|
|
70
|
+
const algSign = 'secp256k1'; // Signing algorithms of ephemeral key
|
|
78
71
|
// Generate ephemeral secret key esk
|
|
79
|
-
const sk = generateEphPrivateKey();
|
|
72
|
+
const sk = generateEphPrivateKey(algSign);
|
|
80
73
|
// Derive public part epk from esk
|
|
81
|
-
const ephPK = getEphPublicKey(sk);
|
|
74
|
+
const ephPK = getEphPublicKey(sk, algSign);
|
|
82
75
|
// Arbitrary ID to identify the ephemeral key
|
|
83
76
|
const ephId = uuidv4();
|
|
84
|
-
// Create
|
|
85
|
-
const
|
|
77
|
+
// Create ephemeral key claim instance based on the ephemeral key
|
|
78
|
+
const ephClaim = new EphKeyClaim(
|
|
79
|
+
ephId,
|
|
80
|
+
ephPK,
|
|
81
|
+
algSign,
|
|
82
|
+
// Lifetime of one hour
|
|
83
|
+
60 * 60,
|
|
84
|
+
);
|
|
86
85
|
|
|
87
86
|
// Create EOA authenticator, signature will include epk
|
|
88
87
|
const eoaAuth = new EOAAuth(
|
|
89
|
-
ephId,
|
|
90
88
|
accountsFromBrowserWallet[0],
|
|
91
89
|
new BrowserWallet(),
|
|
92
|
-
|
|
93
|
-
// Lifetime of one hour
|
|
94
|
-
60 * 60,
|
|
90
|
+
ephClaim
|
|
95
91
|
);
|
|
96
92
|
|
|
93
|
+
// Create a client that connects to the backend service
|
|
94
|
+
const wpClient = await createWalletProviderService(clusterConfig);
|
|
95
|
+
|
|
97
96
|
// Create a new signer instance
|
|
98
97
|
const sdk = new NetworkSigner(wpClient, threshold, partiesNumber, eoaAuth);
|
|
99
98
|
```
|
|
100
99
|
|
|
101
|
-
Now you can generate a key, using the [generateKey](./docs/walletprovider-sdk.networksigner.
|
|
100
|
+
Now you can generate a key, using the [generateKey](./docs/walletprovider-sdk.networksigner.generatekey.md) method. The method accepts optional permissions. No permissions means _allow all operations_.
|
|
102
101
|
|
|
103
102
|
```ts
|
|
104
103
|
const permissions = {
|
|
@@ -120,22 +119,52 @@ const permissions = {
|
|
|
120
119
|
let resp: KeygenResponse = await sdk.generateKey(JSON.stringify(permissions));
|
|
121
120
|
```
|
|
122
121
|
|
|
123
|
-
Calling this method will cause to the
|
|
122
|
+
Calling this method will cause to the Digital Wallet window to pop up, requesting the User to sign the request.
|
|
124
123
|
|
|
125
124
|
The returned [KeygenResponse](./docs/walletprovider-sdk.keygenresponse.md) contains `keyId` and `publicKey`. The `publicKey` is the public part of the key generated by Silent Network. Use the `keyId` in subsequent calls to sign.
|
|
126
125
|
|
|
127
|
-
The `
|
|
126
|
+
The ephemeral `sk` key can be later used in subsequent signgen requests for authenticating.
|
|
128
127
|
|
|
129
128
|
### Authenticate with Passkey
|
|
130
|
-
We provide Passkey
|
|
129
|
+
First, we need to register user passkey to the network. We provide Passkey register via [PasskeyRegister](./docs/walletprovider-sdk.passkeyregister.md) module.
|
|
130
|
+
```ts
|
|
131
|
+
const wpClient = await createWalletProviderService(clusterConfig);
|
|
132
|
+
const rpConfig: RelyingPartyConfig = {
|
|
133
|
+
rpId: 'localhost',
|
|
134
|
+
rpName: 'http://localhost:5173',
|
|
135
|
+
};
|
|
136
|
+
const userId = uuidv4();
|
|
137
|
+
const passkeyUser = {
|
|
138
|
+
id: userId,
|
|
139
|
+
displayName: 'Alice',
|
|
140
|
+
name: 'alice@gmail.com ' + userId, // For development purposes
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const passkeyAuth = new PasskeyRegister(rpConfig, passkeyUser);
|
|
144
|
+
// Create a new signer instance
|
|
145
|
+
const sdk = new NetworkSigner(wpClient, +threshold, +partiesNumber, passkeyAuth);
|
|
146
|
+
|
|
147
|
+
// Register a new passkey
|
|
148
|
+
let resp: RegisterPasskeyResponse = await sdk.registerPasskey();
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
We provide Passkey login authentication via [PasskeyAuth](./docs/walletprovider-sdk.passkeyauth.md) module. Let's create the `NetworkSigner` with associated `PasskeyAuth` object.
|
|
131
152
|
|
|
132
153
|
```ts
|
|
154
|
+
const algSign = 'secp256k1'; // Signing algorithms of ephemeral key
|
|
133
155
|
// Generate ephemeral secret key esk
|
|
134
|
-
const sk = generateEphPrivateKey();
|
|
156
|
+
const sk = generateEphPrivateKey(algSign);
|
|
135
157
|
// Derive public part epk from esk
|
|
136
|
-
const ephPK = getEphPublicKey(sk);
|
|
158
|
+
const ephPK = getEphPublicKey(sk, algSign);
|
|
137
159
|
// Arbitrary ID to identify the ephemeral key
|
|
138
160
|
const ephId = uuidv4();
|
|
161
|
+
// Create ephemeral key claim instance based on the ephemeral key
|
|
162
|
+
const ephClaim = new EphKeyClaim(
|
|
163
|
+
ephId,
|
|
164
|
+
ephPK,
|
|
165
|
+
// Lifetime of one hour
|
|
166
|
+
60 * 60,
|
|
167
|
+
);
|
|
139
168
|
// Create a client that connects to the backend service
|
|
140
169
|
const wpClient = await createWalletProviderService(clusterConfig);
|
|
141
170
|
// Here we configure the relying party for local development
|
|
@@ -143,50 +172,40 @@ const rpConfig: RelyingPartyConfig = {
|
|
|
143
172
|
rpId: 'localhost',
|
|
144
173
|
rpName: 'http://localhost:5173',
|
|
145
174
|
};
|
|
146
|
-
// Information about the owner of the passkey
|
|
147
|
-
const passkeyUser: PasskeyUser = {
|
|
148
|
-
id: userId,
|
|
149
|
-
displayName: 'Alice',
|
|
150
|
-
name: 'alice@gmail.com ' + userId, // For development purposes
|
|
151
|
-
};
|
|
152
175
|
|
|
153
176
|
// Get passkey credential id from your storage
|
|
154
177
|
const credentialId = getPasskeyCredentialId();
|
|
155
|
-
// Create
|
|
178
|
+
// Create Passkey authenticator, signature will include epk
|
|
156
179
|
const passkeyAuth = new PasskeyAuth(
|
|
157
180
|
rpConfig,
|
|
158
|
-
|
|
159
|
-
ephId,
|
|
160
|
-
ephPK,
|
|
161
|
-
// Lifetime of one hour
|
|
162
|
-
60 * 60,
|
|
163
|
-
// If credentialId is null, we will do passkey register, otherwise, we will do passkey auth/login
|
|
181
|
+
// We will do passkey auth/login with the provided credentialId
|
|
164
182
|
credentialId,
|
|
183
|
+
ephClaim,
|
|
165
184
|
);
|
|
166
185
|
|
|
167
186
|
// Create a new signer instance
|
|
168
187
|
const sdk = new NetworkSigner(wpClient, threshold, partiesNumber, passkeyAuth);
|
|
169
188
|
```
|
|
170
189
|
|
|
171
|
-
Now you can generate a key like in the EOA example by calling the [generateKey](./docs/walletprovider-sdk.networksigner.
|
|
190
|
+
Now you can generate a key like in the EOA example by calling the [generateKey](./docs/walletprovider-sdk.networksigner.generatekey.md) method.
|
|
172
191
|
|
|
173
|
-
Calling this method will prompt the
|
|
192
|
+
Calling this method will prompt the device to request [Passkey User Verification](https://web.dev/articles/webauthn-user-verification). Once user verification is done, the [KeygenResponse](./docs/walletprovider-sdk.keygenresponse.md) is returned.
|
|
174
193
|
|
|
175
|
-
The `
|
|
194
|
+
The `sk` key can be later used in subsequent signgen requests.
|
|
176
195
|
|
|
177
196
|
## Signing
|
|
178
197
|
|
|
179
|
-
The full signing example is [here](https://github.com/silence-laboratories/walletprovider-sdk/blob/
|
|
198
|
+
The full signing example is [here](https://github.com/silence-laboratories/walletprovider-sdk/blob/main/demo/src/routes/%2Bpage.svelte#L228).
|
|
180
199
|
|
|
181
|
-
|
|
200
|
+
The workflow is similar to the keygen process. The core objects to use are the [NetworkSigner](./docs/walletprovider-sdk.networksigner.md), WalletProviderServiceClient, and the [ephemeral authenticator module](./docs/walletprovider-sdk.ephauth.md).
|
|
182
201
|
```ts
|
|
183
|
-
const authModule = new EphAuth(
|
|
202
|
+
const authModule = new EphAuth(selectedEphId, ephSK, selectedEphSignAlg);
|
|
184
203
|
// Create a new signer instance
|
|
185
204
|
const sdk = new NetworkSigner(wpClient, threshold, partiesNumber, authModule);
|
|
186
205
|
```
|
|
187
206
|
|
|
188
207
|
|
|
189
|
-
Use the [NetworkSigner.signMessage](./docs/walletprovider-sdk.networksigner.
|
|
208
|
+
Use the [NetworkSigner.signMessage](./docs/walletprovider-sdk.networksigner.signMessage.md) method in order to generate a signature.
|
|
190
209
|
|
|
191
210
|
```ts
|
|
192
211
|
let signMessage = JSON.stringify({
|
|
@@ -215,16 +234,12 @@ let resp = await sdk.signMessage(selectedKeyId, signMessage);
|
|
|
215
234
|
|
|
216
235
|
The [SignResponse](./docs/walletprovider-sdk.signresponse.md) contains the signature `sign` and the recovery ID `recid`.
|
|
217
236
|
|
|
237
|
+
# Development
|
|
218
238
|
|
|
219
|
-
##
|
|
220
|
-
|
|
221
|
-
```bash
|
|
222
|
-
npm install
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
## Build
|
|
239
|
+
## Build the library
|
|
226
240
|
|
|
227
241
|
```bash
|
|
242
|
+
npm i
|
|
228
243
|
npm run build
|
|
229
244
|
```
|
|
230
245
|
|
|
@@ -233,14 +248,14 @@ The output will be in the `dist` folder.
|
|
|
233
248
|
## End to end tests
|
|
234
249
|
Please refer to [README.md](./e2e-tests/README.md) for instructions how to execute them.
|
|
235
250
|
|
|
236
|
-
##
|
|
251
|
+
## Generate the documentation
|
|
237
252
|
|
|
238
253
|
```bash
|
|
239
|
-
npm run
|
|
254
|
+
npm run docs
|
|
240
255
|
```
|
|
241
256
|
|
|
242
|
-
##
|
|
257
|
+
## Lint the code
|
|
243
258
|
|
|
244
259
|
```bash
|
|
245
|
-
|
|
260
|
+
./local_ci.sh
|
|
246
261
|
```
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/** Externally Owned Account (EOA) atuhentication. Uses secret key stored on a wallet to sign requests.
|
|
2
2
|
* The requests are presented to the user in a readable form by using TypedData (EIP712).
|
|
3
3
|
*/
|
|
4
|
-
import { KeygenSetupOpts } from './
|
|
4
|
+
import { MetadataSetupOpts, KeygenSetupOpts } from './setupMessage';
|
|
5
5
|
import { type UserAuthentication } from './authentication';
|
|
6
6
|
import { type TypedDataDomain } from 'viem';
|
|
7
|
-
import {
|
|
7
|
+
import { EphKeyClaim } from './ephemeralAuthentication';
|
|
8
8
|
export type FieldDefinition = {
|
|
9
9
|
name: string;
|
|
10
10
|
type: string;
|
|
@@ -45,13 +45,23 @@ export interface IBrowserWallet {
|
|
|
45
45
|
*/
|
|
46
46
|
signTypedData<T>(from: string, request: TypedData<T>): Promise<unknown>;
|
|
47
47
|
}
|
|
48
|
+
type RequestToSign<T> = {
|
|
49
|
+
setup: T;
|
|
50
|
+
challenge: string;
|
|
51
|
+
};
|
|
52
|
+
export declare const EIP712SilentShardAuthenticationDomain: {
|
|
53
|
+
name: string;
|
|
54
|
+
version: string;
|
|
55
|
+
};
|
|
56
|
+
export declare function createTypedRequest(setup: KeygenSetupOpts | MetadataSetupOpts, aggregated_challenge: string, ephClaim: EphKeyClaim): TypedData<RequestToSign<KeygenSetupOpts | MetadataSetupOpts>>;
|
|
48
57
|
/** Present the request to the User using wallet UI, and ask for sign.
|
|
49
58
|
* The signature is the authorization for keygen operation
|
|
50
59
|
*/
|
|
51
60
|
export declare function authenticateUsingEOA({ setup, eoa, challenge, browserWallet, ephClaim, }: {
|
|
52
|
-
setup: KeygenSetupOpts;
|
|
61
|
+
setup: KeygenSetupOpts | MetadataSetupOpts;
|
|
53
62
|
eoa: string;
|
|
54
63
|
challenge: string;
|
|
55
64
|
browserWallet: IBrowserWallet;
|
|
56
|
-
ephClaim:
|
|
65
|
+
ephClaim: EphKeyClaim;
|
|
57
66
|
}): Promise<UserAuthentication>;
|
|
67
|
+
export {};
|
package/dist/authentication.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MetadataSetupOpts, KeygenSetupOpts, SignSetupOpts } from './setupMessage';
|
|
2
2
|
import { IBrowserWallet } from './EOAauthentication';
|
|
3
3
|
import { PasskeyUser, RelyingPartyConfig } from './passkeyAuthentication';
|
|
4
|
-
import {
|
|
4
|
+
import { EphKeyClaim, SignAlgorithm } from './ephemeralAuthentication';
|
|
5
5
|
/** Type of the request authentication
|
|
6
6
|
* @alpha
|
|
7
7
|
*/
|
|
@@ -16,12 +16,12 @@ export type UserAuthentication = {
|
|
|
16
16
|
};
|
|
17
17
|
export interface AuthModule {
|
|
18
18
|
authenticate({ setup, challenge, }: {
|
|
19
|
-
setup: KeygenSetupOpts | SignSetupOpts |
|
|
19
|
+
setup: KeygenSetupOpts | SignSetupOpts | MetadataSetupOpts;
|
|
20
20
|
challenge: string;
|
|
21
21
|
}): Promise<UserAuthentication>;
|
|
22
22
|
}
|
|
23
23
|
export interface DkgAuthModule extends AuthModule {
|
|
24
|
-
get ephClaim():
|
|
24
|
+
get ephClaim(): EphKeyClaim;
|
|
25
25
|
}
|
|
26
26
|
/** The `EOAAuth` implementing Externally Owned Account authentication.
|
|
27
27
|
* @alpha
|
|
@@ -32,16 +32,14 @@ export declare class EOAAuth implements DkgAuthModule {
|
|
|
32
32
|
/** the ETH address that is used to do EOA authentication */
|
|
33
33
|
private eoa;
|
|
34
34
|
/** Ephemeral key claim */
|
|
35
|
-
ephClaim:
|
|
35
|
+
ephClaim: EphKeyClaim;
|
|
36
36
|
/**
|
|
37
37
|
*
|
|
38
|
-
* @param ephId - Ephemeral key ID
|
|
39
38
|
* @param eoa - Ethereum address
|
|
40
39
|
* @param browserWallet - Interface to the wallet provider, like MetaMask, that is used to sign the requests
|
|
41
|
-
* @param
|
|
42
|
-
* @param lifetime - Lifetime of the ephemeral key. Default is 1 hour
|
|
40
|
+
* @param ephClaim - EphKeyClaim instance
|
|
43
41
|
*/
|
|
44
|
-
constructor(
|
|
42
|
+
constructor(eoa: string, browserWallet: IBrowserWallet, ephClaim: EphKeyClaim);
|
|
45
43
|
private validateInputs;
|
|
46
44
|
/**
|
|
47
45
|
* Prepares a message to present on the Browser Wallet window and requests to sign it.
|
|
@@ -50,8 +48,8 @@ export declare class EOAAuth implements DkgAuthModule {
|
|
|
50
48
|
*
|
|
51
49
|
* @public
|
|
52
50
|
*/
|
|
53
|
-
authenticate({ setup, challenge }: {
|
|
54
|
-
setup: KeygenSetupOpts;
|
|
51
|
+
authenticate({ setup, challenge, }: {
|
|
52
|
+
setup: KeygenSetupOpts | MetadataSetupOpts;
|
|
55
53
|
challenge: string;
|
|
56
54
|
}): Promise<UserAuthentication>;
|
|
57
55
|
}
|
|
@@ -70,8 +68,9 @@ export declare class EphAuth implements AuthModule {
|
|
|
70
68
|
*
|
|
71
69
|
* @param ephId - Ephemeral key ID
|
|
72
70
|
* @param ephSK - Ephemeral secret key
|
|
71
|
+
* @param signAlg - Signature algorithm
|
|
73
72
|
*/
|
|
74
|
-
constructor(ephId: string, ephSK: Uint8Array);
|
|
73
|
+
constructor(ephId: string, ephSK: Uint8Array, signAlg: SignAlgorithm);
|
|
75
74
|
/**
|
|
76
75
|
* Prepares a message to present on the Browser Wallet window and requests to sign it.
|
|
77
76
|
* @param setup - Signgen setup options
|
|
@@ -79,8 +78,8 @@ export declare class EphAuth implements AuthModule {
|
|
|
79
78
|
*
|
|
80
79
|
* @public
|
|
81
80
|
*/
|
|
82
|
-
authenticate({ setup, challenge }: {
|
|
83
|
-
setup: SignSetupOpts;
|
|
81
|
+
authenticate({ setup, challenge, }: {
|
|
82
|
+
setup: SignSetupOpts | MetadataSetupOpts;
|
|
84
83
|
challenge: string;
|
|
85
84
|
}): Promise<UserAuthentication>;
|
|
86
85
|
}
|
|
@@ -92,22 +91,36 @@ export declare class PasskeyAuth implements DkgAuthModule {
|
|
|
92
91
|
private rpConfig;
|
|
93
92
|
/** ID of the acceptable credential by user. App proves that user has passkey credential by passing the value of this field */
|
|
94
93
|
private allowCredentialId;
|
|
94
|
+
/** Ephemeral key claim */
|
|
95
|
+
ephClaim: EphKeyClaim;
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
* @param rpConfig - Passkey relying party configuration. Read more: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions#rp
|
|
99
|
+
* @param allowCredentialId - ID of the acceptable credential by user. App proves that user has passkey credential by passing the value of this field
|
|
100
|
+
* @param ephClaim - EphKeyClaim instance
|
|
101
|
+
*/
|
|
102
|
+
constructor(rpConfig: RelyingPartyConfig, allowCredentialId: string, ephClaim: EphKeyClaim);
|
|
103
|
+
authenticate({ setup, challenge, }: {
|
|
104
|
+
setup: KeygenSetupOpts | MetadataSetupOpts;
|
|
105
|
+
challenge: string;
|
|
106
|
+
}): Promise<UserAuthentication>;
|
|
107
|
+
}
|
|
108
|
+
/** The `AuthModule` implementing Passkey register.
|
|
109
|
+
* @alpha
|
|
110
|
+
*/
|
|
111
|
+
export declare class PasskeyRegister implements AuthModule {
|
|
112
|
+
/** Replying party object. Read more: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions#rp */
|
|
113
|
+
private rpConfig;
|
|
95
114
|
/** Passkey user information, only requires while registering. Read more: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions#user */
|
|
96
115
|
private user;
|
|
97
|
-
/** Ephemeral key claim */
|
|
98
|
-
ephClaim: EphClaim;
|
|
99
116
|
/**
|
|
100
117
|
*
|
|
101
118
|
* @param rpConfig - Passkey relying party configuration. Read more: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions#rp
|
|
102
119
|
* @param user - Passkey user information, only requires while registering. Read more: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions#user
|
|
103
|
-
* @param allowCredentialId - ID of the acceptable credential by user. App proves that user has passkey credential by passing the value of this field
|
|
104
|
-
* @param ephId - Ephemeral key ID
|
|
105
|
-
* @param ephPK - Ephemeral public key
|
|
106
|
-
* @param lifetime - Lifetime of the ephemeral key. Default is 1 hour
|
|
107
120
|
*/
|
|
108
|
-
constructor(rpConfig: RelyingPartyConfig, user: PasskeyUser
|
|
121
|
+
constructor(rpConfig: RelyingPartyConfig, user: PasskeyUser);
|
|
109
122
|
authenticate({ setup, challenge, }: {
|
|
110
|
-
setup:
|
|
123
|
+
setup: MetadataSetupOpts;
|
|
111
124
|
challenge: string;
|
|
112
125
|
}): Promise<UserAuthentication>;
|
|
113
126
|
}
|
package/dist/encoding.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export declare const decodeBase64: (b64: string) => Uint8Array;
|
|
2
2
|
export declare const encodeBase64: (b: Uint8Array) => string;
|
|
3
3
|
export declare const arrayBufferToBase64Url: (a: ArrayBuffer) => string;
|
|
4
|
+
export declare const calculateFinalChallenge: (setupOpts: string) => string;
|
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
import { UserAuthentication } from './authentication';
|
|
2
|
-
import { SignSetupOpts } from './
|
|
3
|
-
|
|
2
|
+
import { SignSetupOpts } from './setupMessage';
|
|
3
|
+
/**
|
|
4
|
+
* Supported signature algorithms for ephemeral key
|
|
5
|
+
* @alpha
|
|
6
|
+
*/
|
|
7
|
+
export type SignAlgorithm = 'ed25519' | 'secp256k1';
|
|
8
|
+
/** The `EphKeyClaim` object represents the public claim of the ephemeral key.
|
|
9
|
+
* @alpha
|
|
10
|
+
*/
|
|
11
|
+
export declare class EphKeyClaim {
|
|
4
12
|
ephId: string;
|
|
5
13
|
ephPK: string;
|
|
14
|
+
signAlg: SignAlgorithm;
|
|
6
15
|
expiry: number;
|
|
7
|
-
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* @param ephId - Ephemeral key ID
|
|
19
|
+
* @param ephPK - Ephemeral public key
|
|
20
|
+
* @param signAlg - Signature algorithm.
|
|
21
|
+
* @param lifetime - Lifetime of the ephemeral key. Default is 1 hour
|
|
22
|
+
*/
|
|
23
|
+
constructor(ephId: string, ephPK: Uint8Array, signAlg: SignAlgorithm, lifetime?: number);
|
|
8
24
|
private validateInputs;
|
|
9
25
|
toJSON(): string;
|
|
10
26
|
}
|
|
@@ -15,7 +31,14 @@ export declare function authenticateUsingEphKey({ setup, challenge, ephSK, ephCl
|
|
|
15
31
|
setup: SignSetupOpts;
|
|
16
32
|
challenge: string;
|
|
17
33
|
ephSK: Uint8Array;
|
|
18
|
-
ephClaim:
|
|
34
|
+
ephClaim: EphKeyClaim;
|
|
19
35
|
}): Promise<UserAuthentication>;
|
|
20
|
-
export declare function
|
|
21
|
-
|
|
36
|
+
export declare function genHexSignature(msg: Uint8Array, ephSK: Uint8Array, signAlg: SignAlgorithm): Promise<string>;
|
|
37
|
+
/** Generate Ephemeral `privateKey`
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
export declare function generateEphPrivateKey(algSign: SignAlgorithm): Uint8Array;
|
|
41
|
+
/** Derive Ephemeral `publicKey` from `privateKey` returned from `generateEphPrivateKey`
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
export declare function getEphPublicKey(ephSK: Uint8Array, algSign: SignAlgorithm): Uint8Array;
|
package/dist/index.cjs.js
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
"use strict";var S=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var Y=(n,e,t)=>e in n?S(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var X=(n,e)=>{for(var t in e)S(n,t,{get:e[t],enumerable:!0})},Z=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of G(e))!z.call(n,i)&&i!==t&&S(n,i,{get:()=>e[i],enumerable:!(r=Q(e,i))||r.enumerable});return n};var j=n=>Z(S({},"__esModule",{value:!0}),n);var s=(n,e,t)=>Y(n,typeof e!="symbol"?e+"":e,t);var se={};X(se,{EOAAuth:()=>I,EphAuth:()=>E,NetworkSigner:()=>C,PasskeyAuth:()=>K,WalletProviderServiceClient:()=>A,computeAddress:()=>V,generateEphPrivateKey:()=>q,getEphPublicKey:()=>B});module.exports=j(se);var U=require("js-base64");var R=n=>btoa(String.fromCodePoint.apply(null,Array.from(n))),c=n=>U.Base64.fromUint8Array(new Uint8Array(n),!0);var h=(n,e)=>{u(typeof e!="string",`${n} must be string`),u((e==null?void 0:e.trim().length)===0,`${n} cannot be empty`)},w=n=>{u(!(n instanceof Uint8Array),"key must be an Uint8Array"),u(n.length!==32,"ed25519: key length must be 32 bytes")},u=(n,e)=>{if(n)throw new Error(e)};var A=class{constructor(e){s(this,"walletProviderId");s(this,"walletProviderUrl");s(this,"passkeyCredentialId");this.walletProviderId=e.walletProviderId,this.walletProviderUrl=e.walletProviderUrl}getWalletId(){return this.walletProviderId}async startKeygen({setup:e,authModule:t}){return this.connect(e,t).then(r=>{var p,l;let i=r.split(":");u(i.length!==2,"Invalid keygen response from network");let a=(p=i[0])==null?void 0:p.split("=")[1];return{publicKey:(l=i[1])==null?void 0:l.split("=")[1],keyId:a,passkeyCredentialId:this.passkeyCredentialId}})}async startSigngen({setup:e,authModule:t}){return this.connect(e,t).then(r=>{var p,l;let i=r.split(":");u(i.length!==2,"Invalid signgen response from network");let a=(p=i[0])==null?void 0:p.split("=")[1],o=(l=i[1])==null?void 0:l.split("=")[1];if(a===void 0||o===void 0)throw new Error("Invalid signgen response from network");return{sign:a,recid:parseInt(o)}})}async addEphemeralKey({setup:e,authModule:t}){return this.connect(e,t).then(r=>({status:r}))}connect(e,t){return new Promise((r,i)=>{let a=0,o=e.queryPath;o==="signgen"&&(e.message=R(new TextEncoder().encode(e.message)));let p=new WebSocket(`${this.walletProviderUrl}/${o}`);p.addEventListener("open",l=>{switch(console.debug(`Connection opened in state ${a} with event ${JSON.stringify(l,void 0," ")}`),a){case 0:a=1,p.send(JSON.stringify(e));break;case 1:case 2:a=3,i("Incorrect protocol state");break;case 3:break}}),p.addEventListener("message",async l=>{switch(console.debug(`Connection message in state ${a} with event ${JSON.stringify(l,void 0," ")}`),a){case 0:a=3,i("Incorrect protocol state");break;case 1:{a=2;try{let d=await t.authenticate({setup:e,challenge:l.data});d.credentials.method==="passkey"&&(this.passkeyCredentialId=d.credentials.id),p.send(JSON.stringify(d))}catch(d){i(d)}break}case 2:a=3,p.close(),r(l.data);break;case 3:break}}),p.addEventListener("error",l=>{console.debug(`Connection error in state ${a} with event ${JSON.stringify(l,void 0," ")}`),a!=3&&(a=3,i("Incorrect protocol state"))}),p.addEventListener("close",l=>{console.debug(`Connection closed in state ${a} with event ${JSON.stringify(l,void 0," ")}`),a!=3&&(a=3,i("Incorrect protocol state"))})})}};var ee=1,T=2,te=3,M=[{name:"tag",type:"uint16"},{name:"value",type:"string"}],g=class{constructor({t:e,n:t,key_label:r,permissions:i}){s(this,"t");s(this,"n");s(this,"key_label");s(this,"metadata");this.t=e,this.n=t,r&&(this.key_label=r),this.metadata=[],i&&this.metadata.push({tag:ee,value:i})}set ephClaim(e){this.metadata.push({tag:T,value:e.toJSON()})}get queryPath(){return"keygen"}get requestSchema(){return{Request:[{name:"setup",type:"KeygenSetupOpts"},{name:"challenge",type:"string"}],KeygenSetupOpts:[{name:"t",type:"uint32"},{name:"n",type:"uint32"},{name:"metadata",type:"TaggedValue[]"}],TaggedValue:M}}},b=class{constructor({t:e,key_id:t,message:r}){s(this,"t");s(this,"key_id");s(this,"message");this.t=e,this.key_id=t,this.message=r}get queryPath(){return"signgen"}},f=class{constructor({n:e,key_id:t}){s(this,"n");s(this,"key_id");s(this,"metadata");this.n=e,this.key_id=t,this.metadata=[],this.metadata.push({tag:te,value:t})}set ephClaim(e){this.metadata.push({tag:T,value:e.toJSON()})}get queryPath(){return"addEphemeralKey"}get requestSchema(){return{Request:[{name:"setup",type:"AddEphemeralKeyOpts"},{name:"challenge",type:"string"}],AddEphemeralKeyOpts:[{name:"n",type:"uint32"},{name:"metadata",type:"TaggedValue[]"}],TaggedValue:M}}},C=class{constructor(e,t,r,i){s(this,"authModule");s(this,"threshold");s(this,"totalNodes");s(this,"wp_client");u(t<2,`Threshold = ${t} must be at least 2`),u(r<t,`Total nodes = ${r} must be greater or equal to threshold = ${t}`),this.threshold=t,this.totalNodes=r,this.authModule=i,this.wp_client=e}async generateKey(e){let t=new g({t:this.threshold,n:this.totalNodes,permissions:e,key_label:void 0});return this.setEphClaimOf(t),await this.wp_client.startKeygen({setup:t,authModule:this.authModule})}async signMessage(e,t){h("keyId",e),h("message",t);let r=new b({t:this.threshold,key_id:e,message:t});return await this.wp_client.startSigngen({setup:r,authModule:this.authModule})}async addEphemeralKey(e){h("keyId",e);let t=new f({n:this.totalNodes,key_id:e});return this.setEphClaimOf(t),await this.wp_client.addEphemeralKey({setup:t,authModule:this.authModule})}setEphClaimOf(e){e.ephClaim=this.authModule.ephClaim}};var ne={name:"SilentShard authentication",version:"0.1.0"},re=[{name:"name",type:"string"},{name:"version",type:"string"}];function ie(n,e,t){let r;return n instanceof g?r=new g({t:n.t,n:n.n,key_label:n.key_label,permissions:void 0}):r=new f({n:n.n,key_id:n.key_id}),r.ephClaim=t,{types:{EIP712Domain:re,...n.requestSchema},domain:ne,primaryType:"Request",message:{setup:r,challenge:e}}}async function N({setup:n,eoa:e,challenge:t,browserWallet:r,ephClaim:i}){let a=ie(n,t,i),o=await r.signTypedData(e,a);return{credentials:{credentials:i.toJSON(),method:"eoa",id:e},signature:o}}var W=require("@noble/curves/ed25519");var O=require("js-base64"),k=require("viem");async function D({user:n,challenge:e,rpConfig:t,ephClaim:r}){let i=(0,k.hexToBytes)(`0x${e}`,{size:32}),a={publicKey:{authenticatorSelection:{residentKey:"preferred",userVerification:"required"},challenge:i,excludeCredentials:[],pubKeyCredParams:[{type:"public-key",alg:-7},{type:"public-key",alg:-257}],rp:{name:t.rpName,id:t.rpId},user:{...n,id:O.Base64.toUint8Array(n.id)}}},o=await navigator.credentials.create(a);if(o===null)throw new Error("No credential returned");let p=c(o.response.attestationObject),d={rawCredential:JSON.stringify({authenticatorAttachment:o.authenticatorAttachment,id:o.id,rawId:c(o.rawId),response:{attestationObject:p,clientDataJSON:c(o.response.clientDataJSON)},type:o.type}),origin:t.rpName,rpId:t.rpId};return{credentials:{credentials:r.toJSON(),method:"passkey",id:o.id},signature:JSON.stringify(d)}}async function J({challenge:n,allowCredentialId:e,rpConfig:t,ephClaim:r}){let i=(0,k.hexToBytes)(`0x${n}`,{size:32}),a=e?[{type:"public-key",id:O.Base64.toUint8Array(e)}]:[],o={publicKey:{userVerification:"required",challenge:i,allowCredentials:a}},p=await navigator.credentials.get(o);if(p===null)throw new Error("Failed to get navigator credentials");let l=p.response,d=l.userHandle;if(d===null)throw new Error("User handle cannot be null");let H=c(l.signature),L={rawCredential:JSON.stringify({authenticatorAttachment:p.authenticatorAttachment,id:p.id,rawId:c(p.rawId),response:{authenticatorData:c(l.authenticatorData),clientDataJSON:c(l.clientDataJSON),signature:H,userHandle:c(d)},type:p.type}),origin:t.rpName,rpId:t.rpId};return{credentials:{credentials:r.toJSON(),method:"passkey",id:p.id},signature:JSON.stringify(L)}}var x=require("viem"),P=require("@noble/curves/ed25519");var m=class{constructor(e,t,r=3600){s(this,"ephId");s(this,"ephPK");s(this,"expiry");this.validateInputs(e,t,r),this.ephId=e,this.ephPK=(0,x.toHex)(t),this.expiry=Math.floor(Date.now()/1e3)+r}validateInputs(e,t,r){h("ephId",e),w(t),u(Number.isInteger(r)===!1,"lifetime must be an integer");let i=r>0&&r<=365*24*60*60;u(!i,"lifetime must be greater than 0 and less than or equal to 365 days")}toJSON(){return JSON.stringify({ephId:this.ephId,ephPK:this.ephPK,expiry:this.expiry})}};async function _({setup:n,challenge:e,ephSK:t,ephClaim:r}){let i={setup:n,challenge:e},a=new TextEncoder,o=(0,x.toHex)(P.ed25519.sign(a.encode(JSON.stringify(i)),t));return{credentials:{credentials:r.toJSON(),method:"ephemeral",id:r.ephId},signature:o}}function q(){return P.ed25519.utils.randomPrivateKey()}function B(n){return P.ed25519.getPublicKey(n)}var $=require("viem");var I=class{constructor(e,t,r,i,a){s(this,"browserWallet");s(this,"eoa");s(this,"ephClaim");this.validateInputs(t,r),this.ephClaim=new m(e,i,a),this.browserWallet=r,this.eoa=t}validateInputs(e,t){u(!(0,$.isAddress)(e),"invalid Ethereum address format"),u(!((t==null?void 0:t.signTypedData)instanceof Function),"invalid browserWallet")}async authenticate({setup:e,challenge:t}){return await N({setup:e,eoa:this.eoa,challenge:t,browserWallet:this.browserWallet,ephClaim:this.ephClaim})}},E=class{constructor(e,t){s(this,"ephSK");s(this,"ephClaim");w(t),this.ephSK=t;let r=W.ed25519.getPublicKey(this.ephSK);this.ephClaim=new m(e,r)}async authenticate({setup:e,challenge:t}){return await _({setup:e,challenge:t,ephSK:this.ephSK,ephClaim:this.ephClaim})}},K=class{constructor(e,t,r,i,a,o){s(this,"rpConfig");s(this,"allowCredentialId");s(this,"user");s(this,"ephClaim");this.ephClaim=new m(i,a,o),this.rpConfig=e,this.user=t,this.allowCredentialId=r}async authenticate({setup:e,challenge:t}){let r=e.queryPath==="addEphemeralKey";if(this.allowCredentialId||r)return await J({allowCredentialId:this.allowCredentialId,challenge:t,rpConfig:this.rpConfig,ephClaim:this.ephClaim});if(this.user)return await D({user:this.user,challenge:t,rpConfig:this.rpConfig,ephClaim:this.ephClaim});throw new Error("Invalid arguments for passkey authentication")}};var v=require("viem/accounts"),F=require("@noble/curves/secp256k1");var y=require("viem");function V(n){if(n.startsWith("0x")&&(n=n.slice(2)),n.startsWith("04"))return(0,v.publicKeyToAddress)(`0x${n} `);if(n.startsWith("02")||n.startsWith("03")){let e=F.secp256k1.ProjectivePoint.fromHex(n).toHex(!1);return(0,v.publicKeyToAddress)(`0x${e}`)}else throw new Error("Invalid public key")}0&&(module.exports={EOAAuth,EphAuth,NetworkSigner,PasskeyAuth,WalletProviderServiceClient,computeAddress,generateEphPrivateKey,getEphPublicKey});
|
|
1
|
+
"use strict";var R=Object.defineProperty;var St=Object.getOwnPropertyDescriptor;var xt=Object.getOwnPropertyNames;var wt=Object.prototype.hasOwnProperty;var bt=(n,t,e)=>t in n?R(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var At=(n,t)=>{for(var e in t)R(n,e,{get:t[e],enumerable:!0})},Pt=(n,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of xt(t))!wt.call(n,r)&&r!==e&&R(n,r,{get:()=>t[r],enumerable:!(i=St(t,r))||i.enumerable});return n};var Ct=n=>Pt(R({},"__esModule",{value:!0}),n);var p=(n,t,e)=>bt(n,typeof t!="symbol"?t+"":t,e);var Bt={};At(Bt,{EOAAuth:()=>b,EphAuth:()=>I,EphKeyClaim:()=>w,NetworkSigner:()=>U,PasskeyAuth:()=>A,PasskeyRegister:()=>E,WalletProviderServiceClient:()=>M,computeAddress:()=>_,default:()=>Tt,generateEphPrivateKey:()=>J,getEphPublicKey:()=>v});module.exports=Ct(Bt);var Ot=1,et=2,F=3,nt=[{name:"tag",type:"uint16"},{name:"value",type:"string"}],m=class{constructor({t,n:e,key_label:i,permissions:r}){p(this,"t");p(this,"n");p(this,"key_label");p(this,"metadata");this.t=t,this.n=e,i&&(this.key_label=i),this.metadata=[],r&&this.metadata.push({tag:Ot,value:r})}set ephClaim(t){this.metadata.push({tag:et,value:t.toJSON()})}get requestSchema(){return{Request:[{name:"setup",type:"KeygenSetupOpts"},{name:"challenge",type:"string"}],KeygenSetupOpts:[{name:"t",type:"uint32"},{name:"n",type:"uint32"},{name:"metadata",type:"TaggedValue[]"}],TaggedValue:nt}}},k=class{constructor({t,key_id:e,message:i}){p(this,"t");p(this,"key_id");p(this,"message");this.t=t,this.key_id=e,this.message=i}},d=class{constructor(){p(this,"metadata");this.metadata=[]}set ephClaim(t){this.metadata.push({tag:et,value:t.toJSON()})}set keyId(t){this.metadata.push({tag:F,value:t})}extractMetadataByTag(t){let e=this.metadata.find(i=>i.tag===t);if(e)return e.value;throw new Error(`Tag ${t} not found in metadata`)}get requestSchema(){return{Request:[{name:"setup",type:"MetadataSetupOpts"},{name:"challenge",type:"string"}],MetadataSetupOpts:[{name:"metadata",type:"TaggedValue[]"}],TaggedValue:nt}}};var kt={name:"SilentShard authentication",version:"0.1.0"},vt=[{name:"name",type:"string"},{name:"version",type:"string"}];function It(n,t,e){let i;return n instanceof m?i=new m({t:n.t,n:n.n,key_label:n.key_label,permissions:void 0}):(i=new d,i.keyId=n.extractMetadataByTag(F)),i.ephClaim=e,{types:{EIP712Domain:vt,...n.requestSchema},domain:kt,primaryType:"Request",message:{setup:i,challenge:t}}}async function it({setup:n,eoa:t,challenge:e,browserWallet:i,ephClaim:r}){let o=It(n,e,r),s=await i.signTypedData(t,o);return{credentials:{credentials:r.toJSON(),method:"eoa",id:t},signature:s}}var ct=require("js-base64");function Et(n){return n instanceof Uint8Array||ArrayBuffer.isView(n)&&n.constructor.name==="Uint8Array"}function q(n,...t){if(!Et(n))throw new Error("Uint8Array expected");if(t.length>0&&!t.includes(n.length))throw new Error("Uint8Array expected of length "+t+", got length="+n.length)}function H(n,t=!0){if(n.destroyed)throw new Error("Hash instance has been destroyed");if(t&&n.finished)throw new Error("Hash#digest() has already been called")}function st(n,t){q(n);let e=t.outputLen;if(n.length<e)throw new Error("digestInto() expects output buffer of length at least "+e)}var B=n=>new DataView(n.buffer,n.byteOffset,n.byteLength),f=(n,t)=>n<<32-t|n>>>t;function Ut(n){if(typeof n!="string")throw new Error("utf8ToBytes expected string, got "+typeof n);return new Uint8Array(new TextEncoder().encode(n))}function G(n){return typeof n=="string"&&(n=Ut(n)),q(n),n}var T=class{clone(){return this._cloneInto()}};function rt(n){let t=i=>n().update(G(i)).digest(),e=n();return t.outputLen=e.outputLen,t.blockLen=e.blockLen,t.create=()=>n(),t}function Mt(n,t,e,i){if(typeof n.setBigUint64=="function")return n.setBigUint64(t,e,i);let r=BigInt(32),o=BigInt(4294967295),s=Number(e>>r&o),a=Number(e&o),c=i?4:0,u=i?0:4;n.setUint32(t+c,s,i),n.setUint32(t+u,a,i)}var ot=(n,t,e)=>n&t^~n&e,at=(n,t,e)=>n&t^n&e^t&e,N=class extends T{constructor(t,e,i,r){super(),this.blockLen=t,this.outputLen=e,this.padOffset=i,this.isLE=r,this.finished=!1,this.length=0,this.pos=0,this.destroyed=!1,this.buffer=new Uint8Array(t),this.view=B(this.buffer)}update(t){H(this);let{view:e,buffer:i,blockLen:r}=this;t=G(t);let o=t.length;for(let s=0;s<o;){let a=Math.min(r-this.pos,o-s);if(a===r){let c=B(t);for(;r<=o-s;s+=r)this.process(c,s);continue}i.set(t.subarray(s,s+a),this.pos),this.pos+=a,s+=a,this.pos===r&&(this.process(e,0),this.pos=0)}return this.length+=t.length,this.roundClean(),this}digestInto(t){H(this),st(t,this),this.finished=!0;let{buffer:e,view:i,blockLen:r,isLE:o}=this,{pos:s}=this;e[s++]=128,this.buffer.subarray(s).fill(0),this.padOffset>r-s&&(this.process(i,0),s=0);for(let l=s;l<r;l++)e[l]=0;Mt(i,r-8,BigInt(this.length*8),o),this.process(i,0);let a=B(t),c=this.outputLen;if(c%4)throw new Error("_sha2: outputLen should be aligned to 32bit");let u=c/4,g=this.get();if(u>g.length)throw new Error("_sha2: outputLen bigger than state");for(let l=0;l<u;l++)a.setUint32(4*l,g[l],o)}digest(){let{buffer:t,outputLen:e}=this;this.digestInto(t);let i=t.slice(0,e);return this.destroy(),i}_cloneInto(t){t||(t=new this.constructor),t.set(...this.get());let{blockLen:e,buffer:i,length:r,finished:o,destroyed:s,pos:a}=this;return t.length=r,t.pos=a,t.finished=o,t.destroyed=s,r%e&&t.buffer.set(i),t}};var Kt=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),S=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),x=new Uint32Array(64),z=class extends N{constructor(){super(64,32,8,!1),this.A=S[0]|0,this.B=S[1]|0,this.C=S[2]|0,this.D=S[3]|0,this.E=S[4]|0,this.F=S[5]|0,this.G=S[6]|0,this.H=S[7]|0}get(){let{A:t,B:e,C:i,D:r,E:o,F:s,G:a,H:c}=this;return[t,e,i,r,o,s,a,c]}set(t,e,i,r,o,s,a,c){this.A=t|0,this.B=e|0,this.C=i|0,this.D=r|0,this.E=o|0,this.F=s|0,this.G=a|0,this.H=c|0}process(t,e){for(let l=0;l<16;l++,e+=4)x[l]=t.getUint32(e,!1);for(let l=16;l<64;l++){let P=x[l-15],O=x[l-2],tt=f(P,7)^f(P,18)^P>>>3,W=f(O,17)^f(O,19)^O>>>10;x[l]=W+x[l-7]+tt+x[l-16]|0}let{A:i,B:r,C:o,D:s,E:a,F:c,G:u,H:g}=this;for(let l=0;l<64;l++){let P=f(a,6)^f(a,11)^f(a,25),O=g+P+ot(a,c,u)+Kt[l]+x[l]|0,W=(f(i,2)^f(i,13)^f(i,22))+at(i,r,o)|0;g=u,u=c,c=a,a=s+O|0,s=o,o=r,r=i,i=O+W|0}i=i+this.A|0,r=r+this.B|0,o=o+this.C|0,s=s+this.D|0,a=a+this.E|0,c=c+this.F|0,u=u+this.G|0,g=g+this.H|0,this.set(i,r,o,s,a,c,u,g)}roundClean(){x.fill(0)}destroy(){this.set(0,0,0,0,0,0,0,0),this.buffer.fill(0)}};var Q=rt(()=>new z);var D=require("viem");var Y=n=>btoa(String.fromCodePoint.apply(null,Array.from(n))),y=n=>ct.Base64.fromUint8Array(new Uint8Array(n),!0),pt=n=>{let t=(0,D.stringToBytes)(n),e=Q(Q(t));return(0,D.toHex)(e,{size:32}).slice(2)};var j=require("js-base64"),X=require("viem");async function ut({user:n,challenge:t,rpConfig:e}){let i=(0,X.hexToBytes)(`0x${t}`,{size:32}),r={publicKey:{authenticatorSelection:{residentKey:"preferred",userVerification:"required"},challenge:i,excludeCredentials:[],pubKeyCredParams:[{type:"public-key",alg:-7},{type:"public-key",alg:-257}],rp:{name:e.rpName,id:e.rpId},user:{...n,id:j.Base64.toUint8Array(n.id)}}},o=await navigator.credentials.create(r);if(o===null)throw new Error("No credential returned");let s=y(o.response.attestationObject),c={rawCredential:JSON.stringify({authenticatorAttachment:o.authenticatorAttachment,id:o.id,rawId:y(o.rawId),response:{attestationObject:s,clientDataJSON:y(o.response.clientDataJSON)},type:o.type}),origin:e.rpName,rpId:e.rpId};return{credentials:{credentials:"",method:"passkey",id:o.id},signature:JSON.stringify(c)}}async function lt({challenge:n,allowCredentialId:t,rpConfig:e,ephClaim:i}){let r=(0,X.hexToBytes)(`0x${n}`,{size:32}),o=t?[{type:"public-key",id:j.Base64.toUint8Array(t)}]:[],s={publicKey:{userVerification:"required",challenge:r,allowCredentials:o}},a=await navigator.credentials.get(s);if(a===null)throw new Error("Failed to get navigator credentials");let c=a.response,u=c.userHandle;if(u===null)throw new Error("User handle cannot be null");let g=y(c.signature),P={rawCredential:JSON.stringify({authenticatorAttachment:a.authenticatorAttachment,id:a.id,rawId:y(a.rawId),response:{authenticatorData:y(c.authenticatorData),clientDataJSON:y(c.clientDataJSON),signature:g,userHandle:y(u)},type:a.type}),origin:e.rpName,rpId:e.rpId};return{credentials:{credentials:i.toJSON(),method:"passkey",id:a.id},signature:JSON.stringify(P)}}var V=require("viem"),L=require("@noble/curves/ed25519"),Z=require("@noble/curves/secp256k1");var C=(n,t)=>{h(typeof t!="string",`${n} must be string`),h((t==null?void 0:t.trim().length)===0,`${n} cannot be empty`)},ht=(n,t)=>{h(!(n instanceof Uint8Array),"key must be an Uint8Array"),t==="secp256k1"&&h(n.length!==65,"secp256k1: key length must be 65 bytes, got "+n.length),t==="ed25519"&&h(n.length!==32,"ed25519: key length must be 32 bytes, got "+n.length)},dt=(n,t)=>{h(!(n instanceof Uint8Array),"key must be an Uint8Array"),t==="secp256k1"&&h(n.length!==32,"secp256k1: key length must be 32 bytes, got "+n.length),t==="ed25519"&&h(n.length!==32,"ed25519: key length must be 32 bytes, got "+n.length)};var h=(n,t)=>{if(n)throw new Error(t)};var gt=require("viem/accounts");var w=class{constructor(t,e,i,r=3600){p(this,"ephId");p(this,"ephPK");p(this,"signAlg");p(this,"expiry");this.validateInputs(t,e,i,r),this.ephId=t,this.ephPK=(0,V.toHex)(e),this.signAlg=i,this.expiry=Math.floor(Date.now()/1e3)+r}validateInputs(t,e,i,r){C("ephId",t),ht(e,i),h(Number.isInteger(r)===!1,"lifetime must be an integer");let o=r>0&&r<=365*24*60*60;h(!o,"lifetime must be greater than 0 and less than or equal to 365 days")}toJSON(){return JSON.stringify({ephId:this.ephId,ephPK:this.ephPK,expiry:this.expiry,signAlg:this.signAlg})}};async function ft({setup:n,challenge:t,ephSK:e,ephClaim:i}){let r={setup:n,challenge:t},s=new TextEncoder().encode(JSON.stringify(r)),a=await Rt(s,e,i.signAlg);return{credentials:{credentials:i.toJSON(),method:"ephemeral",id:i.ephId},signature:a}}async function Rt(n,t,e){switch(e){case"ed25519":return(0,V.toHex)(L.ed25519.sign(n,t));case"secp256k1":return await(0,gt.signMessage)({message:{raw:n},privateKey:(0,V.toHex)(t)});default:throw new Error("Invalid signature algorithm")}}function J(n){switch(n){case"ed25519":return L.ed25519.utils.randomPrivateKey();case"secp256k1":return Z.secp256k1.utils.randomPrivateKey();default:throw new Error("Invalid signature algorithm")}}function v(n,t){switch(t){case"ed25519":return L.ed25519.getPublicKey(n);case"secp256k1":return Z.secp256k1.getPublicKey(n,!1);default:throw new Error("Invalid signature algorithm")}}var mt=require("viem");var b=class{constructor(t,e,i){p(this,"browserWallet");p(this,"eoa");p(this,"ephClaim");this.validateInputs(t,e),this.ephClaim=i,this.browserWallet=e,this.eoa=t}validateInputs(t,e){h(!(0,mt.isAddress)(t),"invalid Ethereum address format"),h(!((e==null?void 0:e.signTypedData)instanceof Function),"invalid browserWallet")}async authenticate({setup:t,challenge:e}){return h(!(t instanceof m||t instanceof d),`invalid setup for EOA authenticate. Requires KeygenSetupOpts or MetadataSetupOpts but found ${JSON.stringify(t)}`),await it({setup:t,eoa:this.eoa,challenge:e,browserWallet:this.browserWallet,ephClaim:this.ephClaim})}},I=class{constructor(t,e,i){p(this,"ephSK");p(this,"ephClaim");dt(e,i),this.ephSK=e;let r=v(this.ephSK,i);this.ephClaim=new w(t,r,i)}async authenticate({setup:t,challenge:e}){return h(!(t instanceof k||t instanceof d),`invalid setup for Eph authenticate. Requires SignSetupOpts or MetadataSetupOpts but found ${JSON.stringify(t)}`),await ft({setup:t,challenge:e,ephSK:this.ephSK,ephClaim:this.ephClaim})}},A=class{constructor(t,e,i){p(this,"rpConfig");p(this,"allowCredentialId");p(this,"ephClaim");this.ephClaim=i,this.rpConfig=t,this.allowCredentialId=e}async authenticate({setup:t,challenge:e}){return h(!(t instanceof m||t instanceof d),`invalid setup for Passkey authenticate. Requires KeygenSetupOpts or MetadataSetupOpts but found ${JSON.stringify(t)}`),await lt({allowCredentialId:this.allowCredentialId,challenge:e,rpConfig:this.rpConfig,ephClaim:this.ephClaim})}},E=class{constructor(t,e){p(this,"rpConfig");p(this,"user");this.rpConfig=t,this.user=e}async authenticate({setup:t,challenge:e}){return h(!(t instanceof d),`invalid setup for Passkey register. Requires MetadataSetupOpts but found ${JSON.stringify(t)}`),await ut({user:this.user,challenge:e,rpConfig:this.rpConfig})}};var U=class{constructor(t,e,i,r){p(this,"authModule");p(this,"threshold");p(this,"totalNodes");p(this,"wpClient");h(e<2,`Threshold = ${e} must be at least 2`),h(i<e,`Total nodes = ${i} must be greater or equal to threshold = ${e}`),this.threshold=e,this.totalNodes=i,this.authModule=r,this.wpClient=t}async generateKey(t){let e=new m({t:this.threshold,n:this.totalNodes,permissions:t,key_label:void 0});return this.setEphClaimOf(e),await this.wpClient.startKeygen({setup:e,authModule:this.authModule})}async signMessage(t,e){C("keyId",t),C("message",e);let i=new k({t:this.threshold,key_id:t,message:e});return await this.wpClient.startSigngen({setup:i,authModule:this.authModule})}async addEphemeralKey(t){C("keyId",t);let e=new d;return e.keyId=t,this.setEphClaimOf(e),await this.wpClient.addEphemeralKey({setup:e,authModule:this.authModule})}async revokeEphemeralKey(t){C("keyId",t);let e=new d;return e.keyId=t,this.setEphClaimOf(e),await this.wpClient.revokeEphemeralKey({setup:e,authModule:this.authModule})}async registerPasskey(){let t=new d;return await this.wpClient.registerPasskey({setup:t,authModule:this.authModule})}setEphClaimOf(t){(this.authModule instanceof b||this.authModule instanceof A)&&(t.ephClaim=this.authModule.ephClaim)}};var M=class{constructor(t){p(this,"walletProviderId");p(this,"walletProviderUrl");p(this,"apiVersion","v1");this.walletProviderId=t.walletProviderId,this.walletProviderUrl=`${t.walletProviderUrl}/${t.apiVersion}`,this.apiVersion=t.apiVersion}getVersion(){return this.apiVersion}getWalletId(){return this.walletProviderId}async startKeygen({setup:t,authModule:e}){return(this.apiVersion==="v1"?this.connect.bind(this):this.connectV2.bind(this))("keygen",t,e).then(r=>{var c,u;let o=r.split(":");h(o.length!==2,"Invalid keygen response from network");let s=(c=o[0])==null?void 0:c.split("=")[1];return{publicKey:(u=o[1])==null?void 0:u.split("=")[1],keyId:s}})}async startSigngen({setup:t,authModule:e}){return(this.apiVersion==="v1"?this.connect.bind(this):this.connectV2.bind(this))("signgen",t,e).then(r=>{var c,u;let o=r.split(":");h(o.length!==2,"Invalid signgen response from network");let s=(c=o[0])==null?void 0:c.split("=")[1],a=(u=o[1])==null?void 0:u.split("=")[1];if(s===void 0||a===void 0)throw new Error("Invalid signgen response from network");return{sign:s,recid:parseInt(a)}})}async addEphemeralKey({setup:t,authModule:e}){return(this.apiVersion==="v1"?this.connect.bind(this):this.connectV2.bind(this))("addEphemeralKey",t,e).then(r=>({status:r}))}async revokeEphemeralKey({setup:t,authModule:e}){return(this.apiVersion==="v1"?this.connect.bind(this):this.connectV2.bind(this))("revokeEphemeralKey",t,e).then(r=>({status:r}))}async registerPasskey({setup:t,authModule:e}){return(this.apiVersion==="v1"?this.connect.bind(this):this.connectV2.bind(this))("registerPasskey",t,e).then(r=>({passkeyCredentialId:r}))}connect(t,e,i){return new Promise((r,o)=>{let s=0;t==="signgen"&&(e.message=Y(new TextEncoder().encode(e.message)));let a=new WebSocket(`${this.walletProviderUrl}/${t}`);a.addEventListener("open",c=>{switch(console.debug(`Connection opened in state ${s} with event ${JSON.stringify(c,void 0," ")}`),s){case 0:s=1,a.send(JSON.stringify(e));break;case 1:case 2:s=3,o("Incorrect protocol state");break;case 3:break}}),a.addEventListener("message",async c=>{switch(console.debug(`Connection message in state ${s} with event ${JSON.stringify(c,void 0," ")}`),s){case 0:s=3,o("Incorrect protocol state");break;case 1:{s=2;try{let u=await i.authenticate({setup:e,challenge:c.data});a.send(JSON.stringify(u))}catch(u){o(u)}break}case 2:s=3,a.close(),r(c.data);break;case 3:break}}),a.addEventListener("error",c=>{console.debug(`Connection error in state ${s} with event ${JSON.stringify(c,void 0," ")}`),s!=3&&(s=3,o("Incorrect protocol state"))}),a.addEventListener("close",c=>{console.debug(`Connection closed in state ${s} with event ${JSON.stringify(c,void 0," ")}`),s!=3&&(s=3,o("Incorrect protocol state"))})})}connectV2(t,e,i){return new Promise((r,o)=>{let s=0;t==="signgen"&&(e.message=Y(new TextEncoder().encode(e.message)));let a=new WebSocket(`${this.walletProviderUrl}/${t}`);a.addEventListener("open",async c=>{switch(console.debug(`Connection opened in state ${s} with event ${JSON.stringify(c,void 0," ")}`),s){case 0:s=2;try{let u=JSON.stringify(e),g=await i.authenticate({setup:e,challenge:pt(u)});a.send(JSON.stringify({setupOpts:u,userAuth:JSON.stringify(g)}))}catch(u){o(u)}break;case 2:s=3,o("Incorrect protocol state");break;case 3:break}}),a.addEventListener("message",async c=>{switch(console.debug(`Connection message in state ${s} with event ${JSON.stringify(c,void 0," ")}`),s){case 0:s=3,o("Incorrect protocol state");break;case 2:s=3,a.close(),r(c.data);break;case 3:break}}),a.addEventListener("error",c=>{console.debug(`Connection error in state ${s} with event ${JSON.stringify(c,void 0," ")}`),s!=3&&(s=3,o("Incorrect protocol state"))}),a.addEventListener("close",c=>{console.debug(`Connection closed in state ${s} with event ${JSON.stringify(c,void 0," ")}`),s!=3&&(s=3,o("Incorrect protocol state"))})})}};var $=require("viem/accounts"),yt=require("@noble/curves/secp256k1");var K=require("viem");function _(n){if(n.startsWith("0x")&&(n=n.slice(2)),n.startsWith("04"))return(0,$.publicKeyToAddress)(`0x${n} `);if(n.startsWith("02")||n.startsWith("03")){let t=yt.secp256k1.ProjectivePoint.fromHex(n).toHex(!1);return(0,$.publicKeyToAddress)(`0x${t}`)}else throw new Error("Invalid public key")}var Tt={NetworkSigner:U,WalletProviderServiceClient:M,EOAAuth:b,EphAuth:I,PasskeyAuth:A,PasskeyRegister:E,generateEphPrivateKey:J,getEphPublicKey:v,EphKeyClaim:w,computeAddress:_};0&&(module.exports={EOAAuth,EphAuth,EphKeyClaim,NetworkSigner,PasskeyAuth,PasskeyRegister,WalletProviderServiceClient,computeAddress,generateEphPrivateKey,getEphPublicKey});
|
|
2
|
+
/*! Bundled license information:
|
|
3
|
+
|
|
4
|
+
@noble/hashes/esm/utils.js:
|
|
5
|
+
(*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
6
|
+
*/
|