Skip to content

Commit

Permalink
feat: add lit action run state machine capability as a state
Browse files Browse the repository at this point in the history
  • Loading branch information
FedericoAmura committed Dec 3, 2024
1 parent 720cce3 commit be62dbc
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 2 deletions.
86 changes: 84 additions & 2 deletions packages/automation/src/lib/state-machine.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import { ethers } from 'ethers';

import {
// createSiweMessageWithRecaps,
// generateAuthSig,
LitActionResource,
// LitPKPResource,
} from '@lit-protocol/auth-helpers';
import {
LIT_ABILITY,
LIT_EVM_CHAINS,
LIT_RPC,
LIT_NETWORK,
} from '@lit-protocol/constants';
import { LitContracts } from '@lit-protocol/contracts-sdk';
import { EthWalletProvider } from '@lit-protocol/lit-auth-client';
import { LitNodeClient } from '@lit-protocol/lit-node-client';

import {
Expand Down Expand Up @@ -34,6 +47,15 @@ import type {

export type MachineStatus = 'running' | 'stopped';

const ethPrivateKey = process.env['ETHEREUM_PRIVATE_KEY'];
if (!ethPrivateKey) {
throw new Error('ethPrivateKey not defined');
}
const yellowstoneSigner = new ethers.Wallet(
ethPrivateKey,
new ethers.providers.JsonRpcProvider(LIT_RPC.CHRONICLE_YELLOWSTONE)
);

/**
* A StateMachine class that manages states and transitions between them.
*/
Expand Down Expand Up @@ -66,7 +88,12 @@ export class StateMachine {
? litNodeClient
: new LitNodeClient(litNodeClient);
const litContractsInstance =
'connect' in litContracts ? litContracts : new LitContracts(litContracts);
'connect' in litContracts
? litContracts
: new LitContracts({
signer: yellowstoneSigner,
...litContracts,
});

if (
litNodeClientInstance.config.litNetwork !== litContractsInstance.network
Expand All @@ -83,7 +110,62 @@ export class StateMachine {
});

machineConfig.states.forEach((state) => {
stateMachine.addState(state);
const { litAction } = state;

const stateConfig: StateParams = {
key: state.key,
};

if (litAction) {
let pkpPublicKey: string = litAction.pkpPublicKey;

stateConfig.onEnter = async () => {
const yellowstoneSigner = new ethers.Wallet(
litAction.pkpOwnerKey,
new ethers.providers.JsonRpcProvider(LIT_RPC.CHRONICLE_YELLOWSTONE)
);

if (!pkpPublicKey) {
console.log(`No PKP for LitAction, minting one...`);
const mintingReceipt =
await litContractsInstance.pkpNftContractUtils.write.mint();
const pkp = mintingReceipt.pkp;
pkpPublicKey = pkp.publicKey;
console.log(`Minted PKP: ${pkp}`);
}

const pkpSessionSigs = await litNodeClientInstance.getPkpSessionSigs({
pkpPublicKey,
capabilityAuthSigs: [],
authMethods: [
await EthWalletProvider.authenticate({
signer: yellowstoneSigner,
litNodeClient: litNodeClientInstance,
expiration: new Date(Date.now() + 1000 * 60 * 10).toISOString(), // 10 minutes
}),
],
resourceAbilityRequests: [
{
resource: new LitActionResource('*'),
ability: LIT_ABILITY.LitActionExecution,
},
],
});

// Run a LitAction
const executeJsResponse = await litNodeClientInstance.executeJs({
sessionSigs: pkpSessionSigs,
ipfsId: litAction.ipfsId,
code: litAction.code,
jsParams: litAction.jsParams,
});

// TODO send user this result with a webhook maybe
console.log(`============ executeJsResponse:`, executeJsResponse);
};
}

stateMachine.addState(stateConfig);
});

machineConfig.transitions.forEach((transition) => {
Expand Down
9 changes: 9 additions & 0 deletions packages/automation/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,17 @@ import { BaseTransitionParams } from './transitions';

export type Address = `0x${string}`;

export interface LitActionStateDefinition {
pkpOwnerKey: string;
pkpPublicKey: string;
ipfsId?: string; // TODO separate into another without code
code: string;
jsParams: Record<string, any>;
}

export interface StateDefinition {
key: string;
litAction?: LitActionStateDefinition;
}

export interface OnEvmChainEvent {
Expand Down

0 comments on commit be62dbc

Please sign in to comment.