From f84bc134dfb2f1774d723eb80a8811a62b6b3b2b Mon Sep 17 00:00:00 2001 From: Ansonhkg Date: Mon, 15 Apr 2024 18:10:53 +0100 Subject: [PATCH 1/8] feat(AMD Cert): Always fetch from CORS --- packages/crypto/src/lib/crypto.ts | 55 +++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/packages/crypto/src/lib/crypto.ts b/packages/crypto/src/lib/crypto.ts index 46936bd0f0..25afbd2bd4 100644 --- a/packages/crypto/src/lib/crypto.ts +++ b/packages/crypto/src/lib/crypto.ts @@ -20,6 +20,8 @@ import { nacl } from '@lit-protocol/nacl'; import { SIGTYPE } from '@lit-protocol/constants'; import { CombinedECDSASignature } from '@lit-protocol/types'; +const LIT_CORS_PROXY = `https://cors.litgateway.com` + // if 'wasmExports' is not available, we need to initialize the BLS SDK if (!globalThis.wasmExports) { blsSdk.initWasmBlsSdk().then((exports) => { @@ -27,8 +29,7 @@ if (!globalThis.wasmExports) { if (!globalThis.jestTesting) { log( - `✅ [BLS SDK] wasmExports loaded. ${ - Object.keys(exports).length + `✅ [BLS SDK] wasmExports loaded. ${Object.keys(exports).length } functions available. Run 'wasmExports' in the console to see them.` ); } @@ -50,8 +51,7 @@ if (!globalThis.wasmECDSA) { if (!globalThis.jestTesting) { log( - `✅ [ECDSA SDK ${env}] wasmECDSA loaded. ${ - Object.keys(wasmECDSA).length + `✅ [ECDSA SDK ${env}] wasmECDSA loaded. ${Object.keys(wasmECDSA).length } functions available. Run 'wasmECDSA' in the console to see them.` ); } @@ -64,8 +64,7 @@ if (!globalThis.wasmSevSnpUtils) { if (!globalThis.jestTesting) { log( - `✅ [SEV SNP Utils SDK] wasmSevSnpUtils loaded. ${ - Object.keys(exports).length + `✅ [SEV SNP Utils SDK] wasmSevSnpUtils loaded. ${Object.keys(exports).length } functions available. Run 'wasmSevSnpUtils' in the console to see them.` ); } @@ -359,14 +358,44 @@ function base64ToBufferAsync(base64) { }); } -async function getAmdCert(url: string) { - // unfortunately, until AMD enables CORS, we have to use a proxy when in the browser - // This project is hosted on heroku and uses this codebase: https://github.com/LIT-Protocol/cors-proxy-amd - if (isBrowser()) { - // CORS proxy url - url = `https://cors.litgateway.com/${url}`; +/** + * Asynchronously fetches an AMD certification from a specified URL using a CORS proxy. + * This approach is used to bypass CORS restrictions when accessing external APIs that do not support CORS. + * It attempts to fetch the AMD cert through a proxy and if the proxy fetch fails, it throws an error. + * + * @param url The URL from which to fetch the AMD cert. + * @returns A Promise that resolves to a Uint8Array containing the AMD certification data. + * @throws An error detailing HTTP or network issues encountered during the fetch process. + */ +async function getAmdCert(url: string): Promise { + + const proxyUrl = `${LIT_CORS_PROXY}/${url}`; + + console.log(`Fetching AMD cert using proxy URL due to CORS restrictions.`); + + let response; + + try { + response = await fetch(proxyUrl); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + } catch (e) { + console.error(`Failed to fetch AMD cert from proxy:`, e); + + // Try direct fetch only if proxy fails + console.log("Attempting to fetch directly without proxy."); + try { + response = await fetch(url); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + } catch (e) { + console.error('Direct fetch also failed:', e); + throw e; // Re-throw to signal that both methods failed + } } - const response = await fetch(url); + const arrayBuffer = await response.arrayBuffer(); return new Uint8Array(arrayBuffer); } From b6f5db59c1b284ddbb05e83bd3c12dc813b5b5ee Mon Sep 17 00:00:00 2001 From: Ansonhkg Date: Mon, 15 Apr 2024 18:16:56 +0100 Subject: [PATCH 2/8] chore: prettified --- lit.config.json | 6 +++--- packages/crypto/src/lib/crypto.ts | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/lit.config.json b/lit.config.json index 414e3fdf42..c7972f34eb 100644 --- a/lit.config.json +++ b/lit.config.json @@ -43,12 +43,12 @@ }, "CACHE": { "network": "cayenne", - "debug": true, + "debug": false, "sevAttestation": false, "CONTROLLER_AUTHSIG": { - "sig": "0x6c6447a53fe789fd0ae681c7698cb414985d006a00637906f412d292bbfd2e352e10af744428e3208df35d2d4065c767941eb4d7d502dfe569267705f0d4d5e61c", + "sig": "0x3ebf0dc7e847b9108ae5d66f69e3ef94b1e8022085d19cca2431a2f3857722b1272edd1181e713707f90a5a89c27fdda51eb659ab962e79f790acab36a5b37ec1c", "derivedVia": "web3.eth.personal.sign", - "signedMessage": "localhost wants you to sign in with your Ethereum account:\n0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37\n\nThis is a test statement. You can put anything you want here.\n\nURI: https://localhost/login\nVersion: 1\nChain ID: 1\nNonce: 0x6cbca5687b3e317ecd4c2c5ef54aa6f8743c63f80dab435a981fa1fe29a2000f\nIssued At: 2024-03-12T13:34:47.589Z\nExpiration Time: 2024-03-12T14:34:47.584Z", + "signedMessage": "localhost wants you to sign in with your Ethereum account:\n0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37\n\nThis is a test statement. You can put anything you want here.\n\nURI: https://localhost/login\nVersion: 1\nChain ID: 1\nNonce: 0x69d030761ca65a79b040360e92f50a3f4462fa412acf0740aaa52da75cb53aaa\nIssued At: 2024-04-15T17:12:43.836Z\nExpiration Time: 2024-04-15T18:12:43.829Z", "address": "0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37" }, "CONTROLLER_WALLET": { diff --git a/packages/crypto/src/lib/crypto.ts b/packages/crypto/src/lib/crypto.ts index 25afbd2bd4..c6d64bb531 100644 --- a/packages/crypto/src/lib/crypto.ts +++ b/packages/crypto/src/lib/crypto.ts @@ -20,7 +20,7 @@ import { nacl } from '@lit-protocol/nacl'; import { SIGTYPE } from '@lit-protocol/constants'; import { CombinedECDSASignature } from '@lit-protocol/types'; -const LIT_CORS_PROXY = `https://cors.litgateway.com` +const LIT_CORS_PROXY = `https://cors.litgateway.com`; // if 'wasmExports' is not available, we need to initialize the BLS SDK if (!globalThis.wasmExports) { @@ -29,7 +29,8 @@ if (!globalThis.wasmExports) { if (!globalThis.jestTesting) { log( - `✅ [BLS SDK] wasmExports loaded. ${Object.keys(exports).length + `✅ [BLS SDK] wasmExports loaded. ${ + Object.keys(exports).length } functions available. Run 'wasmExports' in the console to see them.` ); } @@ -51,7 +52,8 @@ if (!globalThis.wasmECDSA) { if (!globalThis.jestTesting) { log( - `✅ [ECDSA SDK ${env}] wasmECDSA loaded. ${Object.keys(wasmECDSA).length + `✅ [ECDSA SDK ${env}] wasmECDSA loaded. ${ + Object.keys(wasmECDSA).length } functions available. Run 'wasmECDSA' in the console to see them.` ); } @@ -64,7 +66,8 @@ if (!globalThis.wasmSevSnpUtils) { if (!globalThis.jestTesting) { log( - `✅ [SEV SNP Utils SDK] wasmSevSnpUtils loaded. ${Object.keys(exports).length + `✅ [SEV SNP Utils SDK] wasmSevSnpUtils loaded. ${ + Object.keys(exports).length } functions available. Run 'wasmSevSnpUtils' in the console to see them.` ); } @@ -362,13 +365,12 @@ function base64ToBufferAsync(base64) { * Asynchronously fetches an AMD certification from a specified URL using a CORS proxy. * This approach is used to bypass CORS restrictions when accessing external APIs that do not support CORS. * It attempts to fetch the AMD cert through a proxy and if the proxy fetch fails, it throws an error. - * + * * @param url The URL from which to fetch the AMD cert. * @returns A Promise that resolves to a Uint8Array containing the AMD certification data. * @throws An error detailing HTTP or network issues encountered during the fetch process. */ async function getAmdCert(url: string): Promise { - const proxyUrl = `${LIT_CORS_PROXY}/${url}`; console.log(`Fetching AMD cert using proxy URL due to CORS restrictions.`); @@ -382,9 +384,9 @@ async function getAmdCert(url: string): Promise { } } catch (e) { console.error(`Failed to fetch AMD cert from proxy:`, e); - + // Try direct fetch only if proxy fails - console.log("Attempting to fetch directly without proxy."); + console.log('Attempting to fetch directly without proxy.'); try { response = await fetch(url); if (!response.ok) { From fdafcebde05a889f5f08cd566dcec971dd5007b0 Mon Sep 17 00:00:00 2001 From: Ansonhkg Date: Mon, 15 Apr 2024 18:21:33 +0100 Subject: [PATCH 3/8] chore(AMD-Cert): Use `log` instead of `console.log` --- packages/crypto/src/lib/crypto.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/crypto/src/lib/crypto.ts b/packages/crypto/src/lib/crypto.ts index c6d64bb531..3abcc7da75 100644 --- a/packages/crypto/src/lib/crypto.ts +++ b/packages/crypto/src/lib/crypto.ts @@ -373,27 +373,27 @@ function base64ToBufferAsync(base64) { async function getAmdCert(url: string): Promise { const proxyUrl = `${LIT_CORS_PROXY}/${url}`; - console.log(`Fetching AMD cert using proxy URL due to CORS restrictions.`); + log(`[getAmdCert] Fetching AMD cert using proxy URL ${proxyUrl} due to CORS restrictions.`); let response; try { response = await fetch(proxyUrl); if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error(`[getAmdCert] HTTP error! status: ${response.status}`); } } catch (e) { - console.error(`Failed to fetch AMD cert from proxy:`, e); + log(`[getAmdCert] Failed to fetch AMD cert from proxy:`, e); // Try direct fetch only if proxy fails - console.log('Attempting to fetch directly without proxy.'); + log('[getAmdCert] Attempting to fetch directly without proxy.'); try { response = await fetch(url); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } } catch (e) { - console.error('Direct fetch also failed:', e); + log('[getAmdCert] Direct fetch also failed:', e); throw e; // Re-throw to signal that both methods failed } } From bcf633a5381c23ce61e4129bd9e9bda25c58f1e5 Mon Sep 17 00:00:00 2001 From: Ansonhkg Date: Mon, 15 Apr 2024 18:22:53 +0100 Subject: [PATCH 4/8] chore: prettified --- lit.config.json | 6 +++--- packages/crypto/src/lib/crypto.ts | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lit.config.json b/lit.config.json index c7972f34eb..41f51f87b5 100644 --- a/lit.config.json +++ b/lit.config.json @@ -43,12 +43,12 @@ }, "CACHE": { "network": "cayenne", - "debug": false, + "debug": true, "sevAttestation": false, "CONTROLLER_AUTHSIG": { - "sig": "0x3ebf0dc7e847b9108ae5d66f69e3ef94b1e8022085d19cca2431a2f3857722b1272edd1181e713707f90a5a89c27fdda51eb659ab962e79f790acab36a5b37ec1c", + "sig": "0x01d7f16d2e1c79846d235c45e506bd866b0c9b0af05736ed6d2cd9de4a08d5dc1156a8884550df267b1cafc9a81bb029ed3348d15d53a6ae421ec848472c2c341b", "derivedVia": "web3.eth.personal.sign", - "signedMessage": "localhost wants you to sign in with your Ethereum account:\n0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37\n\nThis is a test statement. You can put anything you want here.\n\nURI: https://localhost/login\nVersion: 1\nChain ID: 1\nNonce: 0x69d030761ca65a79b040360e92f50a3f4462fa412acf0740aaa52da75cb53aaa\nIssued At: 2024-04-15T17:12:43.836Z\nExpiration Time: 2024-04-15T18:12:43.829Z", + "signedMessage": "localhost wants you to sign in with your Ethereum account:\n0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37\n\nThis is a test statement. You can put anything you want here.\n\nURI: https://localhost/login\nVersion: 1\nChain ID: 1\nNonce: 0x6a1c254dc3cad8dcdd02e02ba9d5c0c706ce4b1e040bdfc06e87fb360644d81c\nIssued At: 2024-04-15T17:19:38.839Z\nExpiration Time: 2024-04-15T18:19:38.837Z", "address": "0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37" }, "CONTROLLER_WALLET": { diff --git a/packages/crypto/src/lib/crypto.ts b/packages/crypto/src/lib/crypto.ts index 3abcc7da75..0cb202efa1 100644 --- a/packages/crypto/src/lib/crypto.ts +++ b/packages/crypto/src/lib/crypto.ts @@ -373,7 +373,9 @@ function base64ToBufferAsync(base64) { async function getAmdCert(url: string): Promise { const proxyUrl = `${LIT_CORS_PROXY}/${url}`; - log(`[getAmdCert] Fetching AMD cert using proxy URL ${proxyUrl} due to CORS restrictions.`); + log( + `[getAmdCert] Fetching AMD cert using proxy URL ${proxyUrl} due to CORS restrictions.` + ); let response; From 3e8b8bb4d25866175255a62eb93192dc2e5c8c25 Mon Sep 17 00:00:00 2001 From: Anson Date: Mon, 15 Apr 2024 20:10:23 +0100 Subject: [PATCH 5/8] Update packages/crypto/src/lib/crypto.ts Co-authored-by: Daryl Collins Signed-off-by: Anson --- packages/crypto/src/lib/crypto.ts | 38 ++++++++++++++++--------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/crypto/src/lib/crypto.ts b/packages/crypto/src/lib/crypto.ts index 0cb202efa1..347fb4a9db 100644 --- a/packages/crypto/src/lib/crypto.ts +++ b/packages/crypto/src/lib/crypto.ts @@ -377,28 +377,30 @@ async function getAmdCert(url: string): Promise { `[getAmdCert] Fetching AMD cert using proxy URL ${proxyUrl} due to CORS restrictions.` ); - let response; - - try { - response = await fetch(proxyUrl); - if (!response.ok) { + async function fetchAsUint8Array(targetUrl) { + const res = await fetch(targetUrl); + if (!res.ok) { throw new Error(`[getAmdCert] HTTP error! status: ${response.status}`); } + const arrayBuffer = await res.arrayBuffer(); + return new Uint8Array(arrayBuffer); + } + + try { + return await fetchAsUint8Array(proxyUrl); } catch (e) { - log(`[getAmdCert] Failed to fetch AMD cert from proxy:`, e); - - // Try direct fetch only if proxy fails - log('[getAmdCert] Attempting to fetch directly without proxy.'); - try { - response = await fetch(url); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - } catch (e) { - log('[getAmdCert] Direct fetch also failed:', e); - throw e; // Re-throw to signal that both methods failed - } + log(`[getAmdCert] Failed to fetch AMD cert from proxy:`, e); } + + // Try direct fetch only if proxy fails + log('[getAmdCert] Attempting to fetch directly without proxy.'); + try { + return await fetchAsUint8Array(url); + } catch (e) { + log('[getAmdCert] Direct fetch also failed:', e); + throw e; // Re-throw to signal that both methods failed + } + const arrayBuffer = await response.arrayBuffer(); return new Uint8Array(arrayBuffer); From 6a8cda3f22fc42e1526d4cc33c5d9c64897028b4 Mon Sep 17 00:00:00 2001 From: Ansonhkg Date: Mon, 15 Apr 2024 20:13:29 +0100 Subject: [PATCH 6/8] Chore: Update JSDoc --- packages/crypto/src/lib/crypto.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/crypto/src/lib/crypto.ts b/packages/crypto/src/lib/crypto.ts index 347fb4a9db..0829ec04b7 100644 --- a/packages/crypto/src/lib/crypto.ts +++ b/packages/crypto/src/lib/crypto.ts @@ -29,8 +29,7 @@ if (!globalThis.wasmExports) { if (!globalThis.jestTesting) { log( - `✅ [BLS SDK] wasmExports loaded. ${ - Object.keys(exports).length + `✅ [BLS SDK] wasmExports loaded. ${Object.keys(exports).length } functions available. Run 'wasmExports' in the console to see them.` ); } @@ -52,8 +51,7 @@ if (!globalThis.wasmECDSA) { if (!globalThis.jestTesting) { log( - `✅ [ECDSA SDK ${env}] wasmECDSA loaded. ${ - Object.keys(wasmECDSA).length + `✅ [ECDSA SDK ${env}] wasmECDSA loaded. ${Object.keys(wasmECDSA).length } functions available. Run 'wasmECDSA' in the console to see them.` ); } @@ -66,8 +64,7 @@ if (!globalThis.wasmSevSnpUtils) { if (!globalThis.jestTesting) { log( - `✅ [SEV SNP Utils SDK] wasmSevSnpUtils loaded. ${ - Object.keys(exports).length + `✅ [SEV SNP Utils SDK] wasmSevSnpUtils loaded. ${Object.keys(exports).length } functions available. Run 'wasmSevSnpUtils' in the console to see them.` ); } @@ -363,8 +360,11 @@ function base64ToBufferAsync(base64) { /** * Asynchronously fetches an AMD certification from a specified URL using a CORS proxy. - * This approach is used to bypass CORS restrictions when accessing external APIs that do not support CORS. - * It attempts to fetch the AMD cert through a proxy and if the proxy fetch fails, it throws an error. + * The primary purpose of using a CORS proxy is to avoid being rate-limited by AMD. + * The function attempts to fetch the AMD cert through a proxy, and if the proxy fetch fails, + * it retries directly from the original URL. + * + * Note: This project is hosted on heroku and uses this codebase: https://github.com/LIT-Protocol/cors-proxy-amd * * @param url The URL from which to fetch the AMD cert. * @returns A Promise that resolves to a Uint8Array containing the AMD certification data. @@ -386,12 +386,12 @@ async function getAmdCert(url: string): Promise { return new Uint8Array(arrayBuffer); } - try { + try { return await fetchAsUint8Array(proxyUrl); } catch (e) { - log(`[getAmdCert] Failed to fetch AMD cert from proxy:`, e); + log(`[getAmdCert] Failed to fetch AMD cert from proxy:`, e); } - + // Try direct fetch only if proxy fails log('[getAmdCert] Attempting to fetch directly without proxy.'); try { From f8d57dc931504f723b07779bce3706f3df1e833f Mon Sep 17 00:00:00 2001 From: Ansonhkg Date: Mon, 15 Apr 2024 20:14:54 +0100 Subject: [PATCH 7/8] chore: prettified --- packages/crypto/src/lib/crypto.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/crypto/src/lib/crypto.ts b/packages/crypto/src/lib/crypto.ts index 0829ec04b7..8bb24faf91 100644 --- a/packages/crypto/src/lib/crypto.ts +++ b/packages/crypto/src/lib/crypto.ts @@ -29,7 +29,8 @@ if (!globalThis.wasmExports) { if (!globalThis.jestTesting) { log( - `✅ [BLS SDK] wasmExports loaded. ${Object.keys(exports).length + `✅ [BLS SDK] wasmExports loaded. ${ + Object.keys(exports).length } functions available. Run 'wasmExports' in the console to see them.` ); } @@ -51,7 +52,8 @@ if (!globalThis.wasmECDSA) { if (!globalThis.jestTesting) { log( - `✅ [ECDSA SDK ${env}] wasmECDSA loaded. ${Object.keys(wasmECDSA).length + `✅ [ECDSA SDK ${env}] wasmECDSA loaded. ${ + Object.keys(wasmECDSA).length } functions available. Run 'wasmECDSA' in the console to see them.` ); } @@ -64,7 +66,8 @@ if (!globalThis.wasmSevSnpUtils) { if (!globalThis.jestTesting) { log( - `✅ [SEV SNP Utils SDK] wasmSevSnpUtils loaded. ${Object.keys(exports).length + `✅ [SEV SNP Utils SDK] wasmSevSnpUtils loaded. ${ + Object.keys(exports).length } functions available. Run 'wasmSevSnpUtils' in the console to see them.` ); } @@ -363,7 +366,7 @@ function base64ToBufferAsync(base64) { * The primary purpose of using a CORS proxy is to avoid being rate-limited by AMD. * The function attempts to fetch the AMD cert through a proxy, and if the proxy fetch fails, * it retries directly from the original URL. - * + * * Note: This project is hosted on heroku and uses this codebase: https://github.com/LIT-Protocol/cors-proxy-amd * * @param url The URL from which to fetch the AMD cert. @@ -401,7 +404,6 @@ async function getAmdCert(url: string): Promise { throw e; // Re-throw to signal that both methods failed } - const arrayBuffer = await response.arrayBuffer(); return new Uint8Array(arrayBuffer); } From 2de96b98f27a4a99ade6dd2a80f2320492a69338 Mon Sep 17 00:00:00 2001 From: Ansonhkg Date: Mon, 15 Apr 2024 20:17:04 +0100 Subject: [PATCH 8/8] chore: update log --- packages/crypto/src/lib/crypto.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/crypto/src/lib/crypto.ts b/packages/crypto/src/lib/crypto.ts index 8bb24faf91..ea242f6451 100644 --- a/packages/crypto/src/lib/crypto.ts +++ b/packages/crypto/src/lib/crypto.ts @@ -377,7 +377,7 @@ async function getAmdCert(url: string): Promise { const proxyUrl = `${LIT_CORS_PROXY}/${url}`; log( - `[getAmdCert] Fetching AMD cert using proxy URL ${proxyUrl} due to CORS restrictions.` + `[getAmdCert] Fetching AMD cert using proxy URL ${proxyUrl} to manage CORS restrictions and to avoid being rate limited by AMD.` ); async function fetchAsUint8Array(targetUrl) { @@ -397,15 +397,13 @@ async function getAmdCert(url: string): Promise { // Try direct fetch only if proxy fails log('[getAmdCert] Attempting to fetch directly without proxy.'); + try { return await fetchAsUint8Array(url); } catch (e) { log('[getAmdCert] Direct fetch also failed:', e); throw e; // Re-throw to signal that both methods failed } - - const arrayBuffer = await response.arrayBuffer(); - return new Uint8Array(arrayBuffer); } /**