Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
20caa66
refactor(wrapped-keys-lit-actions): LIT-3959 - Restructure directory …
MaximusHaximus Oct 11, 2024
b78a54e
refactor(wrapped-keys-lit-actions): LIT-3959 - Extract `batchGenerate…
MaximusHaximus Oct 11, 2024
b704210
refactor(wrapped-keys-lit-actions): LIT-3959 - Extract `exportPrivate…
MaximusHaximus Oct 11, 2024
53bf8c2
refactor(wrapped-keys-lit-actions): LIT-3959 - Extract `generateEncry…
MaximusHaximus Oct 11, 2024
a9689c8
refactor(wrapped-keys-lit-actions): LIT-3959 - Extract `signMessageWi…
MaximusHaximus Oct 11, 2024
3a93825
refactor(wrapped-keys-lit-actions): LIT-3959 - Extract `signTransacti…
MaximusHaximus Oct 12, 2024
fc797d1
refactor(wrapped-keys-lit-actions): LIT-3959 - Extract `generateEncry…
MaximusHaximus Oct 12, 2024
bd24619
refactor(wrapped-keys-lit-actions): LIT-3959 - Extract `signMessageWi…
MaximusHaximus Oct 12, 2024
c211e59
refactor(wrapped-keys-lit-actions): LIT-3959 - Extract `signTransacti…
MaximusHaximus Oct 12, 2024
ea8d913
feat(wrapped-keys-lit-actions): LIT-3959 - Add abortError and litActi…
MaximusHaximus Oct 12, 2024
f80ef12
feat(wrapped-keys-lit-actions): LIT-3959 - Update getDecryptedKeyToSi…
MaximusHaximus Oct 12, 2024
a5f2604
refactor(wrapped-keys-lit-actions): LIT-3959 - Refactor generateEncry…
MaximusHaximus Oct 12, 2024
34ab5b8
refactor(wrapped-keys-lit-actions): LIT-3959 - Refactor signTransacti…
MaximusHaximus Oct 12, 2024
88a18c2
refactor(wrapped-keys-lit-actions): LIT-3959 - Refactor signMessageWi…
MaximusHaximus Oct 12, 2024
6c37c93
refactor(wrapped-keys-lit-actions): LIT-3959 - Refactor generateEncry…
MaximusHaximus Oct 12, 2024
451f906
refactor(wrapped-keys-lit-actions): LIT-3959 - Refactor signMessageWi…
MaximusHaximus Oct 12, 2024
4971a20
refactor(wrapped-keys-lit-actions): LIT-3959 - Refactor signTransacti…
MaximusHaximus Oct 12, 2024
b728850
refactor(wrapped-keys-lit-actions): LIT-3959 - Refactor exportPrivate…
MaximusHaximus Oct 12, 2024
81c3a72
refactor(wrapped-keys-lit-actions): LIT-3959 - Refactor batchGenerate…
MaximusHaximus Oct 12, 2024
f8dc375
feat(wrapped-keys-lit-actions): LIT-3959 - Export raw LIT action func…
MaximusHaximus Oct 12, 2024
141f0a0
feat(wrapped-keys-lit-actions): LIT-3959 - Ensure string values are n…
MaximusHaximus Oct 12, 2024
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
16 changes: 8 additions & 8 deletions packages/wrapped-keys-lit-actions/esbuild.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ module.exports = {
(async () => {
await esbuild.build({
entryPoints: [
'./src/lib/solana/signTransactionWithEncryptedSolanaKey.js',
'./src/lib/solana/signMessageWithEncryptedSolanaKey.js',
'./src/lib/solana/generateEncryptedSolanaPrivateKey.js',
'./src/lib/ethereum/signTransactionWithEncryptedEthereumKey.js',
'./src/lib/ethereum/signMessageWithEncryptedEthereumKey.js',
'./src/lib/ethereum/generateEncryptedEthereumPrivateKey.js',
'./src/lib/common/exportPrivateKey.js',
'./src/lib/common/batchGenerateEncryptedKeys.js',
'./src/lib/self-executing-actions/solana/signTransactionWithEncryptedSolanaKey.js',
'./src/lib/self-executing-actions/solana/signMessageWithEncryptedSolanaKey.js',
'./src/lib/self-executing-actions/solana/generateEncryptedSolanaPrivateKey.js',
'./src/lib/self-executing-actions/ethereum/signTransactionWithEncryptedEthereumKey.js',
'./src/lib/self-executing-actions/ethereum/signMessageWithEncryptedEthereumKey.js',
'./src/lib/self-executing-actions/ethereum/generateEncryptedEthereumPrivateKey.js',
'./src/lib/self-executing-actions/common/exportPrivateKey.js',
'./src/lib/self-executing-actions/common/batchGenerateEncryptedKeys.js',
Comment on lines +53 to +60
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: "self-executing-actions" makes me think of a cron of that they don't have to be triggered

],
bundle: true,
minify: true,
Expand Down
5 changes: 5 additions & 0 deletions packages/wrapped-keys-lit-actions/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as signTransactionWithEthereumEncryptedKey from './generated/ethereum/s
import * as generateEncryptedSolanaPrivateKey from './generated/solana/generateEncryptedSolanaPrivateKey';
import * as signMessageWithSolanaEncryptedKey from './generated/solana/signMessageWithEncryptedSolanaKey';
import * as signTransactionWithSolanaEncryptedKey from './generated/solana/signTransactionWithEncryptedSolanaKey';
import { rawActionFunctions } from './lib/raw-action-functions';

import type {
LitActionCodeRepository,
Expand Down Expand Up @@ -36,6 +37,10 @@ const litActionRepositoryCommon: LitActionCodeRepositoryCommon = {
};

export {
// Raw functions, <not wrapped in IIFEs>, for consumers to be able to compose these into their own LIT actions
// Facilitates running e.g. `batchGenerateEncryptedKeys` using `Lit.Actions.runOnce` inside of another action
rawActionFunctions,

// Individual exports to allow tree-shaking and only importing the lit actions you need
batchGenerateEncryptedKeys,
exportPrivateKey,
Expand Down
9 changes: 9 additions & 0 deletions packages/wrapped-keys-lit-actions/src/lib/abortError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export class AbortError extends Error {
name = 'AbortError';
}

export const rethrowIfAbortError = (err) => {
if (err instanceof AbortError) {
throw err;
}
};
Comment on lines +1 to +9
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be moved to errors.ts in constants in v7. As followup

Might be a long shot, because nodes are in the middle, but we can think of shared errors between SDK and LAs

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* global Lit */

import { AbortError } from '../../abortError';
import { removeSaltFromDecryptedKey } from '../../utils';

async function tryDecryptToSingleNode({
accessControlConditions,
ciphertext,
dataToEncryptHash,
}) {
try {
// May be undefined, since we're using `decryptToSingleNode`
return await Lit.Actions.decryptToSingleNode({
accessControlConditions,
ciphertext,
dataToEncryptHash,
chain: 'ethereum',
authSig: null,
});
} catch (err) {
throw new Error(`When decrypting key to a single node - ${err.message}`);
}
}

export async function getDecryptedKeyToSingleNode({
accessControlConditions,
ciphertext,
dataToEncryptHash,
}) {
const decryptedPrivateKey = await tryDecryptToSingleNode({
accessControlConditions,
ciphertext,
dataToEncryptHash,
});

if (!decryptedPrivateKey) {
// Silently exit on nodes which didn't run the `decryptToSingleNode` code
throw new AbortError();
}

return removeSaltFromDecryptedKey(decryptedPrivateKey);
}
25 changes: 25 additions & 0 deletions packages/wrapped-keys-lit-actions/src/lib/litActionHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* global Lit */

import { AbortError } from './abortError';

export async function litActionHandler(actionFunc) {
try {
const litActionResult = await actionFunc();
// Don't re-stringify a string; we don't want to double-escape it
const response =
typeof litActionResult === 'string'
? litActionResult
: JSON.stringify(litActionResult);

Lit.Actions.setResponse({ response });
} catch (err) {
// AbortError means exit immediately and do _NOT_ set a response
// Nested code should really only throw this in cases where using e.g. `decryptToSingleNode`
// And this execution isn't that node.
if (err instanceof AbortError) {
return;
}

Lit.Actions.setResponse({ response: `Error: ${err.message}` });
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
const { encryptPrivateKey } = require('./internal/encryptKey');
const { encryptPrivateKey } = require('../../internal/common/encryptKey');
const {
generateEthereumPrivateKey,
} = require('../ethereum/internal/generatePrivateKey');
const { signMessageEthereumKey } = require('../ethereum/internal/signMessage');
} = require('../../internal/ethereum/generatePrivateKey');
const {
signMessageEthereumKey,
} = require('../../internal/ethereum/signMessage');
const {
generateSolanaPrivateKey,
} = require('../solana/internal/generatePrivateKey');
const { signMessageSolanaKey } = require('../solana/internal/signMessage');

/* global accessControlConditions, actions, Lit*/
} = require('../../internal/solana/generatePrivateKey');
const { signMessageSolanaKey } = require('../../internal/solana/signMessage');

async function processEthereumAction(action) {
async function processEthereumAction({ action, accessControlConditions }) {
const { network, generateKeyParams } = action;
const messageToSign = action.signMessageParams?.messageToSign;

Expand Down Expand Up @@ -42,7 +42,7 @@ async function processEthereumAction(action) {
};
}

async function processSolanaAction(action) {
async function processSolanaAction({ action, accessControlConditions }) {
const { network, generateKeyParams } = action;

const messageToSign = action.signMessageParams?.messageToSign;
Expand Down Expand Up @@ -75,15 +75,21 @@ async function processSolanaAction(action) {
};
}

async function processActions(actions) {
async function processActions({ actions, accessControlConditions }) {
return Promise.all(
actions.map(async (action, ndx) => {
const { network } = action;

if (network === 'evm') {
return await processEthereumAction(action, ndx);
return await processEthereumAction({
action,
accessControlConditions,
});
} else if (network === 'solana') {
return await processSolanaAction(action, ndx);
return await processSolanaAction({
action,
accessControlConditions,
});
} else {
// Just in case :tm:
throw new Error(`Invalid network for action[${ndx}]: ${network}`);
Expand Down Expand Up @@ -128,20 +134,14 @@ function validateParams(actions) {
});
}

(async () => {
try {
validateParams(actions);

const batchGeneratePrivateKeysActionResult = await processActions(actions);

Lit.Actions.setResponse({
response: JSON.stringify(batchGeneratePrivateKeysActionResult),
});
export async function batchGenerateEncryptedKeys({
actions,
accessControlConditions,
}) {
validateParams(actions);

// 1. Generate both EVM and solana private keys
// 2. Run appropriate signMessage for each key _and_ encrypt the keys for persistence to wrapped-keys backend
// 3. Return results for both signMessage ops and both encrypted key payloads for persistence
} catch (err) {
Lit.Actions.setResponse({ response: `Error: ${err.message}` });
}
})();
return processActions({
actions,
accessControlConditions,
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const {
getDecryptedKeyToSingleNode,
} = require('../../internal/common/getDecryptedKeyToSingleNode');

/**
*
* Exports the private key after decrypting and removing the salt from it.
*
* @jsParam pkpAddress - The Eth address of the PKP which is associated with the Wrapped Key
* @jsParam ciphertext - For the encrypted Wrapped Key
* @jsParam dataToEncryptHash - For the encrypted Wrapped Key
* @jsParam accessControlConditions - The access control condition that allows only the pkpAddress to decrypt the Wrapped Key
*
* @returns { Promise<string> } - Returns a decrypted private key.
*/

export async function exportPrivateKey({
accessControlConditions,
ciphertext,
dataToEncryptHash,
}) {
return getDecryptedKeyToSingleNode({
accessControlConditions,
ciphertext,
dataToEncryptHash,
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
*
* Generates a random Ethers private key and only allows the provided PKP to decrypt it
*
* @jsParam pkpAddress - The Eth address of the PKP which is associated with the Wrapped Key
* @jsParam accessControlConditions - The access control condition that allows only the pkpAddress to decrypt the Wrapped Key
*
* @returns { Promise<{ciphertext: string, dataToEncryptHash: string, publicKey: string}> } - Returns object with ciphertext & dataToEncryptHash which are the result of the encryption. Also returns the publicKey of the newly generated Ethers Wrapped Key.
*/
import { encryptPrivateKey } from '../../internal/common/encryptKey';
import { generateEthereumPrivateKey } from '../../internal/ethereum/generatePrivateKey';

export async function generateEncryptedEthereumPrivateKey({
accessControlConditions,
}) {
const { privateKey, publicKey } = generateEthereumPrivateKey();
return encryptPrivateKey({
accessControlConditions,
privateKey,
publicKey,
});
}
Loading
Loading