Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
46 changes: 26 additions & 20 deletions packages/wrapped-keys-lit-actions/esbuild.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,30 @@ module.exports = {
};

(async () => {
await esbuild.build({
entryPoints: [
'./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',
],
bundle: true,
minify: true,
sourcemap: false,
treeShaking: true,
outdir: './src/generated/',
inject: ['./buffer.shim.js'],
plugins: [wrapIIFEInStringPlugin],
platform: 'browser',
});
try {
await esbuild.build({
entryPoints: [
'./src/lib/self-executing-actions/solana/signTransactionWithEncryptedSolanaKey.ts',
'./src/lib/self-executing-actions/solana/signMessageWithEncryptedSolanaKey.ts',
'./src/lib/self-executing-actions/solana/generateEncryptedSolanaPrivateKey.ts',
'./src/lib/self-executing-actions/ethereum/signTransactionWithEncryptedEthereumKey.ts',
'./src/lib/self-executing-actions/ethereum/signMessageWithEncryptedEthereumKey.ts',
'./src/lib/self-executing-actions/ethereum/generateEncryptedEthereumPrivateKey.ts',
'./src/lib/self-executing-actions/common/exportPrivateKey.ts',
'./src/lib/self-executing-actions/common/batchGenerateEncryptedKeys.ts',
],
bundle: true,
minify: true,
sourcemap: false,
treeShaking: true,
outdir: './src/generated/',
inject: ['./buffer.shim.js'],
plugins: [wrapIIFEInStringPlugin],
platform: 'browser',
});
console.log('✅ Lit actions built successfully');
} catch (e) {
console.error('❌ Error building lit actions: ', e);
process.exit(1);
}
})();
390 changes: 390 additions & 0 deletions packages/wrapped-keys-lit-actions/global.d.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export class AbortError extends Error {
name = 'AbortError';
override name = 'AbortError';
}

