Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Updated lit signature logic #331

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 45 additions & 18 deletions packages/invoice-dashboard/src/lib/view-requests.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -194,18 +194,30 @@
currencyManager = await initializeCurrencyManager();
});

const getRequestsQueryKey = (address: string, currentPage: number) => ["requestsData", address, currentPage];
const getRequestsQueryKey = (address: string, currentPage: number) => [
"requestsData",
address,
currentPage,
];

const fetchRequests = async (address: string, page: number, pageSize: number) => {
const fetchRequests = async (
address: string,
page: number,
pageSize: number
) => {
if (!address || !requestNetwork) return null;
try {
const requestsData = await requestNetwork.fromIdentity({
type: Types.Identity.TYPE.ETHEREUM_ADDRESS,
value: address,
}, undefined, {
page: page,
pageSize: pageSize,
});
const requestsData = await requestNetwork.fromIdentity(
{
type: Types.Identity.TYPE.ETHEREUM_ADDRESS,
value: address,
},
undefined,
{
page: page,
pageSize: pageSize,
}
);
return requestsData;
} catch (error) {
console.error("Failed to fetch requests:", error);
Expand All @@ -222,12 +234,14 @@
try {
const data = await queryClient.fetchQuery({
queryKey: getRequestsQueryKey(account.address, currentPage),
queryFn: () => fetchRequests(account.address, currentPage, itemsPerPage)
queryFn: () =>
fetchRequests(account.address, currentPage, itemsPerPage),
});

if (data) {
requests = data.requests?.map((request) => request.getData())
.sort((a, b) => b.timestamp - a.timestamp);
requests = data.requests
?.map((request) => request.getData())
.sort((a, b) => b.timestamp - a.timestamp);
hasMoreRequests = data?.meta?.pagination?.hasMore || false;
} else {
requests = [];
Expand All @@ -237,7 +251,8 @@
if (hasMoreRequests) {
queryClient.prefetchQuery({
queryKey: getRequestsQueryKey(account.address, currentPage + 1),
queryFn: () => fetchRequests(account.address, currentPage + 1, itemsPerPage)
queryFn: () =>
fetchRequests(account.address, currentPage + 1, itemsPerPage),
});
}

Expand Down Expand Up @@ -492,24 +507,36 @@
return;

loading = true;
const previousNetworks = [...selectedNetworks]; // Store current selection
const previousNetworks = [...selectedNetworks];

try {
if (sliderValue === "on") {
if (localStorage?.getItem("isDecryptionEnabled") === "false") {
queryClient.invalidateQueries()
}
queryClient.invalidateQueries();
}
try {
const signer = await getEthersSigner(wagmiConfig);
if (signer && currentAccount?.address) {
loadSessionSignatures =
localStorage?.getItem("lit-wallet-sig") === null;
await cipherProvider?.getSessionSignatures(
const signatures = await cipherProvider?.getSessionSignatures(
signer,
currentAccount.address,
window.location.host,
"Sign in to Lit Protocol through Request Network"
);

// Save both signatures
localStorage?.setItem(
"lit-wallet-sig",
JSON.stringify({
address: currentAccount.address,
timestamp: Date.now(),
sig: signatures.walletSig,
})
);
localStorage?.setItem("lit-session-key", signatures.sessionKey);

cipherProvider?.enableDecryption(true);
localStorage?.setItem("isDecryptionEnabled", JSON.stringify(true));
}
Expand All @@ -522,7 +549,7 @@
}
} else {
if (localStorage?.getItem("isDecryptionEnabled") === "true") {
queryClient.invalidateQueries()
queryClient.invalidateQueries();
}
cipherProvider?.enableDecryption(false);
localStorage?.setItem("isDecryptionEnabled", JSON.stringify(false));
Expand Down
95 changes: 18 additions & 77 deletions packages/single-invoice/src/lib/single-invoice.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -252,79 +252,26 @@
};

const ensureDecryption = async () => {
if (!isDecryptionEnabled || !cipherProvider || !account?.address) {
return false;
}

try {
// First check if the request is actually encrypted
const encrypted = await isRequestEncrypted(requestId);
if (!encrypted) {
console.log("Request is not encrypted, skipping decryption setup");
return true;
}

console.log("Request is encrypted, setting up decryption");
const signer = await getEthersSigner(wagmiConfig);
if (!signer) return false;

// Check if we have a valid session first
const hasExistingSession =
localStorage.getItem("lit-wallet-sig") === "true";

if (hasExistingSession) {
// Try to use existing session
try {
cipherProvider.enableDecryption(true);
// Test if current session works with a request fetch
const testRequest = await requestNetwork?.fromRequestId(requestId);

// Only consider the session valid if we can actually decrypt the request
if (testRequest?.getData()) {
console.log("Using existing Lit Protocol session");
return true;
}
} catch (error) {
// If we get a decryption error, we need a new session
if (
String(error).includes("Decryption is not available") ||
String(error).includes("Failed to decrypt") ||
String(error).includes("LitNodeClient is not ready")
) {
console.log("Existing session invalid, clearing...");
localStorage.removeItem("lit-wallet-sig");
} else {
// If it's some other error, keep the session
console.log("Error fetching request, but keeping session:", error);
return true;
}
}
}
if (!account?.address || !cipherProvider) return;

// If we get here, we need a new session
console.log("Getting new Lit Protocol session");
loadSessionSignatures = true;
const walletSig = localStorage.getItem("lit-wallet-sig");
const sessionKey = localStorage.getItem("lit-session-key");
const isEnabled = localStorage.getItem("isDecryptionEnabled") === "true";

if (walletSig && sessionKey && isEnabled) {
try {
await cipherProvider.getSessionSignatures(
signer,
account.address,
window.location.host,
"Sign in to Lit Protocol through Request Network"
);

localStorage.setItem("lit-wallet-sig", "true");
// Use existing signatures
cipherProvider.enableDecryption(true);
return true;
} catch (error) {
console.error("Failed to get new session signatures:", error);
return false;
} finally {
loadSessionSignatures = false;
console.error(
"Failed to enable decryption with existing signatures:",
error
);
// Clear invalid signatures
localStorage.removeItem("lit-wallet-sig");
localStorage.removeItem("lit-session-key");
localStorage.setItem("isDecryptionEnabled", "false");
}
} catch (error) {
console.error("Failed to ensure decryption:", error);
return false;
}
};
Comment on lines 254 to 276
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling in ensureDecryption.

The function silently fails when the account address or cipher provider is missing. Consider:

  1. Returning a boolean to indicate success/failure
  2. Adding error logging for debugging

Apply this diff to improve error handling:

 const ensureDecryption = async () => {
-  if (!account?.address || !cipherProvider) return;
+  if (!account?.address || !cipherProvider) {
+    console.warn('Cannot ensure decryption: missing account address or cipher provider');
+    return false;
+  }

   const walletSig = localStorage.getItem("lit-wallet-sig");
   const sessionKey = localStorage.getItem("lit-session-key");
   const isEnabled = localStorage.getItem("isDecryptionEnabled") === "true";

   if (walletSig && sessionKey && isEnabled) {
     try {
       // Use existing signatures
       cipherProvider.enableDecryption(true);
+      return true;
     } catch (error) {
       console.error(
         "Failed to enable decryption with existing signatures:",
         error
       );
       // Clear invalid signatures
       localStorage.removeItem("lit-wallet-sig");
       localStorage.removeItem("lit-session-key");
       localStorage.setItem("isDecryptionEnabled", "false");
+      return false;
     }
   }
+  return false;
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const ensureDecryption = async () => {
if (!isDecryptionEnabled || !cipherProvider || !account?.address) {
return false;
}
try {
// First check if the request is actually encrypted
const encrypted = await isRequestEncrypted(requestId);
if (!encrypted) {
console.log("Request is not encrypted, skipping decryption setup");
return true;
}
console.log("Request is encrypted, setting up decryption");
const signer = await getEthersSigner(wagmiConfig);
if (!signer) return false;
// Check if we have a valid session first
const hasExistingSession =
localStorage.getItem("lit-wallet-sig") === "true";
if (hasExistingSession) {
// Try to use existing session
try {
cipherProvider.enableDecryption(true);
// Test if current session works with a request fetch
const testRequest = await requestNetwork?.fromRequestId(requestId);
// Only consider the session valid if we can actually decrypt the request
if (testRequest?.getData()) {
console.log("Using existing Lit Protocol session");
return true;
}
} catch (error) {
// If we get a decryption error, we need a new session
if (
String(error).includes("Decryption is not available") ||
String(error).includes("Failed to decrypt") ||
String(error).includes("LitNodeClient is not ready")
) {
console.log("Existing session invalid, clearing...");
localStorage.removeItem("lit-wallet-sig");
} else {
// If it's some other error, keep the session
console.log("Error fetching request, but keeping session:", error);
return true;
}
}
}
if (!account?.address || !cipherProvider) return;
// If we get here, we need a new session
console.log("Getting new Lit Protocol session");
loadSessionSignatures = true;
const walletSig = localStorage.getItem("lit-wallet-sig");
const sessionKey = localStorage.getItem("lit-session-key");
const isEnabled = localStorage.getItem("isDecryptionEnabled") === "true";
if (walletSig && sessionKey && isEnabled) {
try {
await cipherProvider.getSessionSignatures(
signer,
account.address,
window.location.host,
"Sign in to Lit Protocol through Request Network"
);
localStorage.setItem("lit-wallet-sig", "true");
// Use existing signatures
cipherProvider.enableDecryption(true);
return true;
} catch (error) {
console.error("Failed to get new session signatures:", error);
return false;
} finally {
loadSessionSignatures = false;
console.error(
"Failed to enable decryption with existing signatures:",
error
);
// Clear invalid signatures
localStorage.removeItem("lit-wallet-sig");
localStorage.removeItem("lit-session-key");
localStorage.setItem("isDecryptionEnabled", "false");
}
} catch (error) {
console.error("Failed to ensure decryption:", error);
return false;
}
};
const ensureDecryption = async () => {
if (!account?.address || !cipherProvider) {
console.warn('Cannot ensure decryption: missing account address or cipher provider');
return false;
}
const walletSig = localStorage.getItem("lit-wallet-sig");
const sessionKey = localStorage.getItem("lit-session-key");
const isEnabled = localStorage.getItem("isDecryptionEnabled") === "true";
if (walletSig && sessionKey && isEnabled) {
try {
// Use existing signatures
cipherProvider.enableDecryption(true);
return true;
} catch (error) {
console.error(
"Failed to enable decryption with existing signatures:",
error
);
// Clear invalid signatures
localStorage.removeItem("lit-wallet-sig");
localStorage.removeItem("lit-session-key");
localStorage.setItem("isDecryptionEnabled", "false");
return false;
}
}
return false;
};


Expand Down Expand Up @@ -471,22 +418,14 @@
let unwatchAccount: WatchAccountReturnType | undefined;

const handleWalletConnection = async () => {
account = getAccount(wagmiConfig);
if (!account?.address) return;

// Reset decryption state
if (cipherProvider) {
cipherProvider.disconnectWallet();
localStorage.removeItem("lit-wallet-sig");
}
account = getAccount(wagmiConfig);

// Only attempt decryption setup if needed
if (isDecryptionEnabled && requestId) {
const isEncrypted = await isRequestEncrypted(requestId);
if (isEncrypted) {
await ensureDecryption();
} else {
// For non-encrypted requests, just disable decryption
cipherProvider?.enableDecryption(false);
}
}

Expand All @@ -508,6 +447,8 @@
if (cipherProvider) {
cipherProvider.disconnectWallet();
localStorage.removeItem("lit-wallet-sig");
localStorage.removeItem("lit-session-key");
localStorage.setItem("isDecryptionEnabled", "false");
}
};

Expand Down