diff --git a/docs/sdk/access-control/solana/siws-access-control.md b/docs/sdk/access-control/solana/siws-access-control.md new file mode 100644 index 00000000..d897e5f8 --- /dev/null +++ b/docs/sdk/access-control/solana/siws-access-control.md @@ -0,0 +1,124 @@ +# Sign-in With Solana Access Control + +This guide builds on the [Sign-in With Solana Authentication](../../authentication/authenticating-siws.md) guide to show how to use Lit Actions to implement access control for Solana wallets authenticated using SIWS. + +We combine the SIWS authentication with Lit Access Control Conditions to demonstrate how to control access to to an app based on the user's Solana public key. + +## Prerequisites + +Before continuing with this guide, make sure you have the following: + +- An understanding of [Lit Actions](../../serverless-signing/overview) and how they work +- An understanding of how to [authenticate SIWS messages](../../authentication/authenticating-siws) using a Lit Action +- A basic understanding of Phantom's [SIWS specification](https://github.com/phantom/sign-in-with-solana/tree/main) +- An understanding of [Lit Access Control Conditions](../../../sdk/access-control/evm/basic-examples) + +## High Level Overview + +The following diagram depicts the flow of authenticating SIWS messages and then using the authenticated public key to check against Lit Access Control Conditions: + +![SIWS Access Control Flow](../../../../static/img/siws-accs.png) + +:::info +A full implementation of this code example can be found [here](https://github.com/LIT-Protocol/developer-guides-code/blob/master/siws-access-control/browser). +::: + +## Writing the Lit Action + +The Lit Action used for this example does the following: + +1. Parses the raw SIWS message values +2. Builds the SIWS message according to the SIWS specification +3. Validates that the provided Solana signature is valid for the SIWS message +4. Compares the derived public key against the public key specified in the Lit Access Control Conditions +5. Returns the result of the comparison + +For steps 1 - 3, we reuse the SIWS authentication logic from the [SIWS Authentication](../../authentication/authenticating-siws#parsing-and-re-building-the-siws-message) guide, so this guide will pick up from step 4. + +:::note +The full implementation of this Lit Action can be found [here](https://github.com/LIT-Protocol/developer-guides-code/blob/master/siws-accs/browser/src/litActionSiws.ts). +::: + +### Checking the Access Control Conditions + +At this point we have validated that the provided user signature is for the SIWS message, constructed according to the SIWS specification. Now we need to check the user's Solana public key against the public key specified in the Lit Access Control Conditions: + +```js +try { + const result = await LitActions.checkConditions({ + conditions: solRpcConditions, + authSig: { + sig: ethers.utils + .hexlify(ethers.utils.base58.decode(_siwsObject.signature)) + .slice(2), + derivedVia: "solana.signMessage", + signedMessage: siwsMessage, + address: siwsInput.address, + }, + chain: "solana", + }); + + return LitActions.setResponse({ response: result }); +} catch (error) { + console.error("Error checking if authed sol pub key is permitted:", error); + return LitActions.setResponse({ + response: JSON.stringify({ + success: false, + message: "Error checking if authed sol pub key is permitted.", + error: error.toString(), + }), + }); +} +``` + +For this example, the Access Control Conditions (`solRpcConditions`) look like: + +```js +[ + { + method: "", + params: [":userAddress"], + pdaParams: [], + pdaInterface: { offset: 0, fields: {} }, + pdaKey: "", + chain: "solana", + returnValueTest: { + key: "", + comparator: "=", + // This address would be the Solana public key that is authorized to access the app, + // and you would replace it with the actual public key that you want to authorize. + value: address, + }, + }, +]; +``` + +When `LitActions.checkConditions` is executed, it parses the `authSig` property and derives the Solana public key from the `signedMessage`. + +It then compares the derived public key against the `returnValueTest` property defined in the Access Control Condition. If the derived public key is equal to the `value` property from the `returnValueTest` object, the Access Control Condition is met and the Solana public key is considered authorized. + +We then simply return the result of the Access Control Condition check, which is a boolean value, to the frontend: + +```js +return LitActions.setResponse({ response: result }); +``` + +## Summary + +This guide demonstrates implementing access control using Sign-in With Solana (SIWS) messages, Lit Actions, and Access Control Conditions. + +By leveraging Phantom's SIWS specification and Lit Access Control Conditions, we have established a robust and secure method for verifying Solana wallet ownership. This authentication mechanism can be extended to authorize specific Solana public keys for various operations using Lit, such as: + +- **Encrypted Data Access**: Restrict [decryption](../../../sdk/access-control/intro) of sensitive information to specific Solana wallet owners. +- **Access Control**: Restrict access to an application to specific Solana wallet owners. + +Key takeaways from this implementation are that the Lit Action: + +- Reconstructs and verifies the SIWS message, ensuring the integrity of the signed data. +- Allows for custom validation of SIWS message properties to meet specific application requirements. +- Integrates Lit Access Control Conditions to perform custom authorization checks. + +:::note +A full implementation of this code example can be found [here](https://github.com/LIT-Protocol/developer-guides-code/blob/master/siws-accs/browser). +::: + diff --git a/docs/sdk/access-control/other-chains/sol-rpc-conditions.md b/docs/sdk/access-control/solana/sol-rpc-conditions.md similarity index 64% rename from docs/sdk/access-control/other-chains/sol-rpc-conditions.md rename to docs/sdk/access-control/solana/sol-rpc-conditions.md index 8985d10c..6d3a4e69 100644 --- a/docs/sdk/access-control/other-chains/sol-rpc-conditions.md +++ b/docs/sdk/access-control/solana/sol-rpc-conditions.md @@ -4,22 +4,14 @@ sidebar_position: 4 import FeedbackComponent from "@site/src/pages/feedback.md"; -# Solana Examples +# Access Control Conditions Examples -:::danger +The following examples demonstrate additional Solana RPC Conditions you can use to control access to your application. After [authenticating a Sign-in With Solana (SIWS) message](../../authentication/authenticating-siws.md), you can use these Solana RPC Conditions to check if the authenticated Solana public key meets certain conditions. -Solana access control currently is missing various security properties due to the Solana communities lack of a standard on a signed message format. You should not use Solana access control for anything mission critical in it's current form. Any EDDSA signature that is valid will allow auth via Solana. This means, if a given wallet has ever made a Solana txn, it's possilble to auth as that wallet by taking the signature from the chain and presenting it to Lit for auth. If you're building on Solana, please reach out, so we can work on a standard signed message format to solve this problem. - -::: - -:::info -Solana Access Control Conditions are supported only by Auth Sigs not Session Sigs (read more about the difference between the two approaches [here](../../authentication/overview.md)). +:::note +You can use Solana RPC Conditions in the same way you would use EVM conditions, but you should pass a `solRpcConditions` array instead of a `accessControlConditions` or `evmContractConditions` array. ::: -Solana Access Control conditions work a little different than EVM access control conditions. Solana conditions let you make a Solana RPC call, and then filter and parse the response. This is useful for things like checking the balance of an account, checking the owner of an account, or checking the number of tokens a user has. - -Note that you can use Solana RPC Conditions in the same way you would use EVM conditions, but you should pass a `solRpcConditions` array instead of a `accessControlConditions` or `evmContractConditions` array. - ## Must posess an NFT in a Metaplex collection In this example, we are checking if the user owns one or more NFTs in the Metaplex collection with address `FfyafED6kiJUFwEhogyTRQHiL6NguqNg9xcdeoyyJs33`. The collection must be verified. Note that "balanceOfMetaplexCollection" is not a real Solana RPC call. It is a custom RPC call that is specific to Lit Protocol. @@ -64,28 +56,6 @@ var solRpcConditions = [ ]; ``` -## A specific wallet address - -In this example, we are checking that the user is in posession of a specific wallet address `88PoAjLoSqrTjH2cdRWq4JEezhSdDBw3g7Qa6qKQurxA`. The parameter of ":userAddress" will be automatically substituted with the user's wallet address which was verified by checking the message signed by their wallet. - -```js -var solRpcConditions = [ - { - method: "", - params: [":userAddress"], - pdaParams: [], - pdaInterface: { offset: 0, fields: {} }, - pdaKey: "", - chain: "solana", - returnValueTest: { - key: "", - comparator: "=", - value: "88PoAjLoSqrTjH2cdRWq4JEezhSdDBw3g7Qa6qKQurxA", - }, - }, -]; -``` - ## Must posess a balance of a specific token (Fungible or NFT) This example checks if the user owns at least 1 token with address `FrYwrqLcGfmXrgJKcZfrzoWsZ3pqQB9pjjUC9PxSq3xT`. This is done by deriving the user's token account address for the token contract with the user's wallet address, validated via the message signed by the user's wallet. Then, `getTokenAccountBalance` is run on the user's token account address and the result is checked against the `returnValueTest`. Note that "balanceOfToken" is not a real Solana RPC call. It is a custom RPC call that is specific to Lit Protocol. diff --git a/docs/sdk/authentication/authenticating-siws.md b/docs/sdk/authentication/authenticating-siws.md new file mode 100644 index 00000000..a8f251f6 --- /dev/null +++ b/docs/sdk/authentication/authenticating-siws.md @@ -0,0 +1,178 @@ +# Authenticating Sign-in With Solana Messages + +Deriving a Solana public key (aka. address) from a signed message works slightly differently than when using Lit to authenticate signed messages on EVM chains. + +Currently the Lit nodes support deriving an address from a Sign-in With Ethereum Message (EIP-5573), while also validating what was signed using the [EIP-5573 specification](https://eips.ethereum.org/EIPS/eip-5573) (e.g. the signed message hasn't expired and has the correct format). + +However, the Lit nodes built-in support for authenticating signed Solana messages is limited to just deriving the Solana public key from the signed data, but they do **not** perform any validation on the what was signed. This means that any data signed by a specific Solana wallet will be accepted, which opens the door for signature malleability and replay attacks. + +For example, if you had implemented access control that requires a message signed by a specific wallet to permit access, anyone could take any signed message from that specific wallet and use it to gain access, including all past transactions signed by the wallet. This is possible because the Lit nodes do not validate what was signed or when it was signed; they only validate that the data was signed by the specific wallet. + +This guide covers how to authenticate SIWS messages using a Lit Action and the [SIWS specification](https://github.com/phantom/sign-in-with-solana/tree/main) created by Phantom. + +## Prerequisites + +Before continuing with this guide, make sure you have the following: + +- An understanding of [Lit Actions](../serverless-signing/overview) and how they work +- A basic understanding of Phantom's [SIWS specification](https://github.com/phantom/sign-in-with-solana/tree/main) + +## High Level Overview + +Sign-in With Solana (SIWS) allows users to authenticate with applications by signing a standardized message using their Solana wallet. This signed message can then be verified by the app to authenticate the user securely. + +The following diagram depicts the flow of authenticating SIWS messages using Lit Actions: + +![SIWS Authentication Flow](../../../static/img/siws-authentication.png) + +:::info +A full implementation of this code example can be found [here](https://github.com/LIT-Protocol/developer-guides-code/blob/master/siws-authentication/siws-authentication/browser). +::: + +## Writing the Lit Action + +The Lit Action used for this example does the following: + +1. Parses the raw SIWS message values +2. Builds the SIWS message according to the SIWS specification +3. Validates that the provided Solana signature is valid for the SIWS message +4. Returns the authenticated Solana public key + +:::info +The full implementation of this Lit Action can be found [here](https://github.com/LIT-Protocol/developer-guides-code/blob/master/siws-authentication/browser/src/litActionSiwsAuth.ts). +::: + +### Parsing and Re-building the SIWS Message + +The SIWS message that the user signs has a specific structure defined by the SIWS specification. In this code example, the SIWS is built by the frontend and submitted to the user's wallet to prompt the user to sign the message. + +At this point the frontend has the raw SIWS message and the user's signature of the message. The frontend could verify the signature itself, but for the sake of this example we'll assume that the frontend is untrusted and we're using Lit Actions as the backend to verify the SIWS message. + +To verify the SIWS message within a Lit Action, the frontend needs to submit the raw SIWS message properties and the user's signature to the Lit Action. The Lit Action will then parse the raw SIWS message values and build the SIWS message according to the [Sign-In Input Fields specification](https://github.com/phantom/sign-in-with-solana/tree/main?tab=readme-ov-file#sign-in-input-fields). + +An example of this is as follows: + +```js +function getSiwsMessage(siwsInput) { + let message = `${siwsInput.domain} wants you to sign in with your Solana account:\n${siwsInput.address}`; + + if (siwsInput.statement) { + message += `\n\n${siwsInput.statement}`; + } + + const fields = []; + + if (siwsInput.uri !== undefined) fields.push(`URI: ${siwsInput.uri}`); + if (siwsInput.version !== undefined) + fields.push(`Version: ${siwsInput.version}`); + if (siwsInput.chainId !== undefined) + fields.push(`Chain ID: ${siwsInput.chainId}`); + if (siwsInput.nonce !== undefined) fields.push(`Nonce: ${siwsInput.nonce}`); + if (siwsInput.issuedAt !== undefined) + fields.push(`Issued At: ${siwsInput.issuedAt}`); + if (siwsInput.expirationTime !== undefined) + fields.push(`Expiration Time: ${siwsInput.expirationTime}`); + if (siwsInput.notBefore !== undefined) + fields.push(`Not Before: ${siwsInput.notBefore}`); + if (siwsInput.requestId !== undefined) + fields.push(`Request ID: ${siwsInput.requestId}`); + if (siwsInput.resources !== undefined && siwsInput.resources.length > 0) { + fields.push("Resources:"); + for (const resource of siwsInput.resources) { + fields.push(`- ${resource}`); + } + } + + if (fields.length > 0) { + message += `\n\n${fields.join("\n")}`; + } + + return message; +} +``` + +:::info +During reconstruction of the SIWS message would be a good time to validate that the given message properties like `domain`, `chainId`, `expirationTime`, etc. conform to the requirements of your application. +::: + +The output of this function is a string that represents the SIWS message that we're expecting the user to have signed: + +``` +localhost wants you to sign in with your Solana account: +5ZS9h2RYtKVnPM19JSdgKaEE4UJeSEQGgtwmfuFyqLan + +URI: http://localhost:5173 +Version: 1 +Chain ID: 0 +Nonce: 341972 +Issued At: 2024-10-03T04:55:11.105Z +Expiration Time: 2024-10-03T05:05:11.105Z +``` + +### Validating the SIWS Message Signature + +Now that we have the SIWS message, built according to the SIWS specification, we can validate is against the user's signature provided to the Lit Action: + +```js +async function verifySiwsSignature( + message, + signatureBase58, + publicKeyBase58 +) { + // Convert message to Uint8Array + const messageBytes = new TextEncoder().encode(message); + + try { + const signatureBytes = ethers.utils.base58.decode(signatureBase58); + const publicKeyBytes = ethers.utils.base58.decode(publicKeyBase58); + + // Import the public key + const publicKey = await crypto.subtle.importKey( + "raw", + publicKeyBytes, + { + name: "Ed25519", + namedCurve: "Ed25519", + }, + false, + ["verify"] + ); + + // Verify the signature + const isValid = await crypto.subtle.verify( + "Ed25519", + publicKey, + signatureBytes, + messageBytes + ); + + return isValid; + } catch (error) { + console.error("Error in verifySiwsSignature:", error); + throw error; + } +} +``` + +The result of this function is a boolean value indicating whether the signature provided to the Lit Action is for the SIWS message constructed using the provided SIWS message properties. + +We then simply return the now authenticated Solana public key (aka. address) from the given SIWS message, which is a string, to the frontend: + +```js +Lit.Actions.setResponse({ response: siwsInput.address }); +``` + +## Summary + +This guide demonstrates implementing Sign-in With Solana (SIWS) authentication using Lit Actions. + +By implementing Phantom's SIWS specification, we have established a robust and secure method for verifying Solana wallet ownership. This authentication mechanism can be extended to authorize specific Solana public keys for various operations using Lit, such as: + +- **Encrypted Data Access**: Restrict [decryption](../../sdk/access-control/intro) of sensitive information to specific Solana wallet owners. +- **Secure Session Management**: Generate [Session Signatures](../../sdk/authentication/session-sigs/get-lit-action-session-sigs) only for specific authenticated users. +- **Authorized PKP Signing**: Leverage [PKP Signing](../../user-wallets/pkps/quick-start#sign-a-transaction) to ensure only authenticated users can sign data and transactions with a specific PKP. + +Key takeaways from this implementation are that the Lit Action: + +- Reconstructs and verifies the SIWS message, ensuring the integrity of the signed data. +- Allows for custom validation of SIWS message properties to meet specific application requirements. diff --git a/docs/sdk/authentication/session-sigs/get-lit-action-session-sigs.md b/docs/sdk/authentication/session-sigs/get-lit-action-session-sigs.md index 5f7ad658..877a5bcf 100644 --- a/docs/sdk/authentication/session-sigs/get-lit-action-session-sigs.md +++ b/docs/sdk/authentication/session-sigs/get-lit-action-session-sigs.md @@ -6,7 +6,7 @@ import FeedbackComponent from "@site/src/pages/feedback.md"; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -# Generating SessionSigs Using a Lit Action +# Using a Lit Action This guide covers the `getLitActionSessionSigs` function from the Lit SDK. For an overview of what Session Signatures are and how they are to be used, please go [here](./intro). diff --git a/docs/sdk/authentication/session-sigs/get-pkp-session-sigs.md b/docs/sdk/authentication/session-sigs/get-pkp-session-sigs.md index 104f2cc9..336e604b 100644 --- a/docs/sdk/authentication/session-sigs/get-pkp-session-sigs.md +++ b/docs/sdk/authentication/session-sigs/get-pkp-session-sigs.md @@ -6,7 +6,7 @@ import FeedbackComponent from "@site/src/pages/feedback.md"; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -# Generating SessionSigs Using a PKP +# Using a PKP This guide covers the `getPkpSessionSigs` function from the Lit SDK. For an overview of what Session Signatures are and how they are to be used, please go [here](./intro). diff --git a/docs/sdk/authentication/session-sigs/get-session-sigs.md b/docs/sdk/authentication/session-sigs/get-session-sigs.md index 808d8fc7..36ddab19 100644 --- a/docs/sdk/authentication/session-sigs/get-session-sigs.md +++ b/docs/sdk/authentication/session-sigs/get-session-sigs.md @@ -6,7 +6,7 @@ import FeedbackComponent from "@site/src/pages/feedback.md"; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -# Generating SessionSigs Using an Auth Sig +# Using an Auth Sig This guide covers the `getSessionSigs` function from the Lit SDK. For an overview of what Session Signatures are and how they are to be used, please go [here](./intro). diff --git a/docs/sdk/authentication/session-sigs/siws-pkp-session-sigs.md b/docs/sdk/authentication/session-sigs/siws-pkp-session-sigs.md new file mode 100644 index 00000000..fc73419e --- /dev/null +++ b/docs/sdk/authentication/session-sigs/siws-pkp-session-sigs.md @@ -0,0 +1,142 @@ +# Using a Sign-in With Solana Message + +This guide builds on the [Sign-in With Solana Authentication](../authenticating-siws) guide to show how to use Lit Actions to generate PKP Session Signatures for an authorized Solana public key. + +## Prerequisites + +Before continuing with this guide, make sure you have the following: + +- An understanding of how to generate Session Signatures [using a Lit Action](./get-lit-action-session-sigs) +- An understanding of how to [authenticate SIWS messages](../../authentication/authenticating-siws) using a Lit Action +- An understanding of [Authentication Methods](../../../user-wallets/pkps/advanced-topics/auth-methods/overview) and how the can be used to restrict PKP signing capabilities + - You should also be familiar with [Custom Auth Methods](../../../user-wallets/pkps/advanced-topics/auth-methods/custom-auth) +- A basic understanding of Phantom's [SIWS specification](https://github.com/phantom/sign-in-with-solana/tree/main) + +## High Level Overview + +The following diagram depicts the flow of using a PKP to generate Session Signatures for an authorized Solana public key: + +![SIWS PKP Session Sigs Flow](../../../../static/img/siws-session-signatures.png) + +:::info +A full implementation of this code example can be found [here](https://github.com/LIT-Protocol/developer-guides-code/blob/master/siws-session-sigs/browser). +::: + +## Minting the PKP with Permitted Auth Methods + +In the complete implementation of this code example, there's a method called `mintPkpAndAddPermittedAuthMethods`. This method is responsible for minting a PKP and permitting the following PKP auth methods: + +- The IPFS CID of the Lit Action that will be executed to authenticate the SIWS message and generate the Session Signatures +- The Solana public key that will be authorized to sign using the PKP + +To add the Solana public key as a permitted Auth Method, we're going to use Custom Auth Methods. This just means we're going to define our own _Auth Method Type_ and _Auth Method ID_: + +```ts +const authMethodType = ethers.utils.keccak256( + // This can be anything, but should be unique to your app + ethers.utils.toUtf8Bytes("Lit Developer Guide Solana SIWS Example") +); +const authMethodId = ethers.utils.keccak256( + ethers.utils.toUtf8Bytes(`siws:${solanaPublicKey}`) +); +``` + +Then we utilize the [mintNextAndAddAuthMethods](https://v6-api-doc-lit-js-sdk.vercel.app/classes/contracts_sdk_src.LitContracts.html#pkpHelperContractUtil) from the `@lit-protocol/contracts-sdk` package to mint the PKP and add the permitted auth methods to the PKP: + +```ts +const tx = + await litContractsClient.pkpHelperContract.write.mintNextAndAddAuthMethods( + AuthMethodType.LitAction, // keyType + [AuthMethodType.LitAction, authMethodType], // permittedAuthMethodTypes + [ + `0x${Buffer.from( + ethers.utils.base58.decode( + await calculateLitActionCodeCID(litActionSessionSigs) + ) + ).toString("hex")}`, + authMethodId, + ], // permittedAuthMethodIds + ["0x", "0x"], // permittedAuthMethodPubkeys + [[AuthMethodScope.SignAnything], [AuthMethodScope.NoPermissions]], // permittedAuthMethodScopes + true, // addPkpEthAddressAsPermittedAddress + true, // sendPkpToItself + { value: await litContractsClient.pkpNftContract.read.mintCost() } +); +const receipt = await tx.wait(); +``` + +:::info +It's important to note that the first permitted Auth Method (the IPFS CID of the Lit Action) has the permission scope: `[AuthMethodScope.SignAnything]` which allows anything to be signed using the PKP, as long as the signing request is executed from within the Lit Action with the specific IPFS CID. + +The second permitted Auth Method (our custom Auth Method) has the permission scope: `[AuthMethodScope.NoPermissions]` which grants no signing permissions. This is desired because this Auth Method is only used by the Lit Action to check if a Solana public key is authorized to sign using the PKP. +::: + +At this point, we have minted a PKP that is only authorized to sign within a specific Lit Action, and can check if a derived Solana public key from a signed SIWS message is authorized to sign using the PKP. + +## Writing the Lit Action + +The Lit Action used for this example does the following: + +1. Parses the raw SIWS message values +2. Builds the SIWS message according to the SIWS specification +3. Validates that the provided Solana signature is valid for the SIWS message +4. Builds our custom Auth Method Type and ID using the authenticated Solana public key +5. Makes a request to the Lit PKP permissions smart contract to check if the Auth Method Type and ID are permitted for the PKP +6. If permitted, returns the magic value, `"true"`, signalling the Lit network to generate Session Signatures using a given PKP +7. The Lit network returns the generated Session Signatures + +For steps 1 - 3, we reuse the SIWS authentication logic from the [SIWS Authentication](../../authentication/authenticating-siws#parsing-and-re-building-the-siws-message) guide, so this guide will pick up from step 4. + +:::note +The full implementation of this Lit Action can be found [here](https://github.com/LIT-Protocol/developer-guides-code/blob/master/siws-accs/browser/src/litActionSiws.ts). +::: + +### Checking if the Solana Public Key is Authorized + +First we generate the Custom Auth Method Type and ID using the authenticated Solana public key: + +```ts +const SIWS_AUTH_METHOD_TYPE = ethers.utils.keccak256( + ethers.utils.toUtf8Bytes("Lit Developer Guide Solana SIWS Example") +); +const usersAuthMethodId = ethers.utils.keccak256( + ethers.utils.toUtf8Bytes(`siws:${solanaPublicKey}`) +); +``` + +Then we make a request to the Lit PKP permissions smart contract to check if the Auth Method Type and ID are permitted for the PKP: + +```ts +return Lit.Actions.isPermittedAuthMethod({ + tokenId: pkpTokenId, + authMethodType: SIWS_AUTH_METHOD_TYPE, + userId: ethers.utils.arrayify(usersAuthMethodId), +}); +``` + +If this contract call returns `true`, then we know that the Solana public key is authorized to sign using the PKP, and we can proceed to generate Session Signatures using the PKP. + +### Generating Session Signatures + +Now that we've checked the authenticated Solana public key is authorized to sign using the PKP, we simply return the following to signal the Lit network to generate Session Signatures using the PKP: + +```ts +return Lit.Actions.setResponse({ response: "true" }); +``` + +The Lit network will then generate Session Signatures for the PKP and return them to the frontend. + +## Summary + +This guide demonstrates how to leverage Phantom's Sign-in With Solana (SIWS) specification and Lit Actions to generate PKP Session Signatures using an authenticated SIWS message. + +Key takeaways from this implementation are: + +- The PKP is minted with specific permitted Auth Methods, including a Lit Action IPFS CID and a custom Auth Method for the Solana public key. +- The Lit Action reconstructs and verifies the SIWS message, ensuring the integrity of the signed data. +- The Lit Action checks if the authenticated Solana public key is authorized to use the PKP by querying the Lit PKP permissions smart contract. +- Upon successful authorization, the Lit Action signals the Lit network to generate Session Signatures for the PKP. + +:::note +A full implementation of this code example can be found [here](https://github.com/LIT-Protocol/developer-guides-code/blob/master/siws-session-sigs/browser). +::: diff --git a/sidebars.js b/sidebars.js index cdaf760f..b7cf3011 100644 --- a/sidebars.js +++ b/sidebars.js @@ -162,6 +162,7 @@ const sidebars = { label: 'Authentication', collapsed: true, items: [ + 'sdk/authentication/security', { type: 'category', label: 'Session Signatures', @@ -174,13 +175,21 @@ const sidebars = { 'sdk/authentication/session-sigs/resources-and-abilities', 'sdk/authentication/session-sigs/capability-objects', 'sdk/capacity-credits', - 'sdk/authentication/session-sigs/get-session-sigs', - 'sdk/authentication/session-sigs/get-pkp-session-sigs', - 'sdk/authentication/session-sigs/get-lit-action-session-sigs', + { + type: 'category', + label: 'Generating Session Signatures', + collapsed: true, + items: [ + 'sdk/authentication/session-sigs/get-session-sigs', + 'sdk/authentication/session-sigs/get-pkp-session-sigs', + 'sdk/authentication/session-sigs/get-lit-action-session-sigs', + 'sdk/authentication/session-sigs/siws-pkp-session-sigs', + ], + }, 'sdk/authentication/session-sigs/usage', ], }, - 'sdk/authentication/security', + 'sdk/authentication/authenticating-siws', ], }, { @@ -319,13 +328,19 @@ const sidebars = { }, { type: 'category', - label: 'Other Chains', + label: 'Solana', collapsed: true, items: [ - 'sdk/access-control/other-chains/sol-rpc-conditions', - 'sdk/access-control/other-chains/cosmos-conditions', + 'sdk/access-control/solana/siws-access-control', + 'sdk/access-control/solana/sol-rpc-conditions', ], }, + { + type: 'category', + label: 'Other Chains', + collapsed: true, + items: ['sdk/access-control/other-chains/cosmos-conditions'], + }, { type: 'category', label: 'Off-Chain', diff --git a/static/img/siws-accs.png b/static/img/siws-accs.png new file mode 100644 index 00000000..7b2a8ed1 Binary files /dev/null and b/static/img/siws-accs.png differ diff --git a/static/img/siws-authentication.png b/static/img/siws-authentication.png new file mode 100644 index 00000000..7cf8c693 Binary files /dev/null and b/static/img/siws-authentication.png differ diff --git a/static/img/siws-session-signatures.png b/static/img/siws-session-signatures.png new file mode 100644 index 00000000..c0d4c9ae Binary files /dev/null and b/static/img/siws-session-signatures.png differ