@explorins/pers-signer 1.0.27 → 1.0.31
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/dist/browser.cjs.js +64 -38
- package/dist/browser.cjs.js.map +1 -1
- package/dist/browser.esm.js +64 -38
- package/dist/browser.esm.js.map +1 -1
- package/dist/index.cjs.js +75 -54
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +75 -54
- package/dist/index.esm.js.map +1 -1
- package/dist/react-native.cjs.js +75 -54
- package/dist/react-native.cjs.js.map +1 -1
- package/dist/react-native.esm.js +75 -54
- package/dist/react-native.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/browser.cjs.js
CHANGED
|
@@ -137,13 +137,11 @@ const SIGNER_CONFIG = {
|
|
|
137
137
|
* Used as fallback when production signer API is unavailable
|
|
138
138
|
*/
|
|
139
139
|
STAGING_SIGNER_API_URL: 'https://signer-api-staging.pers.ninja/v1',
|
|
140
|
-
// STAGING_SIGNER_API_URL: 'http://localhost:8080/v1',
|
|
141
140
|
/**
|
|
142
141
|
* PERS Platform API URLs
|
|
143
142
|
*/
|
|
144
143
|
DEFAULT_PERS_API_URL: 'https://api.pers.ninja/v2',
|
|
145
144
|
STAGING_PERS_API_URL: 'https://dev.api.pers.ninja/v2',
|
|
146
|
-
// STAGING_PERS_API_URL: 'https://explorins-loyalty.ngrok.io',
|
|
147
145
|
/**
|
|
148
146
|
* Default relying party name for WebAuthn operations
|
|
149
147
|
* This appears in the browser's authentication prompts
|
|
@@ -155,8 +153,31 @@ const SIGNER_CONFIG = {
|
|
|
155
153
|
*/
|
|
156
154
|
// Default fallback provider for Sepolia testnet (no API key required)
|
|
157
155
|
const DEFAULT_FALLBACK_PROVIDER = 'https://ethereum-sepolia.publicnode.com';
|
|
156
|
+
/**
|
|
157
|
+
* WebAuthn configuration constants
|
|
158
|
+
*/
|
|
159
|
+
const WEBAUTHN_CONFIG = {
|
|
160
|
+
/**
|
|
161
|
+
* Timeout for WebAuthn operations (in milliseconds)
|
|
162
|
+
*/
|
|
163
|
+
TIMEOUT: 60000,
|
|
164
|
+
/**
|
|
165
|
+
* User verification requirement
|
|
166
|
+
* 'preferred' - ask for verification if available
|
|
167
|
+
* 'required' - require verification
|
|
168
|
+
* 'discouraged' - don't ask for verification
|
|
169
|
+
*/
|
|
170
|
+
USER_VERIFICATION: 'preferred',
|
|
171
|
+
/**
|
|
172
|
+
* Resident key requirement (Passkeys)
|
|
173
|
+
*/
|
|
174
|
+
RESIDENT_KEY: 'required',
|
|
175
|
+
/**
|
|
176
|
+
* Authenticator attachment preference
|
|
177
|
+
*/
|
|
178
|
+
AUTHENTICATOR_ATTACHMENT: 'platform',
|
|
179
|
+
};
|
|
158
180
|
|
|
159
|
-
// import serviceState from '../core/ServiceState';
|
|
160
181
|
/**
|
|
161
182
|
* Detects the environment (Staging vs Production) based on the JWT token issuer.
|
|
162
183
|
* Updates the global service state accordingly.
|
|
@@ -170,16 +191,8 @@ function detectStagingEnvironmentFromToken(token) {
|
|
|
170
191
|
// Check if issuer matches staging URL
|
|
171
192
|
if (payload.iss === SIGNER_CONFIG.STAGING_PERS_API_URL
|
|
172
193
|
|| SIGNER_CONFIG.STAGING_PERS_API_URL.includes(payload.iss)
|
|
173
|
-
|| SIGNER_CONFIG.STAGING_SIGNER_API_URL.includes(payload.iss)
|
|
174
|
-
// Temporary additional checks for known staging issuers
|
|
175
|
-
// || 'https://signer-api-staging.pers.ninja'.includes(payload.iss)
|
|
176
|
-
// || 'https://dev.api.pers.ninja/v2'.includes(payload.iss)
|
|
177
|
-
) {
|
|
194
|
+
|| SIGNER_CONFIG.STAGING_SIGNER_API_URL.includes(payload.iss)) {
|
|
178
195
|
return true;
|
|
179
|
-
/* } else if (payload.iss === SIGNER_CONFIG.DEFAULT_PERS_API_URL ||
|
|
180
|
-
SIGNER_CONFIG.DEFAULT_PERS_API_URL.includes(payload.iss)) {
|
|
181
|
-
// Explicitly production
|
|
182
|
-
return false; */
|
|
183
196
|
}
|
|
184
197
|
}
|
|
185
198
|
return false;
|
|
@@ -1206,11 +1219,11 @@ class TransactionSigningService {
|
|
|
1206
1219
|
let provider;
|
|
1207
1220
|
try {
|
|
1208
1221
|
// Try primary provider first
|
|
1209
|
-
console.info(`[TransactionSigningService] Attempting to connect to primary provider: ${ethersProviderUrl}`);
|
|
1222
|
+
//console.info(`[TransactionSigningService] Attempting to connect to primary provider: ${ethersProviderUrl}`);
|
|
1210
1223
|
provider = new ethers.JsonRpcProvider(ethersProviderUrl);
|
|
1211
1224
|
// Test the connection with a simple call
|
|
1212
1225
|
await provider.getNetwork();
|
|
1213
|
-
console.info(`[TransactionSigningService] Successfully connected to primary provider`);
|
|
1226
|
+
//console.info(`[TransactionSigningService] Successfully connected to primary provider`);
|
|
1214
1227
|
}
|
|
1215
1228
|
catch (primaryError) {
|
|
1216
1229
|
console.warn(`[TransactionSigningService] Primary provider failed, falling back to: ${DEFAULT_FALLBACK_PROVIDER}`, primaryError);
|
|
@@ -1218,7 +1231,7 @@ class TransactionSigningService {
|
|
|
1218
1231
|
provider = new ethers.JsonRpcProvider(DEFAULT_FALLBACK_PROVIDER);
|
|
1219
1232
|
// Test the fallback connection
|
|
1220
1233
|
await provider.getNetwork();
|
|
1221
|
-
console.info(`[TransactionSigningService] Successfully connected to fallback provider`);
|
|
1234
|
+
//console.info(`[TransactionSigningService] Successfully connected to fallback provider`);
|
|
1222
1235
|
}
|
|
1223
1236
|
catch (fallbackError) {
|
|
1224
1237
|
console.error(`[TransactionSigningService] Both primary and fallback providers failed`, { primaryError, fallbackError });
|
|
@@ -1282,13 +1295,13 @@ class TransactionSigningService {
|
|
|
1282
1295
|
// Validate input parameters first using TransactionValidator
|
|
1283
1296
|
TransactionValidator.validateSigningParams(params);
|
|
1284
1297
|
const { transactionId, authTokens, ethersProviderUrl } = params;
|
|
1285
|
-
console.info(`[TransactionSigningService] Starting signature process for ${transactionId}`);
|
|
1298
|
+
// console.info(`[TransactionSigningService] Starting signature process for ${transactionId}`);
|
|
1286
1299
|
try {
|
|
1287
1300
|
// Step 2: Prepare wallet for signing
|
|
1288
1301
|
const wallet = await this.prepareWallet(authTokens, ethersProviderUrl);
|
|
1289
1302
|
// Step 3: Execute transaction signing
|
|
1290
1303
|
const signature = await this.executeTransactionSigning(wallet, signingData);
|
|
1291
|
-
console.info(`[TransactionSigningService] Completed signing successfully: ${transactionId}`);
|
|
1304
|
+
// console.info(`[TransactionSigningService] Completed signing successfully: ${transactionId}`);
|
|
1292
1305
|
return {
|
|
1293
1306
|
success: true,
|
|
1294
1307
|
transactionId,
|
|
@@ -1757,7 +1770,6 @@ class PersSignerSDK {
|
|
|
1757
1770
|
* @throws {Error} If required configuration is missing
|
|
1758
1771
|
*/
|
|
1759
1772
|
constructor(config) {
|
|
1760
|
-
// console.log('DEBUG: v1.2.0')
|
|
1761
1773
|
this.config = config;
|
|
1762
1774
|
setConfigProvider(new WebConfigProvider({
|
|
1763
1775
|
apiUrl: config.apiUrl || SIGNER_CONFIG.DEFAULT_SIGNER_API_URL,
|
|
@@ -1966,10 +1978,12 @@ class PersSignerSDK {
|
|
|
1966
1978
|
authTokens,
|
|
1967
1979
|
ethersProviderUrl: this.config.ethersProviderUrl ?? DEFAULT_FALLBACK_PROVIDER
|
|
1968
1980
|
}, signingData);
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1981
|
+
if (result.success) {
|
|
1982
|
+
this.triggerStatusUpdate(SigningStatus.COMPLETED, 'Transaction signed successfully', {
|
|
1983
|
+
transactionId: payload.transactionId,
|
|
1984
|
+
signature: result.signature
|
|
1985
|
+
}, statusCallback);
|
|
1986
|
+
}
|
|
1973
1987
|
return result;
|
|
1974
1988
|
}
|
|
1975
1989
|
catch (error) {
|
|
@@ -2113,6 +2127,28 @@ class PersSignerSDK {
|
|
|
2113
2127
|
}
|
|
2114
2128
|
}
|
|
2115
2129
|
|
|
2130
|
+
/**
|
|
2131
|
+
* Get the WebAuthn configuration based on the current environment.
|
|
2132
|
+
* This logic is shared between browser and React Native implementations
|
|
2133
|
+
* to ensure consistent behavior while respecting platform differences.
|
|
2134
|
+
*/
|
|
2135
|
+
function getWebAuthnConfig() {
|
|
2136
|
+
// Check if running in a browser environment with window.location available
|
|
2137
|
+
// We use a safe check that won't crash in React Native
|
|
2138
|
+
const isBrowser = typeof window !== 'undefined' && !!window.location && !!window.location.hostname;
|
|
2139
|
+
return {
|
|
2140
|
+
relyingParty: {
|
|
2141
|
+
// In browser, prefer the actual hostname to avoid RP ID mismatch errors
|
|
2142
|
+
// In React Native, use the configured default RP ID
|
|
2143
|
+
id: isBrowser ? window.location.hostname : SIGNER_CONFIG.DEFAULT_RELYING_PARTY_ID,
|
|
2144
|
+
name: SIGNER_CONFIG.DEFAULT_RELYING_PARTY_NAME,
|
|
2145
|
+
// In browser, use the actual origin
|
|
2146
|
+
// In React Native, fallback to the default RP ID (or a configured origin if added later)
|
|
2147
|
+
origin: isBrowser ? window.location.origin : SIGNER_CONFIG.DEFAULT_RELYING_PARTY_ID,
|
|
2148
|
+
}
|
|
2149
|
+
};
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2116
2152
|
/**
|
|
2117
2153
|
* Base64URL encoding/decoding utilities
|
|
2118
2154
|
* Used for WebAuthn credential ID and challenge handling
|
|
@@ -2176,9 +2212,8 @@ class BrowserWebAuthnProvider {
|
|
|
2176
2212
|
// 1. Prepare options for navigator.credentials.create
|
|
2177
2213
|
// We construct authenticatorSelection manually to ensure no conflicting legacy properties are present
|
|
2178
2214
|
const authenticatorSelection = {
|
|
2179
|
-
residentKey:
|
|
2180
|
-
|
|
2181
|
-
userVerification: challenge.authenticatorSelection?.userVerification || 'preferred',
|
|
2215
|
+
residentKey: WEBAUTHN_CONFIG.RESIDENT_KEY, // Force Passkey (discoverable credential)
|
|
2216
|
+
userVerification: challenge.authenticatorSelection?.userVerification || WEBAUTHN_CONFIG.USER_VERIFICATION,
|
|
2182
2217
|
};
|
|
2183
2218
|
const publicKey = {
|
|
2184
2219
|
challenge: base64UrlToBuffer(challenge.challenge),
|
|
@@ -2194,16 +2229,13 @@ class BrowserWebAuthnProvider {
|
|
|
2194
2229
|
pubKeyCredParams: challenge.pubKeyCredParams,
|
|
2195
2230
|
authenticatorSelection,
|
|
2196
2231
|
attestation: 'none',
|
|
2197
|
-
timeout: challenge.timeout ||
|
|
2232
|
+
timeout: challenge.timeout || WEBAUTHN_CONFIG.TIMEOUT,
|
|
2198
2233
|
excludeCredentials: challenge.excludeCredentials?.map((cred) => ({
|
|
2199
2234
|
id: base64UrlToBuffer(cred.id),
|
|
2200
2235
|
type: 'public-key',
|
|
2201
2236
|
transports: cred.transports,
|
|
2202
2237
|
})),
|
|
2203
2238
|
};
|
|
2204
|
-
// console.log('WebAuthn create options:', publicKey);
|
|
2205
|
-
// console.log('WebAuthn create challenge:', challenge);
|
|
2206
|
-
// console.log('this.config', this.config)
|
|
2207
2239
|
// 2. Call the browser's native WebAuthn API
|
|
2208
2240
|
const credential = await navigator.credentials.create({ publicKey });
|
|
2209
2241
|
if (!credential)
|
|
@@ -2227,8 +2259,8 @@ class BrowserWebAuthnProvider {
|
|
|
2227
2259
|
const publicKey = {
|
|
2228
2260
|
challenge: base64UrlToBuffer(challenge.challenge),
|
|
2229
2261
|
rpId: challenge.rpId || this.config.relyingParty.id,
|
|
2230
|
-
userVerification: challenge.userVerification ||
|
|
2231
|
-
timeout:
|
|
2262
|
+
userVerification: challenge.userVerification || WEBAUTHN_CONFIG.USER_VERIFICATION,
|
|
2263
|
+
timeout: WEBAUTHN_CONFIG.TIMEOUT,
|
|
2232
2264
|
allowCredentials: challenge.allowCredentials?.webauthn?.map((cred) => ({
|
|
2233
2265
|
id: base64UrlToBuffer(cred.id),
|
|
2234
2266
|
type: 'public-key',
|
|
@@ -2267,13 +2299,7 @@ class BrowserWebAuthnProvider {
|
|
|
2267
2299
|
* Get WebAuthn provider for browser environments
|
|
2268
2300
|
*/
|
|
2269
2301
|
async function getBrowserWebAuthnProvider() {
|
|
2270
|
-
const config =
|
|
2271
|
-
relyingParty: {
|
|
2272
|
-
id: typeof window !== 'undefined' ? window.location.hostname : SIGNER_CONFIG.DEFAULT_RELYING_PARTY_ID,
|
|
2273
|
-
name: SIGNER_CONFIG.DEFAULT_RELYING_PARTY_NAME,
|
|
2274
|
-
origin: typeof window !== 'undefined' ? window.location.origin : SIGNER_CONFIG.DEFAULT_RELYING_PARTY_ID,
|
|
2275
|
-
}
|
|
2276
|
-
};
|
|
2302
|
+
const config = getWebAuthnConfig();
|
|
2277
2303
|
return new BrowserWebAuthnProvider(config);
|
|
2278
2304
|
}
|
|
2279
2305
|
|