Skip to content
This repository was archived by the owner on Apr 30, 2025. It is now read-only.

Wrapped Keys v0 #32

Draft
wants to merge 3 commits 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
12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"clean": "node tools/clean.js",
"lint": "npx nx run-many -t lint",
"test": "npx nx run-many -t test -- --passWithNoTests",
"deploy:tools": "npx nx deploy aw-tool-uniswap-swap && npx nx deploy aw-tool-sign-ecdsa && npx nx deploy aw-tool-erc20-transfer",
"deploy:tools": "npx nx deploy aw-tool-uniswap-swap && npx nx deploy aw-tool-sign-ecdsa && npx nx deploy aw-tool-erc20-transfer && npx nx deploy aw-tool-sign-eddsa",
"start:cli": "pnpm build && pnpm deploy:tools && NO_DEPRECATION=* node packages/aw-cli/dist/src/index.js",
"start:cli:no-build": "NO_DEPRECATION=* node packages/aw-cli/dist/src/index.js"
},
Expand All @@ -22,12 +22,19 @@
"@swc/helpers": "~0.5.11",
"@types/jest": "^29.5.12",
"@types/node": "18.16.9",
"browserify-fs": "^1.0.0",
"buffer": "^6.0.3",
"crypto-browserify": "^3.12.1",
"eslint": "^9.8.0",
"eslint-config-prettier": "^9.0.0",
"http-browserify": "^1.7.0",
"https-browserify": "^1.0.0",
"jest": "^29.7.0",
"jest-environment-node": "^29.7.0",
"nx": "20.3.0",
"path-browserify": "^1.0.1",
"prettier": "^2.6.2",
"stream-browserify": "^3.0.0",
"ts-jest": "^29.1.0",
"ts-node": "10.9.1",
"tslib": "^2.3.0",
Expand All @@ -47,6 +54,5 @@
}
}
}
},
"dependencies": {}
}
}
3 changes: 3 additions & 0 deletions packages/agent-wallet/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"files": [],
"include": [],
"references": [
{
"path": "../aw-tool-sign-eddsa"
},
{
"path": "../aw-tool-sign-ecdsa"
},
Expand Down
3 changes: 3 additions & 0 deletions packages/agent-wallet/tsconfig.lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
},
"include": ["src/**/*.ts"],
"references": [
{
"path": "../aw-tool-sign-eddsa/tsconfig.lib.json"
},
{
"path": "../aw-tool-sign-ecdsa/tsconfig.lib.json"
},
Expand Down
1 change: 1 addition & 0 deletions packages/aw-cli/src/lib/handlers/admin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export * from './batch-add-delegatee';
export * from './batch-remove-delegatee';
export * from './mint-pkp';
export * from './transfer-ownership';
export * from './wrapped-keys';
2 changes: 2 additions & 0 deletions packages/aw-cli/src/lib/handlers/admin/mint-pkp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import {
import { promptAdminInsufficientBalance } from '../../prompts/admin/insufficient-balance';
import { logger } from '../../utils/logger';
import { promptManagePkp } from '../../prompts/admin/manage-pkp';
import { handleMintWrappedKey } from './mint-wrapped-key';

export async function handleMintPkp(awAdmin: AwAdmin) {
try {
const pkpInfo = await awAdmin.mintPkp();
await handleMintWrappedKey(awAdmin, pkpInfo);
logger.success(`Minted Agent Wallet: ${pkpInfo.info.ethAddress}`);

const shouldManage = await promptManagePkp(pkpInfo);
Expand Down
30 changes: 30 additions & 0 deletions packages/aw-cli/src/lib/handlers/admin/mint-wrapped-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {
Admin as AwAdmin,
AwSignerError,
AwSignerErrorType,
PkpInfo,
} from '@lit-protocol/agent-wallet';

import { promptAdminInsufficientBalance } from '../../prompts/admin/insufficient-balance';
import { logger } from '../../utils/logger';

export async function handleMintWrappedKey(awAdmin: AwAdmin, pkp: PkpInfo) {
try {
const wrappedKey = await awAdmin.mintWrappedKey(pkp.info.tokenId);
logger.success(`Minted Wrapped Key: ${wrappedKey.publicKey}`);
return;

} catch (error) {
if (error instanceof AwSignerError) {
if (error.type === AwSignerErrorType.INSUFFICIENT_BALANCE_PKP_MINT) {
// Prompt the user to fund the account if the balance is insufficient.
const hasFunded = await promptAdminInsufficientBalance();
if (hasFunded) {
return handleMintWrappedKey(awAdmin, pkp);
}
}
}

throw error;
}
}
61 changes: 61 additions & 0 deletions packages/aw-cli/src/lib/handlers/admin/wrapped-keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { Admin as AwAdmin, AwSignerError } from '@lit-protocol/agent-wallet';
import { promptViewWrappedKeys } from '../../prompts/admin/view-wrapped-keys';
import { promptSelectPkp } from '../../prompts/admin/select-pkp';
import { logger } from '../../utils/logger';

export async function handleViewWrappedKeys(awAdmin: AwAdmin) {
const selectedKeyId = await promptViewWrappedKeys(awAdmin);
if (!selectedKeyId) {
return;
}

try {
const wrappedKey = await awAdmin.getWrappedKeyById(selectedKeyId);
logger.info('Wrapped Key Details:');
logger.info(`ID: ${wrappedKey.id}`);
logger.info(`Public Key: ${wrappedKey.publicKey}`);
} catch (error) {
if (error instanceof AwSignerError) {
logger.error(error.message);
} else {
logger.error('Failed to get wrapped key details');
}
}
}

export async function handleMintWrappedKey(awAdmin: AwAdmin) {
const pkps = await awAdmin.getPkps();
const pkp = await promptSelectPkp(pkps);
if (!pkp) {
return;
}

try {
const wrappedKey = await awAdmin.mintWrappedKey(pkp.info.tokenId);
logger.success(`Minted Wrapped Key: ${wrappedKey.publicKey}`);
} catch (error) {
if (error instanceof AwSignerError) {
logger.error(error.message);
} else {
logger.error('Failed to mint wrapped key');
}
}
}

export async function handleRemoveWrappedKey(awAdmin: AwAdmin) {
const selectedKeyId = await promptViewWrappedKeys(awAdmin);
if (!selectedKeyId) {
return;
}

try {
const wrappedKey = await awAdmin.removeWrappedKey(selectedKeyId);
logger.success(`Removed Wrapped Key: ${wrappedKey.publicKey}`);
} catch (error) {
if (error instanceof AwSignerError) {
logger.error(error.message);
} else {
logger.error('Failed to remove wrapped key');
}
}
}
31 changes: 31 additions & 0 deletions packages/aw-cli/src/lib/handlers/delegatee/execute-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
promptSelectPkp,
promptSelectTool,
promptToolParams,
promptSelectWrappedKey,
} from '../../prompts/delegatee';

// Import custom error types and utilities.
Expand Down Expand Up @@ -93,6 +94,36 @@ export const handleExecuteTool = async (awDelegatee: AwDelegatee) => {
logger.info('Enter Tool Parameters:');
const params = await promptToolParams(selectedTool, selectedPkp.ethAddress);

// If this is a Solana tool, prompt for wrapped key selection
if (selectedTool.chain === 'solana') {
// Get all wrapped keys and filter by the selected PKP's address
const wrappedKeys = await awDelegatee.getWrappedKeys();
const pkpWrappedKeys = wrappedKeys.filter(key => key.pkpAddress === selectedPkp.ethAddress);

if (pkpWrappedKeys.length === 0) {
logger.error('No wrapped keys found for this PKP. Please ask an admin to mint a wrapped key first.');
return;
}

const wrappedKey = await promptSelectWrappedKey(awDelegatee, pkpWrappedKeys);
params.wrappedKeyId = wrappedKey.id;
params.ciphertext = wrappedKey.ciphertext;
params.dataToEncryptHash = wrappedKey.dataToEncryptHash;
params.accessControlConditions = [
{
contractAddress: '',
standardContractType: '',
chain: 'ethereum',
method: '',
parameters: [':currentActionIpfsId'],
returnValueTest: {
comparator: '=',
value: 'QmYf6Bm29HXbTNLCi4ELTidJ1UYdj4Nk8cpm1xfeRLqDqc',
},
},
];
}

// Execute the tool.
logger.loading('Executing tool...');
const response = await awDelegatee.executeTool({
Expand Down
8 changes: 7 additions & 1 deletion packages/aw-cli/src/lib/prompts/admin/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import prompts from 'prompts';
// Import the logger utility for logging messages.
import { logger } from '../../utils/logger';

type ManageChoice = 'tools' | 'policies' | 'delegatees' | 'transferOwnership';
type ManageChoice = 'tools' | 'policies' | 'delegatees' | 'transferOwnership' | 'wrappedKeys';
type Choice = { title: string; value: string };

const categoryChoices: Record<
Expand All @@ -29,6 +29,11 @@ const categoryChoices: Record<
{ title: 'Batch Add Delegatees', value: 'batchAddDelegatees' },
{ title: 'Batch Remove Delegatees', value: 'batchRemoveDelegatees' },
],
wrappedKeys: [
{ title: 'View Wrapped Keys', value: 'viewWrappedKeys' },
{ title: 'Mint Wrapped Key', value: 'mintWrappedKey' },
{ title: 'Remove Wrapped Key', value: 'removeWrappedKey' },
],
};

export const promptAdminManageOrMintMenu = async (numberOfPkps: number) => {
Expand Down Expand Up @@ -70,6 +75,7 @@ export const promptAdminManagePkpMenu = async () => {
{ title: 'Tools', value: 'tools' },
{ title: 'Policies', value: 'policies' },
{ title: 'Delegatees', value: 'delegatees' },
{ title: 'Wrapped Keys', value: 'wrappedKeys' },
{ title: 'Transfer Ownership', value: 'transferOwnership' },
],
});
Expand Down
45 changes: 45 additions & 0 deletions packages/aw-cli/src/lib/prompts/admin/view-wrapped-keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import prompts from 'prompts';
import { Admin as AwAdmin } from '@lit-protocol/agent-wallet';
import { logger } from '../../utils/logger';

type StoredKeyData = {
id: string;
publicKey: string;
};

/**
* Prompts the user to view and manage wrapped keys
* @param awAdmin The Admin instance
* @returns The selected wrapped key ID if the user wants to manage it, undefined otherwise
*/
export const promptViewWrappedKeys = async (awAdmin: AwAdmin): Promise<string | undefined> => {
const wrappedKeys = await awAdmin.getWrappedKeys();

if (wrappedKeys.length === 0) {
logger.info('No wrapped keys found');
return undefined;
}

const choices = wrappedKeys.map((wk: StoredKeyData) => ({
title: `Wrapped Key: ${wk.publicKey}`,
description: `ID: ${wk.id}`,
value: wk.id,
}));

const { selectedKey } = await prompts({
type: 'select',
name: 'selectedKey',
message: 'Select a wrapped key to manage:',
choices: [
...choices,
{ title: 'Back', value: undefined }
],
});

if (selectedKey === undefined) {
logger.error('No selection made');
process.exit(1);
}

return selectedKey;
};
1 change: 1 addition & 0 deletions packages/aw-cli/src/lib/prompts/delegatee/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './select-tool';
export * from './tool-params';
export * from './tool-matching-intent';
export * from './open-ai-api-key';
export * from './select-wrapped-key';
41 changes: 41 additions & 0 deletions packages/aw-cli/src/lib/prompts/delegatee/select-wrapped-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import prompts from 'prompts';
import { Delegatee as AwDelegatee } from '@lit-protocol/agent-wallet';
import { logger } from '../../utils/logger';

/**
* Prompts the user to select a wrapped key
* @param awDelegatee The Delegatee instance
* @param wrappedKeys Optional list of wrapped keys to choose from. If not provided, all wrapped keys will be fetched.
* @returns The selected wrapped key or undefined if none selected
*/
export const promptSelectWrappedKey = async (
awDelegatee: AwDelegatee,
wrappedKeys?: any[]
) => {
const keys = wrappedKeys || await awDelegatee.getWrappedKeys();

if (keys.length === 0) {
logger.error('No wrapped keys found. Please ask the admin to mint a wrapped key first.');
process.exit(1);
}

const choices = keys.map((wk) => ({
title: `Wrapped Key: ${wk.publicKey}`,
description: `ID: ${wk.id}`,
value: wk,
}));

const { selectedKey } = await prompts({
type: 'select',
name: 'selectedKey',
message: 'Select a wrapped key to use:',
choices,
});

if (!selectedKey) {
logger.error('No wrapped key selected');
process.exit(1);
}

return selectedKey;
};
12 changes: 12 additions & 0 deletions packages/aw-cli/src/lib/roles/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ import {
handleBatchRemoveDelegatee,
handleMintPkp,
handleTransferOwnership,
handleViewWrappedKeys,
handleMintWrappedKey,
handleRemoveWrappedKey,
} from '../handlers/admin';

/**
Expand Down Expand Up @@ -174,6 +177,15 @@ export class Admin {
await handleTransferOwnership(admin.awAdmin, pkp);
await Admin.showManageOrMintMenu(admin);
break;
case 'viewWrappedKeys':
await handleViewWrappedKeys(admin.awAdmin);
break;
case 'mintWrappedKey':
await handleMintWrappedKey(admin.awAdmin);
break;
case 'removeWrappedKey':
await handleRemoveWrappedKey(admin.awAdmin);
break;
default:
logger.error('Invalid option selected');
process.exit(1);
Expand Down
3 changes: 3 additions & 0 deletions packages/aw-cli/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
{
"path": "../agent-wallet"
},
{
"path": "../aw-tool-sign-eddsa"
},
{
"path": "../aw-tool-sign-ecdsa"
},
Expand Down
3 changes: 3 additions & 0 deletions packages/aw-cli/tsconfig.lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
{
"path": "../agent-wallet/tsconfig.lib.json"
},
{
"path": "../aw-tool-sign-eddsa/tsconfig.lib.json"
},
{
"path": "../aw-tool-sign-ecdsa/tsconfig.lib.json"
},
Expand Down
4 changes: 4 additions & 0 deletions packages/aw-signer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
"@lit-protocol/aw-tool": "workspace:*",
"@lit-protocol/aw-tool-registry": "workspace:*",
"@lit-protocol/lit-node-client-nodejs": "7.0.2",
"@lit-protocol/wrapped-keys": "7.0.2",
"@lit-protocol/lit-auth-client": "7.0.2",
"@lit-protocol/types": "7.0.2",
"@lit-protocol/encryption": "7.0.2",
"@solana/web3.js": "^1.91.0",
"bs58": "^6.0.0",
"ethers": "5.7.2",
"node-localstorage": "^3.0.5",
Expand Down
Loading
Loading