@silencelaboratories/walletprovider-sdk 0.1.0 → 0.2.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 +94 -51
- package/dist/EOAauthentication.d.ts +6 -20
- package/dist/authentication.d.ts +49 -20
- package/dist/encoding.d.ts +1 -2
- package/dist/ephemeralAuthentication.d.ts +16 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.d.ts +8 -6
- package/dist/index.esm.js +1 -0
- package/dist/networkSigner.d.ts +8 -6
- package/dist/passkeyAuthentication.d.ts +32 -0
- package/dist/viemSigner.d.ts +3 -1
- package/dist/walletProviderServiceClient.d.ts +2 -1
- package/package.json +21 -10
- package/dist/index.js +0 -1
package/README.md
CHANGED
|
@@ -10,8 +10,8 @@ In order to run it execute the following:
|
|
|
10
10
|
1. Build the library
|
|
11
11
|
|
|
12
12
|
```
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
npm install
|
|
14
|
+
npm run build
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
2. Run the demo
|
|
@@ -49,24 +49,30 @@ For description of classes, interfaces, types, please refer to [documentation](.
|
|
|
49
49
|
## Authentication
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
Users authenticate using
|
|
52
|
+
Users authenticate using **EOA wallet** or **Passkey** during **key generation** and register an ephemeral signing key pair and associates it with their identity.
|
|
53
53
|
|
|
54
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.
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
Key generation:
|
|
57
|
+
- [EOAAuth](./docs/walletprovider-sdk.eoaauth.md) to authenticate the user **during keygen**. The `EOAAuth` object is created with the user's wallet address.
|
|
58
|
+
|
|
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
|
+
|
|
61
|
+
- The ephemeral public key and lifetime of the key in seconds will be associated with both `EOAAuth` and `PasskeyAuth` objects.
|
|
57
62
|
|
|
58
|
-
|
|
63
|
+
Signature generation:
|
|
64
|
+
- [EphAuth](./docs/walletprovider-sdk.ephauth.md) to authenticate the user **during signing**. The `EphAuth` object is created with the ephemeral keypair.
|
|
59
65
|
|
|
60
66
|
## Keygen
|
|
61
67
|
|
|
62
68
|
|
|
63
69
|
The full working example is in the [demo](https://github.com/silence-laboratories/walletprovider-sdk/blob/a75d7a009fb4d3629d353d53f8c27c34190c9035/demo/src/routes/%2Bpage.svelte#L89).
|
|
64
|
-
The core object to use is the [NetworkSigner](./docs/walletprovider-sdk.networksigner.md).
|
|
70
|
+
The core object to use is the [NetworkSigner](./docs/walletprovider-sdk.networksigner.md). It allows to generate keys and do signatures.
|
|
65
71
|
|
|
66
|
-
|
|
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 **authentication module**.
|
|
67
73
|
|
|
68
|
-
|
|
69
|
-
Let's create the `NetworkSigner`
|
|
74
|
+
### Authenticate with EOA wallet
|
|
75
|
+
We provide EOA authentication via [EOAAuth](./docs/walletprovider-sdk.eoaauth.md) module. Let's create the `NetworkSigner` with associated `EOAAuth` object.
|
|
70
76
|
|
|
71
77
|
```ts
|
|
72
78
|
// Generate ephemeral secret key esk
|
|
@@ -74,12 +80,14 @@ const sk = ed.utils.randomPrivateKey();
|
|
|
74
80
|
ephSK = sk;
|
|
75
81
|
// Derive public part epk from esk
|
|
76
82
|
ephPK = await ed.getPublicKeyAsync(sk);
|
|
77
|
-
|
|
83
|
+
// Arbitrary ID to identify the ephemeral key
|
|
84
|
+
const ephId = uuidv4();
|
|
78
85
|
// Create a client that connects to the backend service
|
|
79
86
|
const wpClient = await createWalletProviderService(clusterConfig);
|
|
80
87
|
|
|
81
88
|
// Create EOA authenticator, signature will include epk
|
|
82
89
|
const eoaAuth = new EOAAuth(
|
|
90
|
+
ephId,
|
|
83
91
|
accountsFromBrowserWallet[0],
|
|
84
92
|
new BrowserWallet(),
|
|
85
93
|
ephPK,
|
|
@@ -113,9 +121,58 @@ const permissions = {
|
|
|
113
121
|
let resp: KeygenResponse = await sdk.authenticateAndCreateKey(JSON.stringify(permissions));
|
|
114
122
|
```
|
|
115
123
|
|
|
116
|
-
Calling this method will cause to the Browser Wallet window to pop up, requesting the User to sign the request.
|
|
124
|
+
Calling this method will cause to the Browser Wallet window to pop up, requesting the User to sign the request.
|
|
117
125
|
|
|
118
|
-
The [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
|
+
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.
|
|
127
|
+
|
|
128
|
+
The `esk` key can be later used by the frontend in subsequent signgen requests for authenticating.
|
|
129
|
+
|
|
130
|
+
### Authenticate with Passkey
|
|
131
|
+
We provide Passkey authentication via [PasskeyAuth](./docs/walletprovider-sdk.passkeyauth.md) module. Let's create the `NetworkSigner` with associated `PasskeyAuth` object.
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
// Generate ephemeral secret key esk
|
|
135
|
+
const sk = ed.utils.randomPrivateKey();
|
|
136
|
+
ephSK = sk;
|
|
137
|
+
// Derive public part epk from esk
|
|
138
|
+
ephPK = await ed.getPublicKeyAsync(sk);
|
|
139
|
+
// Arbitrary ID to identify the ephemeral key
|
|
140
|
+
const ephId = uuidv4();
|
|
141
|
+
// Create a client that connects to the backend service
|
|
142
|
+
const wpClient = await createWalletProviderService(clusterConfig);
|
|
143
|
+
// Here we configure the relying party for local development
|
|
144
|
+
const rpConfig: RelyingPartyConfig = {
|
|
145
|
+
rpId: 'localhost',
|
|
146
|
+
rpName: 'http://localhost:5173',
|
|
147
|
+
};
|
|
148
|
+
// Information about the owner of the passkey
|
|
149
|
+
const passkeyUser: PasskeyUser = {
|
|
150
|
+
id: userId,
|
|
151
|
+
displayName: 'Alice',
|
|
152
|
+
name: 'alice@gmail.com ' + userId, // For development purposes
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// Get passkey credential id from your storage
|
|
156
|
+
const credentialId = getPasskeyCredentialId();
|
|
157
|
+
// Create EOA authenticator, signature will include epk
|
|
158
|
+
const passkeyAuth = new PasskeyAuth(
|
|
159
|
+
rpConfig,
|
|
160
|
+
passkeyUser,
|
|
161
|
+
ephId,
|
|
162
|
+
ephPK,
|
|
163
|
+
// Lifetime of one hour
|
|
164
|
+
60 * 60,
|
|
165
|
+
// If credentialId is null, we will do passkey register, otherwise, we will do passkey auth/login
|
|
166
|
+
credentialId,
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
// Create a new signer instance
|
|
170
|
+
const sdk = new NetworkSigner(wpClient, threshold, partiesNumber, passkeyAuth);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Now you can generate a key like in the EOA example by calling the [authenticateAndCreateKey](./docs/walletprovider-sdk.networksigner.authenticateandcreatekey.md) method.
|
|
174
|
+
|
|
175
|
+
Calling this method will prompt the browser to request Passkey User Verification. Once user verification is done, the [KeygenResponse](./docs/walletprovider-sdk.keygenresponse.md) is returned.
|
|
119
176
|
|
|
120
177
|
The `esk` key can be later used by the frontend in subsequent signgen requests for authenticating.
|
|
121
178
|
|
|
@@ -125,7 +182,7 @@ The full signing example is [here](https://github.com/silence-laboratories/walle
|
|
|
125
182
|
|
|
126
183
|
Let's create NetworkSigner for signing. Note the `EphAuth` is used to avoid user interaction when generating the signatures.
|
|
127
184
|
```ts
|
|
128
|
-
const authModule = new EphAuth(
|
|
185
|
+
const authModule = new EphAuth(ephId, ephSK);
|
|
129
186
|
// Create a new signer instance
|
|
130
187
|
const sdk = new NetworkSigner(wpClient, threshold, partiesNumber, authModule);
|
|
131
188
|
```
|
|
@@ -135,71 +192,57 @@ Use the [NetworkSigner.authenticateAndSign](./docs/walletprovider-sdk.networksig
|
|
|
135
192
|
|
|
136
193
|
```ts
|
|
137
194
|
let signMessage = JSON.stringify({
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
195
|
+
message: JSON.stringify({
|
|
196
|
+
userOperation: {
|
|
197
|
+
sender: '0x8d4cb2540d993fe34c646299f1ab4af3012ff34c',
|
|
198
|
+
nonce: '0x7',
|
|
199
|
+
initCode: '0x',
|
|
200
|
+
callData: '0000189...',
|
|
201
|
+
callGasLimit: '0x18473',
|
|
202
|
+
verificationGasLimit: '0x18473',
|
|
203
|
+
preVerificationGas: '66768',
|
|
204
|
+
maxFeePerGas: '',
|
|
205
|
+
maxPriorityFeePerGas: '',
|
|
206
|
+
paymasterAndData: '0x',
|
|
207
|
+
},
|
|
208
|
+
entryPointVersion: 'v0.6.0',
|
|
209
|
+
entryPointAddress: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
|
|
210
|
+
chainId: 80002,
|
|
211
|
+
}),
|
|
212
|
+
requestType: 'accountAbstractionTx',
|
|
213
|
+
});
|
|
154
214
|
|
|
155
215
|
let resp = await sdk.authenticateAndSign(selectedKeyId, signMessage);
|
|
156
216
|
```
|
|
157
217
|
|
|
158
218
|
The [SignResponse](./docs/walletprovider-sdk.signresponse.md) contains the signature `sign` and the recovery ID `recid`.
|
|
159
219
|
|
|
160
|
-
# Developing the library
|
|
161
|
-
|
|
162
|
-
Audience of this section are library developers.
|
|
163
|
-
|
|
164
|
-
## Bun runtime is required
|
|
165
|
-
|
|
166
|
-
Install bun from https://bun.sh
|
|
167
220
|
|
|
168
221
|
## Install dependencies
|
|
169
222
|
|
|
170
223
|
```bash
|
|
171
|
-
|
|
224
|
+
npm install
|
|
172
225
|
```
|
|
173
226
|
|
|
174
227
|
## Build
|
|
175
228
|
|
|
176
229
|
```bash
|
|
177
|
-
|
|
230
|
+
npm run build
|
|
178
231
|
```
|
|
179
232
|
|
|
180
233
|
The output will be in the `dist` folder.
|
|
181
234
|
|
|
182
|
-
## Test
|
|
183
|
-
|
|
184
|
-
Create `*.test.ts` files and run tests with:
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
bun run test
|
|
188
|
-
# or watch test
|
|
189
|
-
bun run test:watch
|
|
190
|
-
```
|
|
191
|
-
|
|
192
235
|
## End to end tests
|
|
193
236
|
Please refer to [README.md](./e2e-tests/README.md) for instructions how to execute them.
|
|
194
237
|
|
|
195
238
|
## Format the code
|
|
196
239
|
|
|
197
240
|
```bash
|
|
198
|
-
|
|
241
|
+
npm run format
|
|
199
242
|
```
|
|
200
243
|
|
|
201
244
|
## Generate the documentation
|
|
202
245
|
|
|
203
246
|
```bash
|
|
204
|
-
|
|
205
|
-
```
|
|
247
|
+
npm run docs
|
|
248
|
+
```
|
|
@@ -1,14 +1,9 @@
|
|
|
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
|
|
5
|
-
import { type UserAuthentication } from './authentication
|
|
4
|
+
import { KeygenSetupOpts } from './networkSigner';
|
|
5
|
+
import { type UserAuthentication } from './authentication';
|
|
6
6
|
import { type TypedDataDomain } from 'viem';
|
|
7
|
-
export type EphClaim = {
|
|
8
|
-
eoa: string;
|
|
9
|
-
ephPK: string;
|
|
10
|
-
expiry: number;
|
|
11
|
-
};
|
|
12
7
|
export type FieldDefinition = {
|
|
13
8
|
name: string;
|
|
14
9
|
type: string;
|
|
@@ -50,23 +45,14 @@ export interface IBrowserWallet {
|
|
|
50
45
|
signTypedData<T>(from: string, request: TypedData<T>): Promise<unknown>;
|
|
51
46
|
}
|
|
52
47
|
/** Present the request to the User using wallet UI, and ask for sign.
|
|
53
|
-
* The signature is the authorization for
|
|
48
|
+
* The signature is the authorization for keygen operation
|
|
54
49
|
*/
|
|
55
|
-
export declare function authenticateUsingEOA({ setup,
|
|
50
|
+
export declare function authenticateUsingEOA({ setup, ephId, eoa, challenge, browserWallet, ephPK, lifetime, }: {
|
|
56
51
|
setup: KeygenSetupOpts;
|
|
57
|
-
|
|
52
|
+
ephId: string;
|
|
53
|
+
eoa: string;
|
|
58
54
|
challenge: string;
|
|
59
55
|
browserWallet: IBrowserWallet;
|
|
60
56
|
ephPK: Uint8Array;
|
|
61
57
|
lifetime: number;
|
|
62
58
|
}): Promise<UserAuthentication>;
|
|
63
|
-
/** Present the request to the User using wallet UI, and ask for sign.
|
|
64
|
-
* The signature is the authorization for the operation
|
|
65
|
-
*/
|
|
66
|
-
export declare function authenticateUsingEphKey({ setup, user_id, challenge, ephSK, ephPK, }: {
|
|
67
|
-
setup: SignSetupOpts;
|
|
68
|
-
user_id: string;
|
|
69
|
-
challenge: string;
|
|
70
|
-
ephSK: Uint8Array;
|
|
71
|
-
ephPK: Uint8Array;
|
|
72
|
-
}): Promise<UserAuthentication>;
|
package/dist/authentication.d.ts
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
import { KeygenSetupOpts, SignSetupOpts } from './networkSigner';
|
|
2
2
|
import { IBrowserWallet } from './EOAauthentication';
|
|
3
|
+
import { PasskeyUser, RelyingPartyConfig } from './passkeyAuthentication';
|
|
3
4
|
/** Type of the request authentication
|
|
4
5
|
* @alpha
|
|
5
6
|
*/
|
|
6
|
-
export declare enum AuthMethod {
|
|
7
|
-
/** Authentication using Externally Owned Account */
|
|
8
|
-
EOA = 0,
|
|
9
|
-
/** No authentication */
|
|
10
|
-
NONE = 1
|
|
11
|
-
}
|
|
12
7
|
export type UserCredentials = {
|
|
13
8
|
id: string;
|
|
14
9
|
method: string;
|
|
15
10
|
credentials: string;
|
|
11
|
+
ephId?: string;
|
|
16
12
|
};
|
|
17
13
|
export type UserAuthentication = {
|
|
18
14
|
credentials: UserCredentials;
|
|
19
15
|
signature: string;
|
|
16
|
+
passkeyCredentialId?: string;
|
|
20
17
|
};
|
|
21
18
|
export interface AuthModule {
|
|
22
19
|
authenticate({ setup, challenge, }: {
|
|
@@ -24,46 +21,78 @@ export interface AuthModule {
|
|
|
24
21
|
challenge: string;
|
|
25
22
|
}): Promise<UserAuthentication>;
|
|
26
23
|
}
|
|
27
|
-
/** The `
|
|
24
|
+
/** The `EOAAuth` implementing Externally Owned Account authentication.
|
|
28
25
|
* @alpha
|
|
29
26
|
*/
|
|
30
27
|
export declare class EOAAuth implements AuthModule {
|
|
31
|
-
/**
|
|
32
|
-
|
|
28
|
+
/** Ephemeral id identify ephemeral key */
|
|
29
|
+
ephId: string;
|
|
33
30
|
/** An interface to the wallet, like MetaMask, that is used to sign the requests */
|
|
34
31
|
browserWallet: IBrowserWallet;
|
|
35
32
|
/** Public key of the ephemeral key */
|
|
36
33
|
ephPK: Uint8Array;
|
|
37
34
|
/** Lifetime of the ephemeral key */
|
|
38
35
|
lifetime: number;
|
|
39
|
-
|
|
36
|
+
/** the ETH address that is used to do EOA authentication */
|
|
37
|
+
eoa: string;
|
|
38
|
+
constructor(ephId: string, eoa: string, browserWallet: IBrowserWallet, ephPK: Uint8Array, lifetime?: number);
|
|
40
39
|
/**
|
|
41
40
|
* Prepares a message to present on the Browser Wallet window and requests to sign it.
|
|
42
|
-
* @param setup -
|
|
41
|
+
* @param setup - Keygen setup options
|
|
43
42
|
* @param challenge - the challenge received from the backend
|
|
44
43
|
*
|
|
45
44
|
* @public
|
|
46
45
|
*/
|
|
47
|
-
authenticate({ setup, challenge
|
|
48
|
-
setup: KeygenSetupOpts
|
|
46
|
+
authenticate({ setup, challenge }: {
|
|
47
|
+
setup: KeygenSetupOpts;
|
|
49
48
|
challenge: string;
|
|
50
49
|
}): Promise<UserAuthentication>;
|
|
51
50
|
}
|
|
52
|
-
/**
|
|
51
|
+
/** The `EphAuth` module is only used for signing requests to the network.
|
|
52
|
+
* @alpha
|
|
53
|
+
* An Ephmeral key used to locally sign the signature requests to network.
|
|
53
54
|
* This eph key is registered during keygen. The key is used to sign the requests without
|
|
54
55
|
* asking the user to sign the request each time.
|
|
55
|
-
* The auth module is only used for signing requests to the network.
|
|
56
56
|
* */
|
|
57
57
|
export declare class EphAuth implements AuthModule {
|
|
58
|
-
/**
|
|
59
|
-
|
|
58
|
+
/** Ephemeral id identify ephemeral key */
|
|
59
|
+
ephId: string;
|
|
60
60
|
/** Secret key of the ephemeral keypair */
|
|
61
61
|
ephSK: Uint8Array;
|
|
62
62
|
/** Public key of the ephemeral keypair */
|
|
63
63
|
ephPK: Uint8Array;
|
|
64
|
-
constructor(
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
constructor(ephId: string, ephSK: Uint8Array);
|
|
65
|
+
/**
|
|
66
|
+
* Prepares a message to present on the Browser Wallet window and requests to sign it.
|
|
67
|
+
* @param setup - Signgen setup options
|
|
68
|
+
* @param challenge - the challenge received from the backend
|
|
69
|
+
*
|
|
70
|
+
* @public
|
|
71
|
+
*/
|
|
72
|
+
authenticate({ setup, challenge }: {
|
|
73
|
+
setup: SignSetupOpts;
|
|
74
|
+
challenge: string;
|
|
75
|
+
}): Promise<UserAuthentication>;
|
|
76
|
+
}
|
|
77
|
+
/** The `AuthModule` implementing Passkey authentication.
|
|
78
|
+
* @alpha
|
|
79
|
+
*/
|
|
80
|
+
export declare class PasskeyAuth implements AuthModule {
|
|
81
|
+
/** Replying party object. Read more: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions#rp */
|
|
82
|
+
rpConfig: RelyingPartyConfig;
|
|
83
|
+
/** Passkey user information. Read more: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions#user */
|
|
84
|
+
user: PasskeyUser;
|
|
85
|
+
/** Public key of the ephemeral key */
|
|
86
|
+
ephPK: Uint8Array;
|
|
87
|
+
/** Lifetime of the ephemeral key */
|
|
88
|
+
lifetime: number;
|
|
89
|
+
/** Ephemeral id identify ephemeral key */
|
|
90
|
+
ephId: string;
|
|
91
|
+
/** Credential id that user and authenticator acknowledges about */
|
|
92
|
+
credentialId: string | null;
|
|
93
|
+
constructor(rpConfig: RelyingPartyConfig, user: PasskeyUser, ephId: string, ephPK: Uint8Array, lifetime: number | undefined, credentialId: string | null);
|
|
94
|
+
authenticate({ setup, challenge }: {
|
|
95
|
+
setup: KeygenSetupOpts;
|
|
67
96
|
challenge: string;
|
|
68
97
|
}): Promise<UserAuthentication>;
|
|
69
98
|
}
|
package/dist/encoding.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export declare const decodeHex: (s: string) => Uint8Array;
|
|
2
|
-
export declare const encodeHex: (a: Uint8Array) => string;
|
|
3
1
|
export declare const decodeBase64: (b64: string) => Uint8Array;
|
|
4
2
|
export declare const encodeBase64: (b: Uint8Array) => string;
|
|
3
|
+
export declare const arrayBufferToBase64Url: (a: ArrayBuffer) => string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { UserAuthentication } from './authentication';
|
|
2
|
+
import { SignSetupOpts } from './networkSigner';
|
|
3
|
+
export type EphClaim = {
|
|
4
|
+
ephPK: string;
|
|
5
|
+
expiry: number;
|
|
6
|
+
};
|
|
7
|
+
/** Locally sign the signature requests to network without asking the user, the ephSK is registered during keygen.
|
|
8
|
+
* The signature is the authorization for signgen operation
|
|
9
|
+
*/
|
|
10
|
+
export declare function authenticateUsingEphKey({ setup, ephId, challenge, ephSK, ephPK, }: {
|
|
11
|
+
setup: SignSetupOpts;
|
|
12
|
+
ephId: string;
|
|
13
|
+
challenge: string;
|
|
14
|
+
ephSK: Uint8Array;
|
|
15
|
+
ephPK: Uint8Array;
|
|
16
|
+
}): Promise<UserAuthentication>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var H=Object.create;var y=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var L=Object.getPrototypeOf,V=Object.prototype.hasOwnProperty;var G=(t,e,n)=>e in t?y(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var Y=(t,e)=>{for(var n in e)y(t,n,{get:e[n],enumerable:!0})},v=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of z(e))!V.call(t,s)&&s!==n&&y(t,s,{get:()=>e[s],enumerable:!(r=F(e,s))||r.enumerable});return t};var j=(t,e,n)=>(n=t!=null?H(L(t)):{},v(e||!t||!t.__esModule?y(n,"default",{value:t,enumerable:!0}):n,t)),Q=t=>v(y({},"__esModule",{value:!0}),t);var a=(t,e,n)=>G(t,typeof e!="symbol"?e+"":e,n);var se={};Y(se,{EOAAuth:()=>w,EphAuth:()=>A,NetworkSigner:()=>P,PasskeyAuth:()=>I,WalletProviderServiceClient:()=>K,computeAddress:()=>M});module.exports=Q(se);var k=require("viem");var X=1,Z=2,f=class{constructor({t:e,n,ephPK:r,key_label:s,permissions:i}){a(this,"t");a(this,"n");a(this,"key_label");a(this,"metadata");this.t=e,this.n=n,this.key_label=s,this.metadata=[],this.metadata.push({tag:Z,value:r}),i&&this.metadata.push({tag:X,value:i})}};function u(t){return t.message!==void 0}var P=class{constructor(e,n,r,s){a(this,"authModule");a(this,"threshold");a(this,"totalNodes");a(this,"wp_client");if(n===0)throw new Error("Threshold cannot be 0");this.threshold=n,this.totalNodes=r,this.authModule=s,this.wp_client=e}async authenticateAndCreateKey(e,n){try{let r=new f({t:this.threshold,n:this.totalNodes,permissions:n,ephPK:(0,k.toHex)(e)}),s=p=>this.authModule.authenticate({setup:r,challenge:p}),i=await this.wp_client.startKeygen({setup:r,signer:s});return console.log("Keygen response:",i),i}catch(r){throw console.error(r),r}}async authenticateAndSign(e,n){let r={t:this.threshold,key_id:e,message:n},s=p=>this.authModule.authenticate({setup:r,challenge:p}),i=await this.wp_client.startSigngen({setup:r,signer:s});return console.log("Sign response:",i),i}};var b=require("viem"),ee=[{name:"tag",type:"uint16"},{name:"value",type:"string"}],te={Request:[{name:"setup",type:"KeygenSetupOpts"},{name:"challenge",type:"string"}],KeygenSetupOpts:[{name:"t",type:"uint32"},{name:"n",type:"uint32"},{name:"metadata",type:"TaggedValue[]"}],TaggedValue:ee},ne={name:"SilentShard authentication",version:"0.1.0"},ie=[{name:"name",type:"string"},{name:"version",type:"string"}];function re(t,e,n){console.log("EPHKEY",n);let r=new f({t:t.t,n:t.n,key_label:t.key_label,permissions:void 0,ephPK:(0,b.toHex)(n)});return{types:{EIP712Domain:ie,...te},domain:ne,primaryType:"Request",message:{setup:r,challenge:e}}}async function R({setup:t,ephId:e,eoa:n,challenge:r,browserWallet:s,ephPK:i,lifetime:p}){if(u(t))throw new Error("EOA auth cannot be used for Sign requests, please use EphAuth instead");let c=re(t,r,i),o=await s.signTypedData(n,c);console.log("User signed a request",o);let l={ephPK:(0,b.toHex)(i),expiry:Math.floor(Date.now()/1e3)+p};return{credentials:{credentials:JSON.stringify(l),method:"eoa",id:n,ephId:e},signature:o}}var B=require("@noble/curves/ed25519");var T=require("js-base64");var E=t=>btoa(String.fromCodePoint.apply(null,Array.from(t))),g=t=>T.Base64.fromUint8Array(new Uint8Array(t),!0);var O=require("js-base64"),d=require("viem");async function N({user:t,ephId:e,challenge:n,rpConfig:r,ephPK:s,lifetime:i}){let p=(0,d.hexToBytes)(`0x${n}`,{size:32}),c={publicKey:{authenticatorSelection:{authenticatorAttachment:void 0,residentKey:"preferred",requireResidentKey:!1,userVerification:"required"},challenge:p,excludeCredentials:[],pubKeyCredParams:[{type:"public-key",alg:-7},{type:"public-key",alg:-257}],rp:{name:r.rpName,id:r.rpId},user:{...t,id:O.Base64.toUint8Array(t.id)}}},o=await navigator.credentials.create(c);if(o===null)throw new Error("No credential returned");let l=g(o.response.attestationObject),S={rawCredential:JSON.stringify({authenticatorAttachment:o.authenticatorAttachment,id:o.id,rawId:g(o.rawId),response:{attestationObject:l,clientDataJSON:g(o.response.clientDataJSON)},type:o.type}),origin:r.rpName,rpId:r.rpId},x={ephPK:(0,d.toHex)(s),expiry:Math.floor(Date.now()/1e3)+i};return{credentials:{credentials:JSON.stringify(x),method:"passkey",id:o.id,ephId:e},signature:JSON.stringify(S),passkeyCredentialId:o.id}}async function D({ephId:t,challenge:e,credentialId:n,rpConfig:r,ephPK:s,lifetime:i}){let p=(0,d.hexToBytes)(`0x${e}`,{size:32}),c=[{type:"public-key",id:O.Base64.toUint8Array(n)}],o={publicKey:{userVerification:"required",challenge:p,allowCredentials:c}},l=await navigator.credentials.get(o);if(l===null)throw new Error("Failed to get navigator credentials");let m=l.response,S=m.userHandle;if(S===null)throw new Error("User handle cannot be null");let x=g(m.signature),_={rawCredential:JSON.stringify({authenticatorAttachment:l.authenticatorAttachment,id:l.id,rawId:g(l.rawId),response:{authenticatorData:g(m.authenticatorData),clientDataJSON:g(m.clientDataJSON),signature:x,userHandle:g(S)},type:l.type}),origin:r.rpName,rpId:r.rpId,credentialId:n},$={ephPK:(0,d.toHex)(s),expiry:Math.floor(Date.now()/1e3)+i};return{credentials:{credentials:JSON.stringify($),method:"passkey",id:l.id,ephId:t},signature:JSON.stringify(_),passkeyCredentialId:l.id}}var U=require("viem"),J=require("@noble/curves/ed25519");async function W({setup:t,ephId:e,challenge:n,ephSK:r,ephPK:s}){let i={setup:t,challenge:n},p=new TextEncoder,c=(0,U.toHex)(J.ed25519.sign(p.encode(JSON.stringify(i)),r));console.log("AUTH SIGNATURE by eph key",c);let o={ephPK:(0,U.toHex)(s),expiry:0};return{credentials:{credentials:JSON.stringify(o),method:"ephemeral",id:e},signature:c}}var w=class{constructor(e,n,r,s,i=3600){a(this,"ephId");a(this,"browserWallet");a(this,"ephPK");a(this,"lifetime");a(this,"eoa");this.ephId=e,this.browserWallet=r,this.ephPK=s,this.lifetime=i,this.eoa=n}async authenticate({setup:e,challenge:n}){return await R({setup:e,ephId:this.ephId,eoa:this.eoa,challenge:n,browserWallet:this.browserWallet,ephPK:this.ephPK,lifetime:this.lifetime})}},A=class{constructor(e,n){a(this,"ephId");a(this,"ephSK");a(this,"ephPK");this.ephId=e,this.ephSK=n,this.ephPK=B.ed25519.getPublicKey(this.ephSK)}async authenticate({setup:e,challenge:n}){return await W({setup:e,ephId:this.ephId,challenge:n,ephSK:this.ephSK,ephPK:this.ephPK})}},I=class{constructor(e,n,r,s,i=3600,p){a(this,"rpConfig");a(this,"user");a(this,"ephPK");a(this,"lifetime");a(this,"ephId");a(this,"credentialId");this.rpConfig=e,this.user=n,this.ephPK=s,this.lifetime=i,this.ephId=r,this.credentialId=p}async authenticate({setup:e,challenge:n}){if(u(e))throw new Error("Passkey auth cannot be used for Sign requests, please use EphAuth instead");return this.credentialId?await D({ephId:this.ephId,credentialId:this.credentialId,challenge:n,rpConfig:this.rpConfig,ephPK:this.ephPK,lifetime:this.lifetime}):await N({user:this.user,ephId:this.ephId,challenge:n,rpConfig:this.rpConfig,ephPK:this.ephPK,lifetime:this.lifetime})}};var K=class{constructor(e){a(this,"walletProviderId");a(this,"walletProviderUrl");a(this,"passkeyCredentialId");this.walletProviderId=e.walletProviderId,this.walletProviderUrl=e.walletProviderUrl}getWalletId(){return this.walletProviderId}async startKeygen({setup:e,signer:n}){return this.connect(e,n).then(r=>{let s=r.split(":"),i=s[0].split("=")[1];return{publicKey:s[1].split("=")[1],keyId:i,passkeyCredentialId:this.passkeyCredentialId}})}async startSigngen({setup:e,signer:n}){return this.connect(e,n).then(r=>{let s=r.split(":"),i=s[0].split("=")[1],p=s[1].split("=")[1];return{sign:i,recid:parseInt(p)}})}connect(e,n){return new Promise((r,s)=>{let i=0,p;u(e)?(p="signgen",e.message=E(new TextEncoder().encode(e.message))):p="keygen";let c=new WebSocket(`${this.walletProviderUrl}/${p}`);c.addEventListener("open",o=>{switch(console.log(`Connection opened in state ${i} with event ${JSON.stringify(o,void 0," ")}`),i){case 0:i=1,console.log(`Sending setup: ${JSON.stringify(e)}`),c.send(JSON.stringify(e));break;case 1:case 2:i=3,s("Incorrect protocol state");break;case 3:break}}),c.addEventListener("message",async o=>{switch(console.log(`Connection message in state ${i} with event ${JSON.stringify(o,void 0," ")}`),i){case 0:i=3,s("Incorrect protocol state");break;case 1:{i=2;let l=await n(o.data);l.credentials.method==="passkey"&&(this.passkeyCredentialId=l.passkeyCredentialId),console.log(`Sending signature: ${JSON.stringify(l)}`),c.send(JSON.stringify(l));break}case 2:i=3,c.close(),r(o.data);break;case 3:break}}),c.addEventListener("error",o=>{console.log(`Connection error in state ${i} with event ${JSON.stringify(o,void 0," ")}`),i!=3&&(i=3,s("Incorrect protocol state"))}),c.addEventListener("close",o=>{console.log(`Connection closed in state ${i} with event ${JSON.stringify(o,void 0," ")}`),i!=3&&(i=3,s("Incorrect protocol state"))})})}};var h=j(require("viem")),C=require("viem/accounts"),q=require("@noble/curves/secp256k1");function M(t){if(t.startsWith("0x")&&(t=t.slice(2)),t.startsWith("04"))return(0,C.publicKeyToAddress)(`0x${t} `);if(t.startsWith("02")||t.startsWith("03")){let e=q.secp256k1.ProjectivePoint.fromHex(t).toHex(!1);return(0,C.publicKeyToAddress)(`0x${e}`)}else throw new Error("Invalid public key")}0&&(module.exports={EOAAuth,EphAuth,NetworkSigner,PasskeyAuth,WalletProviderServiceClient,computeAddress});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export type {
|
|
4
|
-
export type {
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
1
|
+
export type { SignResponse, KeygenResponse } from './networkSigner';
|
|
2
|
+
export type { IBrowserWallet, TypedData } from './EOAauthentication';
|
|
3
|
+
export type { ClientConfig, IWalletProviderServiceClient } from './walletProviderServiceClientInterface';
|
|
4
|
+
export type { PasskeyUser, RelyingPartyConfig } from './passkeyAuthentication';
|
|
5
|
+
export { NetworkSigner } from './networkSigner';
|
|
6
|
+
export { EOAAuth, EphAuth, PasskeyAuth } from './authentication';
|
|
7
|
+
export { WalletProviderServiceClient } from './walletProviderServiceClient';
|
|
8
|
+
export { computeAddress } from './viemSigner';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var M=Object.defineProperty,_=Object.defineProperties;var $=Object.getOwnPropertyDescriptors;var b=Object.getOwnPropertySymbols;var H=Object.prototype.hasOwnProperty,F=Object.prototype.propertyIsEnumerable;var P=(n,e,t)=>e in n?M(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,m=(n,e)=>{for(var t in e||(e={}))H.call(e,t)&&P(n,t,e[t]);if(b)for(var t of b(e))F.call(e,t)&&P(n,t,e[t]);return n},w=(n,e)=>_(n,$(e));var a=(n,e,t)=>P(n,typeof e!="symbol"?e+"":e,t);import{toHex as z}from"viem";var L=1,V=2,y=class{constructor({t:e,n:t,ephPK:r,key_label:s,permissions:i}){a(this,"t");a(this,"n");a(this,"key_label");a(this,"metadata");this.t=e,this.n=t,this.key_label=s,this.metadata=[],this.metadata.push({tag:V,value:r}),i&&this.metadata.push({tag:L,value:i})}};function u(n){return n.message!==void 0}var A=class{constructor(e,t,r,s){a(this,"authModule");a(this,"threshold");a(this,"totalNodes");a(this,"wp_client");if(t===0)throw new Error("Threshold cannot be 0");this.threshold=t,this.totalNodes=r,this.authModule=s,this.wp_client=e}async authenticateAndCreateKey(e,t){try{let r=new y({t:this.threshold,n:this.totalNodes,permissions:t,ephPK:z(e)}),s=p=>this.authModule.authenticate({setup:r,challenge:p}),i=await this.wp_client.startKeygen({setup:r,signer:s});return console.log("Keygen response:",i),i}catch(r){throw console.error(r),r}}async authenticateAndSign(e,t){let r={t:this.threshold,key_id:e,message:t},s=p=>this.authModule.authenticate({setup:r,challenge:p}),i=await this.wp_client.startSigngen({setup:r,signer:s});return console.log("Sign response:",i),i}};import{toHex as O}from"viem";var G=[{name:"tag",type:"uint16"},{name:"value",type:"string"}],Y={Request:[{name:"setup",type:"KeygenSetupOpts"},{name:"challenge",type:"string"}],KeygenSetupOpts:[{name:"t",type:"uint32"},{name:"n",type:"uint32"},{name:"metadata",type:"TaggedValue[]"}],TaggedValue:G},j={name:"SilentShard authentication",version:"0.1.0"},Q=[{name:"name",type:"string"},{name:"version",type:"string"}];function X(n,e,t){console.log("EPHKEY",t);let r=new y({t:n.t,n:n.n,key_label:n.key_label,permissions:void 0,ephPK:O(t)});return{types:m({EIP712Domain:Q},Y),domain:j,primaryType:"Request",message:{setup:r,challenge:e}}}async function U({setup:n,ephId:e,eoa:t,challenge:r,browserWallet:s,ephPK:i,lifetime:p}){if(u(n))throw new Error("EOA auth cannot be used for Sign requests, please use EphAuth instead");let c=X(n,r,i),o=await s.signTypedData(t,c);console.log("User signed a request",o);let l={ephPK:O(i),expiry:Math.floor(Date.now()/1e3)+p};return{credentials:{credentials:JSON.stringify(l),method:"eoa",id:t,ephId:e},signature:o}}import{ed25519 as te}from"@noble/curves/ed25519";import{Base64 as Z}from"js-base64";var v=n=>btoa(String.fromCodePoint.apply(null,Array.from(n))),g=n=>Z.fromUint8Array(new Uint8Array(n),!0);import{Base64 as k}from"js-base64";import{toHex as R,hexToBytes as T}from"viem";async function E({user:n,ephId:e,challenge:t,rpConfig:r,ephPK:s,lifetime:i}){let p=T("0x".concat(t),{size:32}),c={publicKey:{authenticatorSelection:{authenticatorAttachment:void 0,residentKey:"preferred",requireResidentKey:!1,userVerification:"required"},challenge:p,excludeCredentials:[],pubKeyCredParams:[{type:"public-key",alg:-7},{type:"public-key",alg:-257}],rp:{name:r.rpName,id:r.rpId},user:w(m({},n),{id:k.toUint8Array(n.id)})}},o=await navigator.credentials.create(c);if(o===null)throw new Error("No credential returned");let l=g(o.response.attestationObject),f={rawCredential:JSON.stringify({authenticatorAttachment:o.authenticatorAttachment,id:o.id,rawId:g(o.rawId),response:{attestationObject:l,clientDataJSON:g(o.response.clientDataJSON)},type:o.type}),origin:r.rpName,rpId:r.rpId},S={ephPK:R(s),expiry:Math.floor(Date.now()/1e3)+i};return{credentials:{credentials:JSON.stringify(S),method:"passkey",id:o.id,ephId:e},signature:JSON.stringify(f),passkeyCredentialId:o.id}}async function N({ephId:n,challenge:e,credentialId:t,rpConfig:r,ephPK:s,lifetime:i}){let p=T("0x".concat(e),{size:32}),c=[{type:"public-key",id:k.toUint8Array(t)}],o={publicKey:{userVerification:"required",challenge:p,allowCredentials:c}},l=await navigator.credentials.get(o);if(l===null)throw new Error("Failed to get navigator credentials");let h=l.response,f=h.userHandle;if(f===null)throw new Error("User handle cannot be null");let S=g(h.signature),B={rawCredential:JSON.stringify({authenticatorAttachment:l.authenticatorAttachment,id:l.id,rawId:g(l.rawId),response:{authenticatorData:g(h.authenticatorData),clientDataJSON:g(h.clientDataJSON),signature:S,userHandle:g(f)},type:l.type}),origin:r.rpName,rpId:r.rpId,credentialId:t},q={ephPK:R(s),expiry:Math.floor(Date.now()/1e3)+i};return{credentials:{credentials:JSON.stringify(q),method:"passkey",id:l.id,ephId:n},signature:JSON.stringify(B),passkeyCredentialId:l.id}}import{toHex as D}from"viem";import{ed25519 as ee}from"@noble/curves/ed25519";async function J({setup:n,ephId:e,challenge:t,ephSK:r,ephPK:s}){let i={setup:n,challenge:t},p=new TextEncoder,c=D(ee.sign(p.encode(JSON.stringify(i)),r));console.log("AUTH SIGNATURE by eph key",c);let o={ephPK:D(s),expiry:0};return{credentials:{credentials:JSON.stringify(o),method:"ephemeral",id:e},signature:c}}var I=class{constructor(e,t,r,s,i=3600){a(this,"ephId");a(this,"browserWallet");a(this,"ephPK");a(this,"lifetime");a(this,"eoa");this.ephId=e,this.browserWallet=r,this.ephPK=s,this.lifetime=i,this.eoa=t}async authenticate({setup:e,challenge:t}){return await U({setup:e,ephId:this.ephId,eoa:this.eoa,challenge:t,browserWallet:this.browserWallet,ephPK:this.ephPK,lifetime:this.lifetime})}},K=class{constructor(e,t){a(this,"ephId");a(this,"ephSK");a(this,"ephPK");this.ephId=e,this.ephSK=t,this.ephPK=te.getPublicKey(this.ephSK)}async authenticate({setup:e,challenge:t}){return await J({setup:e,ephId:this.ephId,challenge:t,ephSK:this.ephSK,ephPK:this.ephPK})}},C=class{constructor(e,t,r,s,i=3600,p){a(this,"rpConfig");a(this,"user");a(this,"ephPK");a(this,"lifetime");a(this,"ephId");a(this,"credentialId");this.rpConfig=e,this.user=t,this.ephPK=s,this.lifetime=i,this.ephId=r,this.credentialId=p}async authenticate({setup:e,challenge:t}){if(u(e))throw new Error("Passkey auth cannot be used for Sign requests, please use EphAuth instead");return this.credentialId?await N({ephId:this.ephId,credentialId:this.credentialId,challenge:t,rpConfig:this.rpConfig,ephPK:this.ephPK,lifetime:this.lifetime}):await E({user:this.user,ephId:this.ephId,challenge:t,rpConfig:this.rpConfig,ephPK:this.ephPK,lifetime:this.lifetime})}};var x=class{constructor(e){a(this,"walletProviderId");a(this,"walletProviderUrl");a(this,"passkeyCredentialId");this.walletProviderId=e.walletProviderId,this.walletProviderUrl=e.walletProviderUrl}getWalletId(){return this.walletProviderId}async startKeygen({setup:e,signer:t}){return this.connect(e,t).then(r=>{let s=r.split(":"),i=s[0].split("=")[1];return{publicKey:s[1].split("=")[1],keyId:i,passkeyCredentialId:this.passkeyCredentialId}})}async startSigngen({setup:e,signer:t}){return this.connect(e,t).then(r=>{let s=r.split(":"),i=s[0].split("=")[1],p=s[1].split("=")[1];return{sign:i,recid:parseInt(p)}})}connect(e,t){return new Promise((r,s)=>{let i=0,p;u(e)?(p="signgen",e.message=v(new TextEncoder().encode(e.message))):p="keygen";let c=new WebSocket("".concat(this.walletProviderUrl,"/").concat(p));c.addEventListener("open",o=>{switch(console.log("Connection opened in state ".concat(i," with event ").concat(JSON.stringify(o,void 0," "))),i){case 0:i=1,console.log("Sending setup: ".concat(JSON.stringify(e))),c.send(JSON.stringify(e));break;case 1:case 2:i=3,s("Incorrect protocol state");break;case 3:break}}),c.addEventListener("message",async o=>{switch(console.log("Connection message in state ".concat(i," with event ").concat(JSON.stringify(o,void 0," "))),i){case 0:i=3,s("Incorrect protocol state");break;case 1:{i=2;let l=await t(o.data);l.credentials.method==="passkey"&&(this.passkeyCredentialId=l.passkeyCredentialId),console.log("Sending signature: ".concat(JSON.stringify(l))),c.send(JSON.stringify(l));break}case 2:i=3,c.close(),r(o.data);break;case 3:break}}),c.addEventListener("error",o=>{console.log("Connection error in state ".concat(i," with event ").concat(JSON.stringify(o,void 0," "))),i!=3&&(i=3,s("Incorrect protocol state"))}),c.addEventListener("close",o=>{console.log("Connection closed in state ".concat(i," with event ").concat(JSON.stringify(o,void 0," "))),i!=3&&(i=3,s("Incorrect protocol state"))})})}};import*as d from"viem";import{publicKeyToAddress as W,toAccount as _e}from"viem/accounts";import{secp256k1 as ne}from"@noble/curves/secp256k1";function ie(n){if(n.startsWith("0x")&&(n=n.slice(2)),n.startsWith("04"))return W("0x".concat(n," "));if(n.startsWith("02")||n.startsWith("03")){let e=ne.ProjectivePoint.fromHex(n).toHex(!1);return W("0x".concat(e))}else throw new Error("Invalid public key")}export{I as EOAAuth,K as EphAuth,A as NetworkSigner,C as PasskeyAuth,x as WalletProviderServiceClient,ie as computeAddress};
|
package/dist/networkSigner.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AuthModule, UserAuthentication } from './authentication
|
|
2
|
-
import { type IWalletProviderServiceClient } from './walletProviderServiceClientInterface
|
|
1
|
+
import { AuthModule, UserAuthentication } from './authentication';
|
|
2
|
+
import { type IWalletProviderServiceClient } from './walletProviderServiceClientInterface';
|
|
3
3
|
/**
|
|
4
4
|
* Response from the network for keygen requests
|
|
5
5
|
* @alpha
|
|
@@ -19,6 +19,10 @@ export interface KeygenResponse {
|
|
|
19
19
|
* where Y is set to 0x02 if Y-coord is even, or 0x03 if Y-coord is odd
|
|
20
20
|
*/
|
|
21
21
|
publicKey: string;
|
|
22
|
+
/**
|
|
23
|
+
* Optional credential id used for passkey authentication
|
|
24
|
+
*/
|
|
25
|
+
passkeyCredentialId?: string;
|
|
22
26
|
}
|
|
23
27
|
/**
|
|
24
28
|
* Response from the network for sign request
|
|
@@ -49,12 +53,12 @@ export declare class KeygenSetupOpts {
|
|
|
49
53
|
tag: number;
|
|
50
54
|
value: string;
|
|
51
55
|
}[];
|
|
52
|
-
constructor({ t, n, key_label, permissions,
|
|
56
|
+
constructor({ t, n, ephPK, key_label, permissions, }: {
|
|
53
57
|
t: number;
|
|
54
58
|
n: number;
|
|
59
|
+
ephPK: string;
|
|
55
60
|
key_label?: string;
|
|
56
61
|
permissions?: string;
|
|
57
|
-
ephPK?: string;
|
|
58
62
|
});
|
|
59
63
|
}
|
|
60
64
|
/** Parameters used in Signature execution */
|
|
@@ -101,7 +105,6 @@ export declare class NetworkSigner {
|
|
|
101
105
|
* The permissions are validated during sign requests.
|
|
102
106
|
* @returns {@link KeygenResponse} containing `keyId` and the `pubKey` public part of the key
|
|
103
107
|
* @public
|
|
104
|
-
* @alpha
|
|
105
108
|
*/
|
|
106
109
|
authenticateAndCreateKey(ephKey: Uint8Array, permissions?: string): Promise<KeygenResponse>;
|
|
107
110
|
/** Generate a signature. Uses `authModule` to authenticate the sign request by the User.
|
|
@@ -110,7 +113,6 @@ export declare class NetworkSigner {
|
|
|
110
113
|
* @param message - the message to sign by the MPC network
|
|
111
114
|
* @returns {@link SignResponse}
|
|
112
115
|
* @public
|
|
113
|
-
* @alpha
|
|
114
116
|
*/
|
|
115
117
|
authenticateAndSign(keyId: string, message: string): Promise<SignResponse>;
|
|
116
118
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { UserAuthentication } from './authentication';
|
|
2
|
+
/** Information about the user currently registering. Read more: https://w3c.github.io/webauthn/#dom-publickeycredentialcreationoptions-user
|
|
3
|
+
* @alpha
|
|
4
|
+
* */
|
|
5
|
+
export type PasskeyUser = {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
displayName: string;
|
|
9
|
+
};
|
|
10
|
+
/** The RP responsible for registering and authenticating the user. Read more: https://w3c.github.io/webauthn/#dom-publickeycredentialcreationoptions-rp
|
|
11
|
+
* @alpha
|
|
12
|
+
* */
|
|
13
|
+
export type RelyingPartyConfig = {
|
|
14
|
+
rpName: string;
|
|
15
|
+
rpId: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function passkeyRegister({ user, ephId, challenge, rpConfig, ephPK, lifetime, }: {
|
|
18
|
+
user: PasskeyUser;
|
|
19
|
+
ephId: string;
|
|
20
|
+
challenge: string;
|
|
21
|
+
rpConfig: RelyingPartyConfig;
|
|
22
|
+
ephPK: Uint8Array;
|
|
23
|
+
lifetime: number;
|
|
24
|
+
}): Promise<UserAuthentication>;
|
|
25
|
+
export declare function passkeyLogin({ ephId, challenge, credentialId, rpConfig, ephPK, lifetime, }: {
|
|
26
|
+
ephId: string;
|
|
27
|
+
challenge: string;
|
|
28
|
+
credentialId: string;
|
|
29
|
+
rpConfig: RelyingPartyConfig;
|
|
30
|
+
ephPK: Uint8Array;
|
|
31
|
+
lifetime: number;
|
|
32
|
+
}): Promise<UserAuthentication>;
|
package/dist/viemSigner.d.ts
CHANGED
|
@@ -9,5 +9,7 @@ import { NetworkSigner } from './networkSigner';
|
|
|
9
9
|
* @param threshold The threshold.
|
|
10
10
|
*/
|
|
11
11
|
export declare function createViemAccount(networkSigner: NetworkSigner, keyId: string, publicKey: string): viem.LocalAccount;
|
|
12
|
-
/** Computes ETH address from ECDSA `publicKey` returned by Silent Network
|
|
12
|
+
/** Computes ETH address from ECDSA `publicKey` returned by Silent Network
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
13
15
|
export declare function computeAddress(publicKey: string): viem.Address;
|
|
@@ -8,6 +8,7 @@ import { type ClientConfig, IWalletProviderServiceClient, type Signer } from './
|
|
|
8
8
|
export declare class WalletProviderServiceClient implements IWalletProviderServiceClient {
|
|
9
9
|
walletProviderId: string;
|
|
10
10
|
walletProviderUrl: string;
|
|
11
|
+
passkeyCredentialId?: string;
|
|
11
12
|
/**
|
|
12
13
|
* Create new client that connects to the backend service
|
|
13
14
|
* @param config - config containing information about backend service
|
|
@@ -22,5 +23,5 @@ export declare class WalletProviderServiceClient implements IWalletProviderServi
|
|
|
22
23
|
setup: SignSetupOpts;
|
|
23
24
|
signer: Signer;
|
|
24
25
|
}): Promise<SignResponse>;
|
|
25
|
-
connect(
|
|
26
|
+
connect(setupOpts: KeygenSetupOpts | SignSetupOpts, signer: Signer): Promise<string>;
|
|
26
27
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silencelaboratories/walletprovider-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"author": "Silence Laboratories",
|
|
4
5
|
"description": "Frontend SDK for Wallet Providers",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"
|
|
6
|
+
"main": "./dist/index.cjs.js",
|
|
7
|
+
"module": "./dist/index.esm.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"require": "./dist/index.cjs.js",
|
|
13
|
+
"import": "./dist/index.esm.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
7
16
|
"files": [
|
|
8
17
|
"dist"
|
|
9
18
|
],
|
|
@@ -12,27 +21,29 @@
|
|
|
12
21
|
"formatcheck": "prettier --check --cache .",
|
|
13
22
|
"lint": "eslint --cache ./src/**/*.ts",
|
|
14
23
|
"typecheck": "tsc -p . --noEmit",
|
|
15
|
-
"build": "
|
|
16
|
-
"build:e2e": "bun run scripts/build.e2e.mjs && bun run build:declaration",
|
|
24
|
+
"build": "npm run clean && node build.js && npm run build:declaration",
|
|
17
25
|
"build:declaration": "tsc -p . --emitDeclarationOnly",
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"docs": "
|
|
26
|
+
"clean": "rimraf dist",
|
|
27
|
+
"prepack": "npm run clean && npm run build && npm run build:declaration",
|
|
28
|
+
"docs": "npm run build:declaration && api-extractor run --local --verbose && api-documenter markdown -i ./temp -o ./docs"
|
|
21
29
|
},
|
|
22
|
-
"type": "module",
|
|
23
30
|
"devDependencies": {
|
|
24
31
|
"@eslint/js": "^9.3.0",
|
|
25
32
|
"@microsoft/api-documenter": "^7.25.2",
|
|
26
33
|
"@microsoft/api-extractor": "^7.46.2",
|
|
27
|
-
"
|
|
34
|
+
"esbuild": "^0.23.0",
|
|
35
|
+
"esbuild-node-externals": "^1.14.0",
|
|
28
36
|
"eslint": "^8.x",
|
|
29
37
|
"globals": "^15.3.0",
|
|
38
|
+
"npm-dts": "^1.3.13",
|
|
30
39
|
"prettier": "^3.2.5",
|
|
40
|
+
"rimraf": "^6.0.1",
|
|
31
41
|
"typescript": "^5.4.5",
|
|
32
42
|
"typescript-eslint": "^7.11.0"
|
|
33
43
|
},
|
|
34
44
|
"dependencies": {
|
|
35
45
|
"@noble/curves": "^1.4.2",
|
|
46
|
+
"js-base64": "^3.7.7",
|
|
36
47
|
"viem": "^2.11.1"
|
|
37
48
|
}
|
|
38
49
|
}
|
package/dist/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{toHex as R} from"viem";function Y(x){return x.message!==void 0}var j=1,E=2;class H{t;n;key_label;metadata;constructor({t:x,n:F,key_label:B,permissions:J,ephPK:U}){if(this.t=x,this.n=F,this.key_label=B,this.metadata=[],J)this.metadata.push({tag:j,value:J});if(U)this.metadata.push({tag:E,value:U})}}class V{authModule;threshold;totalNodes;wp_client;constructor(x,F,B,J){if(F===0)throw new Error("Threshold cannot be 0");this.threshold=F,this.totalNodes=B,this.authModule=J,this.wp_client=x}async authenticateAndCreateKey(x,F){try{const B=new H({t:this.threshold,n:this.totalNodes,permissions:F,ephPK:R(x)});console.log("Generated Payload:",B);const J=(X)=>this.authModule.authenticate({setup:B,challenge:X}),U=await this.wp_client.startKeygen({setup:B,signer:J});return console.log("Keygen response:",U),U}catch(B){throw console.error(B),B}}async authenticateAndSign(x,F){const B={t:this.threshold,key_id:x,message:F},J=(X)=>this.authModule.authenticate({setup:B,challenge:X}),U=await this.wp_client.startSigngen({setup:B,signer:J});return console.log("Sign response:",U),U}}import{toHex as z} from"viem";import{ed25519 as f} from"@noble/curves/ed25519";var k=function(x,F,B){console.log("EPHKEY",B);const J=new H({t:x.t,n:x.n,key_label:x.key_label,permissions:void 0,ephPK:z(B)});return console.log("SETUP_NO_PERM",J),{types:{EIP712Domain:_,...w},domain:I,primaryType:"Request",message:{setup:J,challenge:F}}};async function D({setup:x,user_id:F,challenge:B,browserWallet:J,ephPK:U,lifetime:X}){if(Y(x))throw new Error("EOA auth cannot be used for Sign requests, please use EphAuth instead");const Z=k(x,B,U);console.log("typed request:"),console.log(JSON.stringify(Z,void 0,4));const Q=await J.signTypedData(F,Z);console.log("User signed a request",Q);const $={eoa:F,ephPK:z(U),expiry:Math.floor(Date.now()/1000)+X};return{credentials:{credentials:JSON.stringify($),method:"eoa",id:F},signature:Q}}async function N({setup:x,user_id:F,challenge:B,ephSK:J,ephPK:U}){const X={setup:x,challenge:B},Z=new TextEncoder,Q=z(f.sign(Z.encode(JSON.stringify(X)),J));console.log("AUTH SIGNATURE by eph key",Q),console.log("User signed a request",Q);const $={eoa:F,ephPK:z(U),expiry:0};return{credentials:{credentials:JSON.stringify($),method:"ephemeral",id:F},signature:Q}}var M=[{name:"tag",type:"uint16"},{name:"value",type:"string"}],w={Request:[{name:"setup",type:"KeygenSetupOpts"},{name:"challenge",type:"string"}],KeygenSetupOpts:[{name:"t",type:"uint32"},{name:"n",type:"uint32"},{name:"metadata",type:"TaggedValue[]"}],TaggedValue:M},I={name:"SilentShard authentication",version:"0.1.0"},_=[{name:"name",type:"string"},{name:"version",type:"string"}];import{ed25519 as v} from"@noble/curves/ed25519";var q;(function(B){B[B["EOA"]=0]="EOA";B[B["NONE"]=1]="NONE"})(q||(q={}));class W{userId;browserWallet;ephPK;lifetime;constructor(x,F,B,J=3600){this.userId=x,this.browserWallet=F,this.ephPK=B,this.lifetime=J}async authenticate({setup:x,challenge:F}){return await D({setup:x,user_id:this.userId,challenge:F,browserWallet:this.browserWallet,ephPK:this.ephPK,lifetime:this.lifetime})}}class C{userId;ephSK;ephPK;constructor(x,F){this.userId=x,this.ephSK=F,this.ephPK=v.getPublicKey(this.ephSK)}async authenticate({setup:x,challenge:F}){return await N({setup:x,user_id:this.userId,challenge:F,ephSK:this.ephSK,ephPK:this.ephPK})}}var T=(x)=>btoa(String.fromCodePoint.apply(null,Array.from(x)));var L;(function(U){U[U["initiated"]=0]="initiated";U[U["waitingForSign"]=1]="waitingForSign";U[U["waitingForResult"]=2]="waitingForResult";U[U["finished"]=3]="finished"})(L||(L={}));class O{walletProviderId;walletProviderUrl;constructor(x){this.walletProviderId=x.walletProviderId,this.walletProviderUrl=x.walletProviderUrl}getWalletId(){return this.walletProviderId}async startKeygen({setup:x,signer:F}){return this.connect(x,F).then((B)=>{const J=B.split(":"),U=J[1].split("=")[1],X=J[0].split("=")[1];return{publicKey:U,keyId:X}})}async startSigngen({setup:x,signer:F}){return this.connect(x,F).then((B)=>{const J=B.split(":"),U=J[0].split("=")[1],X=J[1].split("=")[1];return{sign:U,recid:parseInt(X)}})}connect(x,F){return new Promise((B,J)=>{let U=L.initiated,X;if(Y(x))X="signgen",x.message=T((new TextEncoder()).encode(x.message));else X="keygen";const Z=new WebSocket(`${this.walletProviderUrl}/${X}`);Z.addEventListener("open",(Q)=>{switch(console.log(`Connection opened in state ${U} with event ${JSON.stringify(Q,void 0,"\t")}`),U){case L.initiated:U=L.waitingForSign,console.log(`Sending setup: ${JSON.stringify(x)}`),Z.send(JSON.stringify(x));break;case L.waitingForSign:case L.waitingForResult:U=L.finished,J("Incorrect protocol state");break;case L.finished:break}}),Z.addEventListener("message",async(Q)=>{switch(console.log(`Connection message in state ${U} with event ${JSON.stringify(Q,void 0,"\t")}`),U){case L.initiated:U=L.finished,J("Incorrect protocol state");break;case L.waitingForSign:{U=L.waitingForResult;const $=await F(Q.data);console.log(`Sending signature: ${JSON.stringify($)}`),Z.send(JSON.stringify($));break}case L.waitingForResult:U=L.finished,Z.close(),B(Q.data);break;case L.finished:break}}),Z.addEventListener("error",(Q)=>{if(console.log(`Connection error in state ${U} with event ${JSON.stringify(Q,void 0,"\t")}`),U!=L.finished)U=L.finished,J("Incorrect protocol state")}),Z.addEventListener("close",(Q)=>{if(console.log(`Connection closed in state ${U} with event ${JSON.stringify(Q,void 0,"\t")}`),U!=L.finished)U=L.finished,J("Incorrect protocol state")})})}}import*as G from"viem";import{publicKeyToAddress as A,toAccount as t} from"viem/accounts";import{secp256k1 as b} from"@noble/curves/secp256k1";function m(x){if(x.startsWith("0x"))x=x.slice(2);if(x.startsWith("04"))return A(`0x${x} `);else if(x.startsWith("02")||x.startsWith("03")){const F=b.ProjectivePoint.fromHex(x).toHex(!1);return A(`0x${F}`)}else throw new Error("Invalid public key")}export{m as computeAddress,O as WalletProviderServiceClient,V as NetworkSigner,C as EphAuth,W as EOAAuth,q as AuthMethod};
|