@zerodev/permissions 5.3.2-alpha-0 → 5.3.2-alpha-1
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/_cjs/constants.js +2 -3
- package/_cjs/constants.js.map +1 -1
- package/_cjs/deserializePermissionAccount.js.map +1 -1
- package/_cjs/policies/callPolicyUtils.js +8 -24
- package/_cjs/policies/callPolicyUtils.js.map +1 -1
- package/_cjs/policies/toCallPolicy.js +2 -1
- package/_cjs/policies/toCallPolicy.js.map +1 -1
- package/_cjs/policies/types.js +0 -1
- package/_cjs/policies/types.js.map +1 -1
- package/_cjs/signers/index.js +3 -3
- package/_cjs/signers/index.js.map +1 -1
- package/_cjs/signers/toWebAuthnSigner.js +60 -74
- package/_cjs/signers/toWebAuthnSigner.js.map +1 -1
- package/_esm/constants.js +1 -8
- package/_esm/constants.js.map +1 -1
- package/_esm/deserializePermissionAccount.js.map +1 -1
- package/_esm/policies/callPolicyUtils.js +8 -24
- package/_esm/policies/callPolicyUtils.js.map +1 -1
- package/_esm/policies/toCallPolicy.js +2 -1
- package/_esm/policies/toCallPolicy.js.map +1 -1
- package/_esm/policies/types.js +0 -1
- package/_esm/policies/types.js.map +1 -1
- package/_esm/signers/index.js +1 -1
- package/_esm/signers/index.js.map +1 -1
- package/_esm/signers/toWebAuthnSigner.js +72 -88
- package/_esm/signers/toWebAuthnSigner.js.map +1 -1
- package/_types/constants.d.ts +1 -8
- package/_types/constants.d.ts.map +1 -1
- package/_types/deserializePermissionAccount.d.ts.map +1 -1
- package/_types/policies/callPolicyUtils.d.ts +1 -1
- package/_types/policies/callPolicyUtils.d.ts.map +1 -1
- package/_types/policies/toCallPolicy.d.ts.map +1 -1
- package/_types/policies/types.d.ts +6 -12
- package/_types/policies/types.d.ts.map +1 -1
- package/_types/signers/index.d.ts +1 -1
- package/_types/signers/index.d.ts.map +1 -1
- package/_types/signers/toWebAuthnSigner.d.ts +2 -3
- package/_types/signers/toWebAuthnSigner.d.ts.map +1 -1
- package/_types/types.d.ts +1 -1
- package/_types/types.d.ts.map +1 -1
- package/constants.ts +1 -10
- package/deserializePermissionAccount.ts +4 -1
- package/package.json +2 -1
- package/policies/callPolicyUtils.ts +16 -32
- package/policies/toCallPolicy.ts +2 -1
- package/policies/types.ts +17 -31
- package/signers/index.ts +1 -1
- package/signers/toWebAuthnSigner.ts +99 -115
- package/types.ts +1 -1
- package/_cjs/signers/toWebAuthnKey.js +0 -101
- package/_cjs/signers/toWebAuthnKey.js.map +0 -1
- package/_cjs/signers/webAuthnUtils.js +0 -45
- package/_cjs/signers/webAuthnUtils.js.map +0 -1
- package/_esm/signers/toWebAuthnKey.js +0 -110
- package/_esm/signers/toWebAuthnKey.js.map +0 -1
- package/_esm/signers/webAuthnUtils.js +0 -41
- package/_esm/signers/webAuthnUtils.js.map +0 -1
- package/_types/signers/toWebAuthnKey.d.ts +0 -17
- package/_types/signers/toWebAuthnKey.d.ts.map +0 -1
- package/_types/signers/webAuthnUtils.d.ts +0 -13
- package/_types/signers/webAuthnUtils.d.ts.map +0 -1
- package/signers/toWebAuthnKey.ts +0 -163
- package/signers/webAuthnUtils.ts +0 -54
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import type { PublicKeyCredentialRequestOptionsJSON } from "@simplewebauthn/typescript-types"
|
|
2
|
+
import type { WebAuthnKey } from "@zerodev/webauthn-key"
|
|
3
|
+
import {
|
|
4
|
+
b64ToBytes,
|
|
5
|
+
base64FromUint8Array,
|
|
6
|
+
findQuoteIndices,
|
|
7
|
+
hexStringToUint8Array,
|
|
8
|
+
isRIP7212SupportedNetwork,
|
|
9
|
+
parseAndNormalizeSig,
|
|
10
|
+
uint8ArrayToHexString
|
|
11
|
+
} from "@zerodev/webauthn-key"
|
|
2
12
|
import type { TypedData } from "abitype"
|
|
3
13
|
import { SignTransactionNotSupportedBySmartAccount } from "permissionless/accounts"
|
|
4
14
|
import {
|
|
@@ -14,23 +24,93 @@ import {
|
|
|
14
24
|
} from "viem"
|
|
15
25
|
import { type SignableMessage, encodeAbiParameters } from "viem"
|
|
16
26
|
import { toAccount } from "viem/accounts"
|
|
17
|
-
import { getChainId } from "viem/actions"
|
|
27
|
+
import { getChainId, signMessage } from "viem/actions"
|
|
18
28
|
import { WEBAUTHN_SIGNER_CONTRACT } from "../constants.js"
|
|
19
29
|
import type { ModularSigner, ModularSignerParams } from "../types.js"
|
|
20
|
-
import type { WebAuthnKey } from "./toWebAuthnKey.js"
|
|
21
|
-
import {
|
|
22
|
-
b64ToBytes,
|
|
23
|
-
findQuoteIndices,
|
|
24
|
-
isRIP7212SupportedNetwork,
|
|
25
|
-
parseAndNormalizeSig,
|
|
26
|
-
uint8ArrayToHexString
|
|
27
|
-
} from "./webAuthnUtils.js"
|
|
28
30
|
|
|
29
31
|
export type WebAuthnModularSignerParams = ModularSignerParams & {
|
|
30
|
-
passkeyServerUrl: string
|
|
31
32
|
webAuthnKey: WebAuthnKey
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
const signMessageUsingWebAuthn = async (
|
|
36
|
+
message: SignableMessage,
|
|
37
|
+
chainId: number,
|
|
38
|
+
allowCredentials?: PublicKeyCredentialRequestOptionsJSON["allowCredentials"]
|
|
39
|
+
) => {
|
|
40
|
+
let messageContent: string
|
|
41
|
+
if (typeof message === "string") {
|
|
42
|
+
// message is a string
|
|
43
|
+
messageContent = message
|
|
44
|
+
} else if ("raw" in message && typeof message.raw === "string") {
|
|
45
|
+
// message.raw is a Hex string
|
|
46
|
+
messageContent = message.raw
|
|
47
|
+
} else if ("raw" in message && message.raw instanceof Uint8Array) {
|
|
48
|
+
// message.raw is a ByteArray
|
|
49
|
+
messageContent = message.raw.toString()
|
|
50
|
+
} else {
|
|
51
|
+
throw new Error("Unsupported message format")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// remove 0x prefix if present
|
|
55
|
+
const formattedMessage = messageContent.startsWith("0x")
|
|
56
|
+
? messageContent.slice(2)
|
|
57
|
+
: messageContent
|
|
58
|
+
|
|
59
|
+
const challenge = base64FromUint8Array(
|
|
60
|
+
hexStringToUint8Array(formattedMessage),
|
|
61
|
+
true
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
// prepare assertion options
|
|
65
|
+
const assertionOptions: PublicKeyCredentialRequestOptionsJSON = {
|
|
66
|
+
challenge,
|
|
67
|
+
allowCredentials,
|
|
68
|
+
userVerification: "required"
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// start authentication (signing)
|
|
72
|
+
const { startAuthentication } = await import("@simplewebauthn/browser")
|
|
73
|
+
const cred = await startAuthentication(assertionOptions)
|
|
74
|
+
|
|
75
|
+
// get authenticator data
|
|
76
|
+
const { authenticatorData } = cred.response
|
|
77
|
+
const authenticatorDataHex = uint8ArrayToHexString(
|
|
78
|
+
b64ToBytes(authenticatorData)
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
// get client data JSON
|
|
82
|
+
const clientDataJSON = atob(cred.response.clientDataJSON)
|
|
83
|
+
|
|
84
|
+
// get challenge and response type location
|
|
85
|
+
const { beforeType } = findQuoteIndices(clientDataJSON)
|
|
86
|
+
|
|
87
|
+
// get signature r,s
|
|
88
|
+
const { signature } = cred.response
|
|
89
|
+
const signatureHex = uint8ArrayToHexString(b64ToBytes(signature))
|
|
90
|
+
const { r, s } = parseAndNormalizeSig(signatureHex)
|
|
91
|
+
|
|
92
|
+
// encode signature
|
|
93
|
+
const encodedSignature = encodeAbiParameters(
|
|
94
|
+
[
|
|
95
|
+
{ name: "authenticatorData", type: "bytes" },
|
|
96
|
+
{ name: "clientDataJSON", type: "string" },
|
|
97
|
+
{ name: "responseTypeLocation", type: "uint256" },
|
|
98
|
+
{ name: "r", type: "uint256" },
|
|
99
|
+
{ name: "s", type: "uint256" },
|
|
100
|
+
{ name: "usePrecompiled", type: "bool" }
|
|
101
|
+
],
|
|
102
|
+
[
|
|
103
|
+
authenticatorDataHex,
|
|
104
|
+
clientDataJSON,
|
|
105
|
+
beforeType,
|
|
106
|
+
BigInt(r),
|
|
107
|
+
BigInt(s),
|
|
108
|
+
isRIP7212SupportedNetwork(chainId)
|
|
109
|
+
]
|
|
110
|
+
)
|
|
111
|
+
return encodedSignature
|
|
112
|
+
}
|
|
113
|
+
|
|
34
114
|
export const toWebAuthnSigner = async <
|
|
35
115
|
TTransport extends Transport = Transport,
|
|
36
116
|
TChain extends Chain | undefined = Chain | undefined
|
|
@@ -38,118 +118,18 @@ export const toWebAuthnSigner = async <
|
|
|
38
118
|
client: Client<TTransport, TChain, undefined>,
|
|
39
119
|
{
|
|
40
120
|
signerContractAddress = WEBAUTHN_SIGNER_CONTRACT,
|
|
41
|
-
passkeyServerUrl,
|
|
42
121
|
webAuthnKey
|
|
43
122
|
}: WebAuthnModularSignerParams
|
|
44
123
|
): Promise<ModularSigner> => {
|
|
45
124
|
const chainId = await getChainId(client)
|
|
46
125
|
|
|
47
|
-
const signMessageUsingWebAuthn = async (message: SignableMessage) => {
|
|
48
|
-
let messageContent: string
|
|
49
|
-
if (typeof message === "string") {
|
|
50
|
-
// message is a string
|
|
51
|
-
messageContent = message
|
|
52
|
-
} else if ("raw" in message && typeof message.raw === "string") {
|
|
53
|
-
// message.raw is a Hex string
|
|
54
|
-
messageContent = message.raw
|
|
55
|
-
} else if ("raw" in message && message.raw instanceof Uint8Array) {
|
|
56
|
-
// message.raw is a ByteArray
|
|
57
|
-
messageContent = message.raw.toString()
|
|
58
|
-
} else {
|
|
59
|
-
throw new Error("Unsupported message format")
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// remove 0x prefix if present
|
|
63
|
-
const formattedMessage = messageContent.startsWith("0x")
|
|
64
|
-
? messageContent.slice(2)
|
|
65
|
-
: messageContent
|
|
66
|
-
|
|
67
|
-
if (window.sessionStorage === undefined) {
|
|
68
|
-
throw new Error("sessionStorage is not available")
|
|
69
|
-
}
|
|
70
|
-
const userId = sessionStorage.getItem("userId")
|
|
71
|
-
|
|
72
|
-
// initiate signing
|
|
73
|
-
const signInitiateResponse = await fetch(
|
|
74
|
-
`${passkeyServerUrl}/sign-initiate`,
|
|
75
|
-
{
|
|
76
|
-
method: "POST",
|
|
77
|
-
headers: { "Content-Type": "application/json" },
|
|
78
|
-
body: JSON.stringify({ data: formattedMessage, userId }),
|
|
79
|
-
credentials: "include"
|
|
80
|
-
}
|
|
81
|
-
)
|
|
82
|
-
const signInitiateResult = await signInitiateResponse.json()
|
|
83
|
-
|
|
84
|
-
// prepare assertion options
|
|
85
|
-
const assertionOptions: PublicKeyCredentialRequestOptionsJSON = {
|
|
86
|
-
challenge: signInitiateResult.challenge,
|
|
87
|
-
allowCredentials: signInitiateResult.allowCredentials,
|
|
88
|
-
userVerification: "required"
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// start authentication (signing)
|
|
92
|
-
|
|
93
|
-
const { startAuthentication } = await import("@simplewebauthn/browser")
|
|
94
|
-
const cred = await startAuthentication(assertionOptions)
|
|
95
|
-
|
|
96
|
-
// verify signature from server
|
|
97
|
-
const verifyResponse = await fetch(`${passkeyServerUrl}/sign-verify`, {
|
|
98
|
-
method: "POST",
|
|
99
|
-
headers: { "Content-Type": "application/json" },
|
|
100
|
-
body: JSON.stringify({ cred, userId }),
|
|
101
|
-
credentials: "include"
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
const verifyResult = await verifyResponse.json()
|
|
105
|
-
|
|
106
|
-
if (!verifyResult.success) {
|
|
107
|
-
throw new Error("Signature not verified")
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// get authenticator data
|
|
111
|
-
const authenticatorData = verifyResult.authenticatorData
|
|
112
|
-
const authenticatorDataHex = uint8ArrayToHexString(
|
|
113
|
-
b64ToBytes(authenticatorData)
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
// get client data JSON
|
|
117
|
-
const clientDataJSON = atob(cred.response.clientDataJSON)
|
|
118
|
-
|
|
119
|
-
// get challenge and response type location
|
|
120
|
-
const { beforeType } = findQuoteIndices(clientDataJSON)
|
|
121
|
-
|
|
122
|
-
// get signature r,s
|
|
123
|
-
const signature = verifyResult.signature
|
|
124
|
-
const signatureHex = uint8ArrayToHexString(b64ToBytes(signature))
|
|
125
|
-
const { r, s } = parseAndNormalizeSig(signatureHex)
|
|
126
|
-
|
|
127
|
-
// encode signature
|
|
128
|
-
const encodedSignature = encodeAbiParameters(
|
|
129
|
-
[
|
|
130
|
-
{ name: "authenticatorData", type: "bytes" },
|
|
131
|
-
{ name: "clientDataJSON", type: "string" },
|
|
132
|
-
{ name: "responseTypeLocation", type: "uint256" },
|
|
133
|
-
{ name: "r", type: "uint256" },
|
|
134
|
-
{ name: "s", type: "uint256" },
|
|
135
|
-
{ name: "usePrecompiled", type: "bool" }
|
|
136
|
-
],
|
|
137
|
-
[
|
|
138
|
-
authenticatorDataHex,
|
|
139
|
-
clientDataJSON,
|
|
140
|
-
beforeType,
|
|
141
|
-
BigInt(r),
|
|
142
|
-
BigInt(s),
|
|
143
|
-
isRIP7212SupportedNetwork(chainId)
|
|
144
|
-
]
|
|
145
|
-
)
|
|
146
|
-
return encodedSignature
|
|
147
|
-
}
|
|
148
126
|
const account: LocalAccount = toAccount({
|
|
149
127
|
// note that this address will be overwritten by actual address
|
|
150
128
|
address: "0x0000000000000000000000000000000000000000",
|
|
151
129
|
async signMessage({ message }) {
|
|
152
|
-
return signMessageUsingWebAuthn(message
|
|
130
|
+
return signMessageUsingWebAuthn(message, chainId, [
|
|
131
|
+
{ id: webAuthnKey.authenticatorId, type: "public-key" }
|
|
132
|
+
])
|
|
153
133
|
},
|
|
154
134
|
async signTransaction(_, __) {
|
|
155
135
|
throw new SignTransactionNotSupportedBySmartAccount()
|
|
@@ -171,7 +151,11 @@ export const toWebAuthnSigner = async <
|
|
|
171
151
|
validateTypedData({ domain, message, primaryType, types })
|
|
172
152
|
|
|
173
153
|
const hash = hashTypedData(typedData)
|
|
174
|
-
|
|
154
|
+
const signature = await signMessage(client, {
|
|
155
|
+
account,
|
|
156
|
+
message: hash
|
|
157
|
+
})
|
|
158
|
+
return signature
|
|
175
159
|
}
|
|
176
160
|
})
|
|
177
161
|
|
|
@@ -209,7 +193,7 @@ export const toWebAuthnSigner = async <
|
|
|
209
193
|
],
|
|
210
194
|
[
|
|
211
195
|
"0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97631d00000000",
|
|
212
|
-
'{"type":"webauthn.get","challenge":"tbxXNFS9X_4Byr1cMwqKrIGB-_30a0QhZ6y7ucM0BOE","origin":"http://localhost:3000","crossOrigin":false}',
|
|
196
|
+
'{"type":"webauthn.get","challenge":"tbxXNFS9X_4Byr1cMwqKrIGB-_30a0QhZ6y7ucM0BOE","origin":"http://localhost:3000","crossOrigin":false, "other_keys_can_be_added_here":"do not compare clientDataJSON against a template. See https://goo.gl/yabPex"}',
|
|
213
197
|
1n,
|
|
214
198
|
44941127272049826721201904734628716258498742255959991581049806490182030242267n,
|
|
215
199
|
9910254599581058084911561569808925251374718953855182016200087235935345969636n,
|
package/types.ts
CHANGED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toWebAuthnKey = exports.WebAuthnMode = void 0;
|
|
4
|
-
const buffer_1 = require("buffer");
|
|
5
|
-
const viem_1 = require("viem");
|
|
6
|
-
const webAuthnUtils_js_1 = require("./webAuthnUtils.js");
|
|
7
|
-
var WebAuthnMode;
|
|
8
|
-
(function (WebAuthnMode) {
|
|
9
|
-
WebAuthnMode["Register"] = "register";
|
|
10
|
-
WebAuthnMode["Login"] = "login";
|
|
11
|
-
})(WebAuthnMode || (exports.WebAuthnMode = WebAuthnMode = {}));
|
|
12
|
-
const toWebAuthnKey = async ({ passkeyName, passkeyServerUrl, webAuthnKey, mode = WebAuthnMode.Login }) => {
|
|
13
|
-
if (webAuthnKey) {
|
|
14
|
-
return webAuthnKey;
|
|
15
|
-
}
|
|
16
|
-
let pubKey;
|
|
17
|
-
let authenticatorIdHash;
|
|
18
|
-
if (mode === WebAuthnMode.Login) {
|
|
19
|
-
const loginOptionsResponse = await fetch(`${passkeyServerUrl}/login/options`, {
|
|
20
|
-
method: "POST",
|
|
21
|
-
headers: { "Content-Type": "application/json" },
|
|
22
|
-
credentials: "include"
|
|
23
|
-
});
|
|
24
|
-
const loginOptions = await loginOptionsResponse.json();
|
|
25
|
-
const { startAuthentication } = await Promise.resolve().then(() => require("@simplewebauthn/browser"));
|
|
26
|
-
const loginCred = await startAuthentication(loginOptions);
|
|
27
|
-
authenticatorIdHash = (0, viem_1.keccak256)((0, webAuthnUtils_js_1.uint8ArrayToHexString)((0, webAuthnUtils_js_1.b64ToBytes)(loginCred.id)));
|
|
28
|
-
const loginVerifyResponse = await fetch(`${passkeyServerUrl}/login/verify`, {
|
|
29
|
-
method: "POST",
|
|
30
|
-
headers: { "Content-Type": "application/json" },
|
|
31
|
-
body: JSON.stringify({ cred: loginCred }),
|
|
32
|
-
credentials: "include"
|
|
33
|
-
});
|
|
34
|
-
const loginVerifyResult = await loginVerifyResponse.json();
|
|
35
|
-
if (window.sessionStorage === undefined) {
|
|
36
|
-
throw new Error("sessionStorage is not available");
|
|
37
|
-
}
|
|
38
|
-
sessionStorage.setItem("userId", loginVerifyResult.userId);
|
|
39
|
-
if (!loginVerifyResult.verification.verified) {
|
|
40
|
-
throw new Error("Login not verified");
|
|
41
|
-
}
|
|
42
|
-
pubKey = loginVerifyResult.pubkey;
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
if (!passkeyName) {
|
|
46
|
-
throw new Error("No passkey name provided");
|
|
47
|
-
}
|
|
48
|
-
const registerOptionsResponse = await fetch(`${passkeyServerUrl}/register/options`, {
|
|
49
|
-
method: "POST",
|
|
50
|
-
headers: {
|
|
51
|
-
"Content-Type": "application/json"
|
|
52
|
-
},
|
|
53
|
-
body: JSON.stringify({ username: passkeyName }),
|
|
54
|
-
credentials: "include"
|
|
55
|
-
});
|
|
56
|
-
const registerOptions = await registerOptionsResponse.json();
|
|
57
|
-
if (window.sessionStorage === undefined) {
|
|
58
|
-
throw new Error("sessionStorage is not available");
|
|
59
|
-
}
|
|
60
|
-
sessionStorage.setItem("userId", registerOptions.userId);
|
|
61
|
-
const { startRegistration } = await Promise.resolve().then(() => require("@simplewebauthn/browser"));
|
|
62
|
-
const registerCred = await startRegistration(registerOptions.options);
|
|
63
|
-
authenticatorIdHash = (0, viem_1.keccak256)((0, webAuthnUtils_js_1.uint8ArrayToHexString)((0, webAuthnUtils_js_1.b64ToBytes)(registerCred.id)));
|
|
64
|
-
const registerVerifyResponse = await fetch(`${passkeyServerUrl}/register/verify`, {
|
|
65
|
-
method: "POST",
|
|
66
|
-
headers: {
|
|
67
|
-
"Content-Type": "application/json"
|
|
68
|
-
},
|
|
69
|
-
body: JSON.stringify({
|
|
70
|
-
userId: registerOptions.userId,
|
|
71
|
-
username: passkeyName,
|
|
72
|
-
cred: registerCred
|
|
73
|
-
}),
|
|
74
|
-
credentials: "include"
|
|
75
|
-
});
|
|
76
|
-
const registerVerifyResult = await registerVerifyResponse.json();
|
|
77
|
-
if (!registerVerifyResult.verified) {
|
|
78
|
-
throw new Error("Registration not verified");
|
|
79
|
-
}
|
|
80
|
-
pubKey = registerCred.response.publicKey;
|
|
81
|
-
}
|
|
82
|
-
if (!pubKey) {
|
|
83
|
-
throw new Error("No public key returned from registration credential");
|
|
84
|
-
}
|
|
85
|
-
const spkiDer = buffer_1.Buffer.from(pubKey, "base64");
|
|
86
|
-
const key = await crypto.subtle.importKey("spki", spkiDer, {
|
|
87
|
-
name: "ECDSA",
|
|
88
|
-
namedCurve: "P-256"
|
|
89
|
-
}, true, ["verify"]);
|
|
90
|
-
const rawKey = await crypto.subtle.exportKey("raw", key);
|
|
91
|
-
const rawKeyBuffer = buffer_1.Buffer.from(rawKey);
|
|
92
|
-
const pubKeyX = rawKeyBuffer.subarray(1, 33).toString("hex");
|
|
93
|
-
const pubKeyY = rawKeyBuffer.subarray(33).toString("hex");
|
|
94
|
-
return {
|
|
95
|
-
pubX: BigInt(`0x${pubKeyX}`),
|
|
96
|
-
pubY: BigInt(`0x${pubKeyY}`),
|
|
97
|
-
authenticatorIdHash
|
|
98
|
-
};
|
|
99
|
-
};
|
|
100
|
-
exports.toWebAuthnKey = toWebAuthnKey;
|
|
101
|
-
//# sourceMappingURL=toWebAuthnKey.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toWebAuthnKey.js","sourceRoot":"","sources":["../../signers/toWebAuthnKey.ts"],"names":[],"mappings":";;;AAAA,mCAA+B;AAC/B,+BAA0C;AAC1C,yDAAsE;AAEtE,IAAY,YAGX;AAHD,WAAY,YAAY;IACpB,qCAAqB,CAAA;IACrB,+BAAe,CAAA;AACnB,CAAC,EAHW,YAAY,4BAAZ,YAAY,QAGvB;AAQM,MAAM,aAAa,GAAG,KAAK,EAAE,EAChC,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,IAAI,GAAG,YAAY,CAAC,KAAK,EAM5B,EAAwB,EAAE;IACvB,IAAI,WAAW,EAAE,CAAC;QACd,OAAO,WAAW,CAAA;IACtB,CAAC;IACD,IAAI,MAA0B,CAAA;IAC9B,IAAI,mBAAwB,CAAA;IAC5B,IAAI,IAAI,KAAK,YAAY,CAAC,KAAK,EAAE,CAAC;QAE9B,MAAM,oBAAoB,GAAG,MAAM,KAAK,CACpC,GAAG,gBAAgB,gBAAgB,EACnC;YACI,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,WAAW,EAAE,SAAS;SACzB,CACJ,CAAA;QACD,MAAM,YAAY,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,CAAA;QAGtD,MAAM,EAAE,mBAAmB,EAAE,GAAG,2CAAa,yBAAyB,EAAC,CAAA;QACvE,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,YAAY,CAAC,CAAA;QAGzD,mBAAmB,GAAG,IAAA,gBAAS,EAC3B,IAAA,wCAAqB,EAAC,IAAA,6BAAU,EAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAClD,CAAA;QAGD,MAAM,mBAAmB,GAAG,MAAM,KAAK,CACnC,GAAG,gBAAgB,eAAe,EAClC;YACI,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YACzC,WAAW,EAAE,SAAS;SACzB,CACJ,CAAA;QAED,MAAM,iBAAiB,GAAG,MAAM,mBAAmB,CAAC,IAAI,EAAE,CAAA;QAE1D,IAAI,MAAM,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;QACtD,CAAC;QACD,cAAc,CAAC,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAA;QAE1D,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;QACzC,CAAC;QAED,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAA;IACrC,CAAC;SAAM,CAAC;QACJ,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;QAC/C,CAAC;QAED,MAAM,uBAAuB,GAAG,MAAM,KAAK,CACvC,GAAG,gBAAgB,mBAAmB,EACtC;YACI,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;aACrC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;YAC/C,WAAW,EAAE,SAAS;SACzB,CACJ,CAAA;QACD,MAAM,eAAe,GAAG,MAAM,uBAAuB,CAAC,IAAI,EAAE,CAAA;QAG5D,IAAI,MAAM,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;QACtD,CAAC;QACD,cAAc,CAAC,OAAO,CAAC,QAAQ,EAAE,eAAe,CAAC,MAAM,CAAC,CAAA;QAGxD,MAAM,EAAE,iBAAiB,EAAE,GAAG,2CAAa,yBAAyB,EAAC,CAAA;QACrE,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;QAGrE,mBAAmB,GAAG,IAAA,gBAAS,EAC3B,IAAA,wCAAqB,EAAC,IAAA,6BAAU,EAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CACrD,CAAA;QAGD,MAAM,sBAAsB,GAAG,MAAM,KAAK,CACtC,GAAG,gBAAgB,kBAAkB,EACrC;YACI,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;aACrC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACjB,MAAM,EAAE,eAAe,CAAC,MAAM;gBAC9B,QAAQ,EAAE,WAAW;gBACrB,IAAI,EAAE,YAAY;aACrB,CAAC;YACF,WAAW,EAAE,SAAS;SACzB,CACJ,CAAA;QAED,MAAM,oBAAoB,GAAG,MAAM,sBAAsB,CAAC,IAAI,EAAE,CAAA;QAChE,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;QAChD,CAAC;QAGD,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAA;IAC5C,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAA;IAC1E,CAAC;IAED,MAAM,OAAO,GAAG,eAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAC7C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACrC,MAAM,EACN,OAAO,EACP;QACI,IAAI,EAAE,OAAO;QACb,UAAU,EAAE,OAAO;KACtB,EACD,IAAI,EACJ,CAAC,QAAQ,CAAC,CACb,CAAA;IAGD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACxD,MAAM,YAAY,GAAG,eAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAGxC,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC5D,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEzD,OAAO;QACH,IAAI,EAAE,MAAM,CAAC,KAAK,OAAO,EAAE,CAAC;QAC5B,IAAI,EAAE,MAAM,CAAC,KAAK,OAAO,EAAE,CAAC;QAC5B,mBAAmB;KACtB,CAAA;AACL,CAAC,CAAA;AAnJY,QAAA,aAAa,iBAmJzB"}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isRIP7212SupportedNetwork = exports.parseAndNormalizeSig = exports.findQuoteIndices = exports.b64ToBytes = exports.uint8ArrayToHexString = void 0;
|
|
4
|
-
const p256_1 = require("@noble/curves/p256");
|
|
5
|
-
const viem_1 = require("viem");
|
|
6
|
-
const RIP7212_SUPPORTED_NETWORKS = [80001];
|
|
7
|
-
const uint8ArrayToHexString = (array) => {
|
|
8
|
-
return `0x${Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
|
|
9
|
-
};
|
|
10
|
-
exports.uint8ArrayToHexString = uint8ArrayToHexString;
|
|
11
|
-
const b64ToBytes = (base64) => {
|
|
12
|
-
const paddedBase64 = base64
|
|
13
|
-
.replace(/-/g, "+")
|
|
14
|
-
.replace(/_/g, "/")
|
|
15
|
-
.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), "=");
|
|
16
|
-
const binString = atob(paddedBase64);
|
|
17
|
-
return Uint8Array.from(binString, (m) => m.codePointAt(0) ?? 0);
|
|
18
|
-
};
|
|
19
|
-
exports.b64ToBytes = b64ToBytes;
|
|
20
|
-
const findQuoteIndices = (input) => {
|
|
21
|
-
const beforeTypeIndex = BigInt(input.lastIndexOf('"type":"webauthn.get"'));
|
|
22
|
-
const beforeChallengeIndex = BigInt(input.indexOf('"challenge'));
|
|
23
|
-
return {
|
|
24
|
-
beforeType: beforeTypeIndex,
|
|
25
|
-
beforeChallenge: beforeChallengeIndex
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
exports.findQuoteIndices = findQuoteIndices;
|
|
29
|
-
function parseAndNormalizeSig(derSig) {
|
|
30
|
-
const parsedSignature = p256_1.p256.Signature.fromDER(derSig.slice(2));
|
|
31
|
-
const bSig = (0, viem_1.hexToBytes)(`0x${parsedSignature.toCompactHex()}`);
|
|
32
|
-
const bR = bSig.slice(0, 32);
|
|
33
|
-
const bS = bSig.slice(32);
|
|
34
|
-
const r = (0, viem_1.bytesToBigInt)(bR);
|
|
35
|
-
let s = (0, viem_1.bytesToBigInt)(bS);
|
|
36
|
-
const n = BigInt("0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
|
|
37
|
-
if (s > n / 2n) {
|
|
38
|
-
s = n - s;
|
|
39
|
-
}
|
|
40
|
-
return { r, s };
|
|
41
|
-
}
|
|
42
|
-
exports.parseAndNormalizeSig = parseAndNormalizeSig;
|
|
43
|
-
const isRIP7212SupportedNetwork = (chainId) => RIP7212_SUPPORTED_NETWORKS.includes(chainId);
|
|
44
|
-
exports.isRIP7212SupportedNetwork = isRIP7212SupportedNetwork;
|
|
45
|
-
//# sourceMappingURL=webAuthnUtils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webAuthnUtils.js","sourceRoot":"","sources":["../../signers/webAuthnUtils.ts"],"names":[],"mappings":";;;AAAA,6CAAyC;AACzC,+BAA0D;AAE1D,MAAM,0BAA0B,GAAG,CAAC,KAAK,CAAC,CAAA;AAEnC,MAAM,qBAAqB,GAAG,CAAC,KAAiB,EAAiB,EAAE;IACtE,OAAO,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CACnC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CACrC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAmB,CAAA;AACjC,CAAC,CAAA;AAJY,QAAA,qBAAqB,yBAIjC;AAEM,MAAM,UAAU,GAAG,CAAC,MAAc,EAAc,EAAE;IACrD,MAAM,YAAY,GAAG,MAAM;SACtB,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;SAClB,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;SAClB,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACjE,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,CAAA;IACpC,OAAO,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;AACnE,CAAC,CAAA;AAPY,QAAA,UAAU,cAOtB;AAEM,MAAM,gBAAgB,GAAG,CAC5B,KAAa,EACkC,EAAE;IACjD,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC,CAAA;IAC1E,MAAM,oBAAoB,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAA;IAChE,OAAO;QACH,UAAU,EAAE,eAAe;QAC3B,eAAe,EAAE,oBAAoB;KACxC,CAAA;AACL,CAAC,CAAA;AATY,QAAA,gBAAgB,oBAS5B;AAID,SAAgB,oBAAoB,CAAC,MAAW;IAC5C,MAAM,eAAe,GAAG,WAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAC/D,MAAM,IAAI,GAAG,IAAA,iBAAU,EAAC,KAAK,eAAe,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;IAE9D,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAC5B,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAGzB,MAAM,CAAC,GAAG,IAAA,oBAAa,EAAC,EAAE,CAAC,CAAA;IAC3B,IAAI,CAAC,GAAG,IAAA,oBAAa,EAAC,EAAE,CAAC,CAAA;IACzB,MAAM,CAAC,GAAG,MAAM,CACZ,oEAAoE,CACvE,CAAA;IACD,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC;QACb,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACb,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;AACnB,CAAC;AAjBD,oDAiBC;AAEM,MAAM,yBAAyB,GAAG,CAAC,OAAe,EAAW,EAAE,CAClE,0BAA0B,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;AADnC,QAAA,yBAAyB,6BACU"}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { Buffer } from "buffer";
|
|
2
|
-
import { keccak256 } from "viem";
|
|
3
|
-
import { b64ToBytes, uint8ArrayToHexString } from "./webAuthnUtils.js";
|
|
4
|
-
export var WebAuthnMode;
|
|
5
|
-
(function (WebAuthnMode) {
|
|
6
|
-
WebAuthnMode["Register"] = "register";
|
|
7
|
-
WebAuthnMode["Login"] = "login";
|
|
8
|
-
})(WebAuthnMode || (WebAuthnMode = {}));
|
|
9
|
-
export const toWebAuthnKey = async ({ passkeyName, passkeyServerUrl, webAuthnKey, mode = WebAuthnMode.Login }) => {
|
|
10
|
-
if (webAuthnKey) {
|
|
11
|
-
return webAuthnKey;
|
|
12
|
-
}
|
|
13
|
-
let pubKey;
|
|
14
|
-
let authenticatorIdHash;
|
|
15
|
-
if (mode === WebAuthnMode.Login) {
|
|
16
|
-
// Get login options
|
|
17
|
-
const loginOptionsResponse = await fetch(`${passkeyServerUrl}/login/options`, {
|
|
18
|
-
method: "POST",
|
|
19
|
-
headers: { "Content-Type": "application/json" },
|
|
20
|
-
credentials: "include"
|
|
21
|
-
});
|
|
22
|
-
const loginOptions = await loginOptionsResponse.json();
|
|
23
|
-
// Start authentication (login)
|
|
24
|
-
const { startAuthentication } = await import("@simplewebauthn/browser");
|
|
25
|
-
const loginCred = await startAuthentication(loginOptions);
|
|
26
|
-
// get authenticatorIdHash
|
|
27
|
-
authenticatorIdHash = keccak256(uint8ArrayToHexString(b64ToBytes(loginCred.id)));
|
|
28
|
-
// Verify authentication
|
|
29
|
-
const loginVerifyResponse = await fetch(`${passkeyServerUrl}/login/verify`, {
|
|
30
|
-
method: "POST",
|
|
31
|
-
headers: { "Content-Type": "application/json" },
|
|
32
|
-
body: JSON.stringify({ cred: loginCred }),
|
|
33
|
-
credentials: "include"
|
|
34
|
-
});
|
|
35
|
-
const loginVerifyResult = await loginVerifyResponse.json();
|
|
36
|
-
if (window.sessionStorage === undefined) {
|
|
37
|
-
throw new Error("sessionStorage is not available");
|
|
38
|
-
}
|
|
39
|
-
sessionStorage.setItem("userId", loginVerifyResult.userId);
|
|
40
|
-
if (!loginVerifyResult.verification.verified) {
|
|
41
|
-
throw new Error("Login not verified");
|
|
42
|
-
}
|
|
43
|
-
// Import the key
|
|
44
|
-
pubKey = loginVerifyResult.pubkey; // Uint8Array pubkey
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
if (!passkeyName) {
|
|
48
|
-
throw new Error("No passkey name provided");
|
|
49
|
-
}
|
|
50
|
-
// Get registration options
|
|
51
|
-
const registerOptionsResponse = await fetch(`${passkeyServerUrl}/register/options`, {
|
|
52
|
-
method: "POST",
|
|
53
|
-
headers: {
|
|
54
|
-
"Content-Type": "application/json"
|
|
55
|
-
},
|
|
56
|
-
body: JSON.stringify({ username: passkeyName }),
|
|
57
|
-
credentials: "include"
|
|
58
|
-
});
|
|
59
|
-
const registerOptions = await registerOptionsResponse.json();
|
|
60
|
-
// save userId to sessionStorage
|
|
61
|
-
if (window.sessionStorage === undefined) {
|
|
62
|
-
throw new Error("sessionStorage is not available");
|
|
63
|
-
}
|
|
64
|
-
sessionStorage.setItem("userId", registerOptions.userId);
|
|
65
|
-
// Start registration
|
|
66
|
-
const { startRegistration } = await import("@simplewebauthn/browser");
|
|
67
|
-
const registerCred = await startRegistration(registerOptions.options);
|
|
68
|
-
// get authenticatorIdHash
|
|
69
|
-
authenticatorIdHash = keccak256(uint8ArrayToHexString(b64ToBytes(registerCred.id)));
|
|
70
|
-
// Verify registration
|
|
71
|
-
const registerVerifyResponse = await fetch(`${passkeyServerUrl}/register/verify`, {
|
|
72
|
-
method: "POST",
|
|
73
|
-
headers: {
|
|
74
|
-
"Content-Type": "application/json"
|
|
75
|
-
},
|
|
76
|
-
body: JSON.stringify({
|
|
77
|
-
userId: registerOptions.userId,
|
|
78
|
-
username: passkeyName,
|
|
79
|
-
cred: registerCred
|
|
80
|
-
}),
|
|
81
|
-
credentials: "include"
|
|
82
|
-
});
|
|
83
|
-
const registerVerifyResult = await registerVerifyResponse.json();
|
|
84
|
-
if (!registerVerifyResult.verified) {
|
|
85
|
-
throw new Error("Registration not verified");
|
|
86
|
-
}
|
|
87
|
-
// Import the key
|
|
88
|
-
pubKey = registerCred.response.publicKey;
|
|
89
|
-
}
|
|
90
|
-
if (!pubKey) {
|
|
91
|
-
throw new Error("No public key returned from registration credential");
|
|
92
|
-
}
|
|
93
|
-
const spkiDer = Buffer.from(pubKey, "base64");
|
|
94
|
-
const key = await crypto.subtle.importKey("spki", spkiDer, {
|
|
95
|
-
name: "ECDSA",
|
|
96
|
-
namedCurve: "P-256"
|
|
97
|
-
}, true, ["verify"]);
|
|
98
|
-
// Export the key to the raw format
|
|
99
|
-
const rawKey = await crypto.subtle.exportKey("raw", key);
|
|
100
|
-
const rawKeyBuffer = Buffer.from(rawKey);
|
|
101
|
-
// The first byte is 0x04 (uncompressed), followed by x and y coordinates (32 bytes each for P-256)
|
|
102
|
-
const pubKeyX = rawKeyBuffer.subarray(1, 33).toString("hex");
|
|
103
|
-
const pubKeyY = rawKeyBuffer.subarray(33).toString("hex");
|
|
104
|
-
return {
|
|
105
|
-
pubX: BigInt(`0x${pubKeyX}`),
|
|
106
|
-
pubY: BigInt(`0x${pubKeyY}`),
|
|
107
|
-
authenticatorIdHash
|
|
108
|
-
};
|
|
109
|
-
};
|
|
110
|
-
//# sourceMappingURL=toWebAuthnKey.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toWebAuthnKey.js","sourceRoot":"","sources":["../../signers/toWebAuthnKey.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { p256 } from "@noble/curves/p256";
|
|
2
|
-
import { bytesToBigInt, hexToBytes } from "viem";
|
|
3
|
-
const RIP7212_SUPPORTED_NETWORKS = [80001];
|
|
4
|
-
export const uint8ArrayToHexString = (array) => {
|
|
5
|
-
return `0x${Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
|
|
6
|
-
};
|
|
7
|
-
export const b64ToBytes = (base64) => {
|
|
8
|
-
const paddedBase64 = base64
|
|
9
|
-
.replace(/-/g, "+")
|
|
10
|
-
.replace(/_/g, "/")
|
|
11
|
-
.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), "=");
|
|
12
|
-
const binString = atob(paddedBase64);
|
|
13
|
-
return Uint8Array.from(binString, (m) => m.codePointAt(0) ?? 0);
|
|
14
|
-
};
|
|
15
|
-
export const findQuoteIndices = (input) => {
|
|
16
|
-
const beforeTypeIndex = BigInt(input.lastIndexOf('"type":"webauthn.get"'));
|
|
17
|
-
const beforeChallengeIndex = BigInt(input.indexOf('"challenge'));
|
|
18
|
-
return {
|
|
19
|
-
beforeType: beforeTypeIndex,
|
|
20
|
-
beforeChallenge: beforeChallengeIndex
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
// Parse DER-encoded P256-SHA256 signature to contract-friendly signature
|
|
24
|
-
// and normalize it so the signature is not malleable.
|
|
25
|
-
export function parseAndNormalizeSig(derSig) {
|
|
26
|
-
const parsedSignature = p256.Signature.fromDER(derSig.slice(2));
|
|
27
|
-
const bSig = hexToBytes(`0x${parsedSignature.toCompactHex()}`);
|
|
28
|
-
// assert(bSig.length === 64, "signature is not 64 bytes");
|
|
29
|
-
const bR = bSig.slice(0, 32);
|
|
30
|
-
const bS = bSig.slice(32);
|
|
31
|
-
// Avoid malleability. Ensure low S (<= N/2 where N is the curve order)
|
|
32
|
-
const r = bytesToBigInt(bR);
|
|
33
|
-
let s = bytesToBigInt(bS);
|
|
34
|
-
const n = BigInt("0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
|
|
35
|
-
if (s > n / 2n) {
|
|
36
|
-
s = n - s;
|
|
37
|
-
}
|
|
38
|
-
return { r, s };
|
|
39
|
-
}
|
|
40
|
-
export const isRIP7212SupportedNetwork = (chainId) => RIP7212_SUPPORTED_NETWORKS.includes(chainId);
|
|
41
|
-
//# sourceMappingURL=webAuthnUtils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webAuthnUtils.js","sourceRoot":"","sources":["../../signers/webAuthnUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAAY,aAAa,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AAE1D,MAAM,0BAA0B,GAAG,CAAC,KAAK,CAAC,CAAA;AAE1C,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAiB,EAAiB,EAAE;IACtE,OAAO,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CACnC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CACrC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAmB,CAAA;AACjC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAc,EAAc,EAAE;IACrD,MAAM,YAAY,GAAG,MAAM;SACtB,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;SAClB,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;SAClB,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACjE,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,CAAA;IACpC,OAAO,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;AACnE,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC5B,KAAa,EACkC,EAAE;IACjD,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC,CAAA;IAC1E,MAAM,oBAAoB,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAA;IAChE,OAAO;QACH,UAAU,EAAE,eAAe;QAC3B,eAAe,EAAE,oBAAoB;KACxC,CAAA;AACL,CAAC,CAAA;AAED,yEAAyE;AACzE,sDAAsD;AACtD,MAAM,UAAU,oBAAoB,CAAC,MAAW;IAC5C,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAC/D,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,eAAe,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;IAC9D,2DAA2D;IAC3D,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAC5B,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAEzB,uEAAuE;IACvE,MAAM,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,CAAA;IAC3B,IAAI,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,CAAA;IACzB,MAAM,CAAC,GAAG,MAAM,CACZ,oEAAoE,CACvE,CAAA;IACD,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC;QACb,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACb,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,OAAe,EAAW,EAAE,CAClE,0BAA0B,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { type Hex } from "viem";
|
|
2
|
-
export declare enum WebAuthnMode {
|
|
3
|
-
Register = "register",
|
|
4
|
-
Login = "login"
|
|
5
|
-
}
|
|
6
|
-
export type WebAuthnKey = {
|
|
7
|
-
pubX: bigint;
|
|
8
|
-
pubY: bigint;
|
|
9
|
-
authenticatorIdHash: Hex;
|
|
10
|
-
};
|
|
11
|
-
export declare const toWebAuthnKey: ({ passkeyName, passkeyServerUrl, webAuthnKey, mode }: {
|
|
12
|
-
passkeyName: string;
|
|
13
|
-
passkeyServerUrl: string;
|
|
14
|
-
webAuthnKey?: WebAuthnKey | undefined;
|
|
15
|
-
mode: WebAuthnMode;
|
|
16
|
-
}) => Promise<WebAuthnKey>;
|
|
17
|
-
//# sourceMappingURL=toWebAuthnKey.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toWebAuthnKey.d.ts","sourceRoot":"","sources":["../../signers/toWebAuthnKey.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,GAAG,EAAa,MAAM,MAAM,CAAA;AAG1C,oBAAY,YAAY;IACpB,QAAQ,aAAa;IACrB,KAAK,UAAU;CAClB;AAED,MAAM,MAAM,WAAW,GAAG;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,mBAAmB,EAAE,GAAG,CAAA;CAC3B,CAAA;AAED,eAAO,MAAM,aAAa;iBAMT,MAAM;sBACD,MAAM;;UAElB,YAAY;MAClB,QAAQ,WAAW,CAyItB,CAAA"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { type Hex } from "viem";
|
|
2
|
-
export declare const uint8ArrayToHexString: (array: Uint8Array) => `0x${string}`;
|
|
3
|
-
export declare const b64ToBytes: (base64: string) => Uint8Array;
|
|
4
|
-
export declare const findQuoteIndices: (input: string) => {
|
|
5
|
-
beforeType: bigint;
|
|
6
|
-
beforeChallenge: bigint;
|
|
7
|
-
};
|
|
8
|
-
export declare function parseAndNormalizeSig(derSig: Hex): {
|
|
9
|
-
r: bigint;
|
|
10
|
-
s: bigint;
|
|
11
|
-
};
|
|
12
|
-
export declare const isRIP7212SupportedNetwork: (chainId: number) => boolean;
|
|
13
|
-
//# sourceMappingURL=webAuthnUtils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webAuthnUtils.d.ts","sourceRoot":"","sources":["../../signers/webAuthnUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,GAAG,EAA6B,MAAM,MAAM,CAAA;AAI1D,eAAO,MAAM,qBAAqB,UAAW,UAAU,KAAG,KAAK,MAAM,EAIpE,CAAA;AAED,eAAO,MAAM,UAAU,WAAY,MAAM,KAAG,UAO3C,CAAA;AAED,eAAO,MAAM,gBAAgB,UAClB,MAAM,KACd;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAO/C,CAAA;AAID,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,GAAG,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAiB1E;AAED,eAAO,MAAM,yBAAyB,YAAa,MAAM,KAAG,OACZ,CAAA"}
|