export const rethrowIfAbortError = (err) => {
export const rethrowIfAbortError = (err: any) => {
if (err instanceof AbortError) {
throw err;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ export async function encryptPrivateKey({
accessControlConditions,
privateKey,
publicKey,
}) {
}: {
accessControlConditions: string;
privateKey: string;
publicKey: string;
}): Promise<{
ciphertext: string;
dataToEncryptHash: string;
publicKey: string;
}> {
const { ciphertext, dataToEncryptHash } = await Lit.Actions.encrypt({
accessControlConditions,
to_encrypt: new TextEncoder().encode(LIT_PREFIX + privateKey),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
import { AbortError } from '../../abortError';
import { removeSaltFromDecryptedKey } from '../../utils';

interface TryDecryptToSingleNodeParams {
accessControlConditions: any;
ciphertext: string;
dataToEncryptHash: string;
}

async function tryDecryptToSingleNode({
accessControlConditions,
ciphertext,
dataToEncryptHash,
}) {
}: TryDecryptToSingleNodeParams): Promise<string | undefined> {
try {
// May be undefined, since we're using `decryptToSingleNode`
return await Lit.Actions.decryptToSingleNode({
Expand All @@ -17,16 +23,22 @@ async function tryDecryptToSingleNode({
chain: 'ethereum',
authSig: null,
});
} catch (err) {
} catch (err: any) {
throw new Error(`When decrypting key to a single node - ${err.message}`);
}
}

interface GetDecryptedKeyToSingleNodeParams {
accessControlConditions: string; // Define a more specific type if possible
ciphertext: string; // Define a more specific type if possible
dataToEncryptHash: string; // Define a more specific type if possible
}

export async function getDecryptedKeyToSingleNode({
accessControlConditions,
ciphertext,
dataToEncryptHash,
}) {
}: GetDecryptedKeyToSingleNodeParams): Promise<string> {
const decryptedPrivateKey = await tryDecryptToSingleNode({
accessControlConditions,
ciphertext,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* global ethers */

interface SignMessageParams {
privateKey: string;
messageToSign: string;
}

interface VerifyMessageSignatureParams {
messageToSign: string;
signature: string;
}

async function signMessage({
privateKey,
messageToSign,
}: SignMessageParams): Promise<{ signature: string; walletAddress: string }> {
try {
const wallet = new ethers.Wallet(privateKey);
const signature = await wallet.signMessage(messageToSign);

return { signature, walletAddress: wallet.address };
} catch (err: unknown) {
throw new Error(`When signing message - ${(err as Error).message}`);
}
}

function verifyMessageSignature({
messageToSign,
signature,
}: VerifyMessageSignatureParams): string {
try {
return ethers.utils.verifyMessage(messageToSign, signature);
} catch (err: unknown) {
throw new Error(
`When validating signed Ethereum message is valid: ${
(err as Error).message
}`
);
}
}

export async function signMessageEthereumKey({
privateKey,
messageToSign,
}: SignMessageParams): Promise<string> {
const { signature, walletAddress } = await signMessage({
privateKey,
messageToSign,
});

const recoveredAddress = verifyMessageSignature({ messageToSign, signature });

if (recoveredAddress !== walletAddress) {
throw new Error(
"Recovered address from verifyMessage doesn't match the wallet address"
);
}

return signature;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
/* global ethers, Lit */

export function getValidatedUnsignedTx(unsignedTransaction) {
interface UnsignedTransaction {
toAddress: string;
chain: string;
value: string;
chainId: number;
dataHex?: string;
gasPrice?: string;
gasLimit?: number;
}

export function getValidatedUnsignedTx(
unsignedTransaction: UnsignedTransaction
) {
try {
if (!unsignedTransaction.toAddress) {
throw new Error('Missing required field: toAddress');
Expand All @@ -26,73 +38,107 @@ export function getValidatedUnsignedTx(unsignedTransaction) {
chainId: unsignedTransaction.chainId,
data: unsignedTransaction.dataHex,
};
} catch (err) {
throw new Error(`Invalid unsignedTransaction - ${err.message}`);
} catch (err: unknown) {
throw new Error(`Invalid unsignedTransaction - ${(err as Error).message}`);
}
}

async function getLatestNonce({ walletAddress, chain }) {
async function getLatestNonce({
walletAddress,
chain,
}: {
walletAddress: string;
chain: string;
}) {
try {
const nonce = await Lit.Actions.getLatestNonce({
address: walletAddress,
chain: chain,
});

return nonce;
} catch (err) {
throw new Error(`Unable to get latest nonce - ${err.message}`);
} catch (err: unknown) {
throw new Error(`Unable to get latest nonce - ${(err as Error).message}`);
}
}

async function getEthersRPCProvider({ chain }) {
async function getEthersRPCProvider({ chain }: { chain: string }) {
try {
const rpcUrl = await Lit.Actions.getRpcUrl({
chain,
});

return new ethers.providers.JsonRpcProvider(rpcUrl);
} catch (err) {
throw new Error(`Getting the rpc for the chain: ${chain} - ${err.message}`);
} catch (err: unknown) {
throw new Error(
`Getting the rpc for the chain: ${chain} - ${(err as Error).message}`
);
}
}

async function getGasPrice({ userProvidedGasPrice, provider }) {
async function getGasPrice({
userProvidedGasPrice,
provider,
}: {
userProvidedGasPrice?: string;
provider: any;
}) {
try {
if (userProvidedGasPrice) {
return ethers.utils.parseUnits(userProvidedGasPrice, 'gwei');
} else {
return await provider.getGasPrice();
}
} catch (err) {
throw new Error(`When getting gas price - ${err.message}`);
} catch (err: unknown) {
throw new Error(`When getting gas price - ${(err as Error).message}`);
}
}

async function getGasLimit({ provider, userProvidedGasLimit, validatedTx }) {
async function getGasLimit({
provider,
userProvidedGasLimit,
validatedTx,
}: {
provider: any;
userProvidedGasLimit?: number;
validatedTx: any;
}) {
if (userProvidedGasLimit) {
return userProvidedGasLimit;
} else {
try {
return await provider.estimateGas(validatedTx);
} catch (err) {
throw new Error(`When estimating gas - ${err.message}`);
} catch (err: unknown) {
throw new Error(`When estimating gas - ${(err as Error).message}`);
}
}
}

async function signTransaction({ validatedTx, wallet }) {
async function signTransaction({
validatedTx,
wallet,
}: {
validatedTx: any;
wallet: any;
}) {
try {
return await wallet.signTransaction(validatedTx);
} catch (err) {
throw new Error(`When signing transaction - ${err.message}`);
} catch (err: unknown) {
throw new Error(`When signing transaction - ${(err as Error).message}`);
}
}

async function broadcastTransaction({ provider, signedTx }) {
async function broadcastTransaction({
provider,
signedTx,
}: {
provider: any;
signedTx: string;
}) {
try {
return await provider.sendTransaction(signedTx);
} catch (err) {
throw new Error(`When sending transaction - ${err.message}`);
} catch (err: unknown) {
throw new Error(`When sending transaction - ${(err as Error).message}`);
}
}

Expand All @@ -101,6 +147,11 @@ export async function signTransactionEthereumKey({
privateKey,
validatedTx,
unsignedTransaction,
}: {
broadcast: boolean;
privateKey: string;
validatedTx: any;
unsignedTransaction: UnsignedTransaction;
}) {
const wallet = new ethers.Wallet(privateKey);

Expand Down
Loading
Loading