import { config } from 'dotenv';
import * as util from 'util';
import {
setupVincentDevelopmentEnvironment,
} from '@lit-protocol/vincent-e2e-test-utils';
import {
getVincentAbilityClient,
disconnectVincentAbilityClients,
} from '@lit-protocol/vincent-app-sdk/abilityClient';
import { ethers } from 'ethers';
// TODO: Import your bundled abilities here
import {
bundledVincentAbility,
} from '@lit-protocol/vincent-ability-evm-transaction-signer';
// Load environment variables
config();
// Run setup and execution if this file is executed directly
if (require.main === module) {
(async () => {
try {
console.log('🚀 Starting ability execution...\n');
// Setup Vincent development environment (handles funding internally)
console.log('🔧 Setting up Vincent development environment...');
// TODO: Add your bundled Vincent Abilities, Policies, and Policy values here
const PERMISSION_DATA = {
[bundledVincentAbility.ipfsCid]: {},
};
const { agentPkpInfo, wallets } = await setupVincentDevelopmentEnvironment({
permissionData: PERMISSION_DATA,
});
console.log('✅ Setup complete\n');
// Create ability client with your bundled ability
const abilityClient = getVincentAbilityClient({
bundledVincentAbility: bundledVincentAbility,
ethersSigner: wallets.appDelegatee,
debug: false
});
// Create and serialize a sample transaction (ERC20 transfer of USDC)
// Note: This transaction won't be submitted, so we use example values
console.log('📝 Creating transaction...');
const serializedTx = ethers.utils.serializeTransaction({
to: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
value: '0x00',
data: new ethers.utils.Interface([
'function transfer(address to, uint256 amount) returns (bool)',
]).encodeFunctionData('transfer', [
'0x4200000000000000000000000000000000000006', // Recipient (WETH contract as example)
'100000', // 0.1 USDC (6 decimals)
]),
chainId: 8453, // Base mainnet
nonce: 0, // Example nonce
gasPrice: '0x3B9ACA00', // Example: 1 gwei
gasLimit: '0x186A0', // 100,000 gas
});
// TODO: Run the precheck according to your imported abilities
console.log('\n🔍 Running precheck...');
const precheckResult = await abilityClient.precheck(
{
serializedTransaction: serializedTx,
},
{
delegatorPkpEthAddress: agentPkpInfo.ethAddress,
},
);
console.log('Precheck result:', util.inspect(precheckResult, { depth: 10 }));
if (!precheckResult.success) {
console.error('❌ Precheck failed:');
if (precheckResult.runtimeError) {
console.error(' Runtime error:', precheckResult.runtimeError);
}
if (precheckResult.result) {
console.error(' Result:', util.inspect(precheckResult.result, { depth: 10 }));
}
return;
}
const { deserializedUnsignedTransaction } = precheckResult.result;
console.log('✅ Precheck passed - deserialized transaction:', deserializedUnsignedTransaction);
// TODO: Execute according to your imported abilities
console.log('\n⚡ Executing ability (signing transaction)...');
const executeResult = await abilityClient.execute(
{
serializedTransaction: serializedTx,
},
{
delegatorPkpEthAddress: agentPkpInfo.ethAddress,
},
);
console.log('Execution result:', util.inspect(executeResult, { depth: 10 }));
if (!executeResult.success) {
console.error('❌ Execution failed:');
if (executeResult.runtimeError) {
console.error(' Runtime error:', executeResult.runtimeError);
}
if (executeResult.result) {
console.error(' Result:', util.inspect(executeResult.result, { depth: 10 }));
}
return;
}
const { signedTransaction, deserializedSignedTransaction } = executeResult.result;
console.log('\n🎉 All ability executions completed successfully!');
console.log('\nSigned transaction:', signedTransaction);
console.log('Deserialized signed transaction:', deserializedSignedTransaction);
} catch (error) {
console.error('❌ Execution failed with error:', error);
throw error;
} finally {
console.log('\n🧹 Cleaning up...');
await disconnectVincentAbilityClients();
}
})();
}