The keys are encrypted and stored in a DynamoDB instance managed by us.
Every wrapped key is associated with a PKP which is used only for authentication and not for signing since the wrapped keys are used for signing.
The access to the database is guarded by Lambda which allows only the PKP sessionSig to query the wrapped key item associated with it.
We only provide a single sessionSig to the Lambda since we only need to compare the delegation/inner AuthSig for establishing the wrapped key ownership.
SDK package
The idea is to provide very easy to use functions for:
importPrivateKey- Imports a private key as a string and stores in our DynamoDB
generatePrivateKey- For new users generate a random private key inside the Lit Action and return it to the SDK that internally stores it in DynamoDB
exportPrivateKey- Fetches the DynamoDB item and decrypts using decryptString and provides the decrypted private key to the user after stripping the pre-pended "lit_"
signTransactionWithEncryptedKey- Fetches the item from DynamoDB and calls the Lit Action to sign the user provided transaction object. Optionally, broadcasts the signed transaction and returns the tx hash or just returns the signed tx that the user can broadcast themselves
signMessageWithEncryptedKey- Fetches the item from DynamoDB and calls the Lit Action to sign the user provided message object
Access Control
The private data is encrypted with the condition to allow only the specific PKP wallet address to decrypt it. We prepend "lit_" to the private key hex string for security reasons.
Supported Chains
We currently support all the EVM chains supported by the Lit nodes in the rpc.config.yaml file and all 3 Solana chains.
Lit Actions
The idea is that the only place where the bare (un-encrypted) private key exist is the Lit Action (that too on a single node). Hence the SDK only fetches the encrypted private key from DynamoDB and provide it to the Lit Action where it is internally decrypted and used to sign and finally return the signed tx/message.
Since the idea is to provide a default function that doesn't require the user to provide a Lit Action we have published all the Lit Actions and use their ipfsCid instead of passing the code as a string.
There are separate Lit Actions for Solana & EVM wrapped keys because they have different dependencies like Solana Lit Actions need the solana/web3 to be bundled (wrapped-keys/esbuild.config.js).
Since Solana tx have several params we accept an unsigned serialized tx in the Lit Action param whereas for EVM we accept tx params and craft the transaction object inside the Lit Action.
Note: We don't wait for the transaction to be confirmed after broadcasting from inside the Lit Action since it could take very long and the Lit Action can timeout.
Tests
There are unit test for utility functions and Tinny test to test several valid and invalid scenarios for all the 5 functionalities listed above.
Special Attention
While reviewing please pay special attention to the assertion in the tests which should be strict and the error handling i.e. we're throwing error when either the AWS DB throws an error or when the SDK throws an error eg: executeJs. Finally we're doing a bunch of if conditional checks after receiving the response from the executeJs
Author: @DashKash54
What
We add a new SDK package:
wrapped-keys
. It's been published with thebeta
tag: https://www.npmjs.com/package/@lit-protocol/wrapped-keys/v/6.0.3-wrapped-keys.beta.2AWS
SDK package
The idea is to provide very easy to use functions for:
importPrivateKey
- Imports a private key as a string and stores in our DynamoDBgeneratePrivateKey
- For new users generate a random private key inside the Lit Action and return it to the SDK that internally stores it in DynamoDBexportPrivateKey
- Fetches the DynamoDB item and decrypts usingdecryptString
and provides the decrypted private key to the user after stripping the pre-pended "lit_"signTransactionWithEncryptedKey
- Fetches the item from DynamoDB and calls the Lit Action to sign the user provided transaction object. Optionally, broadcasts the signed transaction and returns the tx hash or just returns the signed tx that the user can broadcast themselvessignMessageWithEncryptedKey
- Fetches the item from DynamoDB and calls the Lit Action to sign the user provided message objectAccess Control
The private data is encrypted with the condition to allow only the specific PKP wallet address to decrypt it. We prepend "lit_" to the private key hex string for security reasons.
Supported Chains
We currently support all the EVM chains supported by the Lit nodes in the
rpc.config.yaml
file and all 3 Solana chains.Lit Actions
The idea is that the only place where the bare (un-encrypted) private key exist is the Lit Action (that too on a single node). Hence the SDK only fetches the encrypted private key from DynamoDB and provide it to the Lit Action where it is internally decrypted and used to sign and finally return the signed tx/message.
Since the idea is to provide a default function that doesn't require the user to provide a Lit Action we have published all the Lit Actions and use their
ipfsCid
instead of passing the code as a string.There are separate Lit Actions for Solana & EVM wrapped keys because they have different dependencies like Solana Lit Actions need the
solana/web3
to be bundled (wrapped-keys/esbuild.config.js
).Since Solana tx have several params we accept an unsigned serialized tx in the Lit Action param whereas for EVM we accept tx params and craft the transaction object inside the Lit Action.
Note: We don't wait for the transaction to be confirmed after broadcasting from inside the Lit Action since it could take very long and the Lit Action can timeout.
Tests
There are unit test for utility functions and Tinny test to test several valid and invalid scenarios for all the 5 functionalities listed above.
Special Attention
While reviewing please pay special attention to the assertion in the tests which should be strict and the error handling i.e. we're throwing error when either the AWS DB throws an error or when the SDK throws an error eg:
executeJs
. Finally we're doing a bunch of if conditional checks after receiving the response from theexecuteJs