@@ -9,24 +9,26 @@ import {
9
9
elizaLogger ,
10
10
} from '@elizaos/core' ;
11
11
import { v4 as uuidv4 } from 'uuid' ;
12
- import { http , createPublicClient , createWalletClient } from 'viem' ;
13
- import { privateKeyToAccount } from 'viem/accounts' ;
14
- import { sonic } from 'viem/chains' ;
12
+ import type { Address , PublicClient , WalletClient } from 'viem' ;
15
13
import { z } from 'zod' ;
16
- import VaultFactoryArtifact from '../../../../../contracts/artifacts/src/contracts/create-vault/VaultFactory.sol/VaultFactory.json' ;
17
- import { env } from '../../../config/env' ;
14
+ import { ethereumAddressSchema } from '../../../validators/ethereum' ;
15
+ import { VAULT_FACTORY_ABI } from '../constants/vault-factory-abi' ;
16
+ import { initSonicProvider } from '../providers/sonic' ;
18
17
18
+ // TODO Move this to a type
19
19
interface MessageMetadata {
20
- walletAddress ?: string ;
20
+ walletAddress ?: Address ;
21
21
[ key : string ] : unknown ;
22
22
}
23
23
24
24
const createVaultContentSchema = z . object ( {
25
- userId : z . string ( ) ,
26
- walletAddress : z . string ( ) ,
27
- tokenAddress : z . string ( ) ,
28
- vaultName : z . string ( ) . optional ( ) ,
29
- vaultDescription : z . string ( ) . optional ( ) ,
25
+ userId : z . string ( ) . uuid ( ) ,
26
+ walletAddress : ethereumAddressSchema ,
27
+ agentAddress : ethereumAddressSchema ,
28
+ vaultFactoryAddress : ethereumAddressSchema ,
29
+ // FIXME Should be typed
30
+ publicClient : z . unknown ( ) ,
31
+ walletClient : z . unknown ( ) ,
30
32
} ) ;
31
33
32
34
type CreateVaultContent = z . infer < typeof createVaultContentSchema > ;
@@ -40,52 +42,39 @@ interface CreateVaultResponse {
40
42
async function createVault (
41
43
params : CreateVaultContent & { runtime : IAgentRuntime } ,
42
44
) : Promise < CreateVaultResponse > {
43
- const {
44
- userId,
45
- walletAddress,
46
- tokenAddress,
47
- vaultName,
48
- vaultDescription,
49
- runtime,
50
- } = params ;
51
-
52
45
try {
53
- // Initialize Viem clients
54
- const publicClient = createPublicClient ( {
55
- chain : sonic ,
56
- transport : http ( 'https://rpc.soniclabs.com' ) ,
57
- } ) ;
58
-
59
- // Create wallet client with private key
60
- const account = privateKeyToAccount ( env . EVM_PRIVATE_KEY ) ;
61
- const walletClient = createWalletClient ( {
62
- account,
63
- chain : sonic ,
64
- transport : http ( 'https://rpc.soniclabs.com' ) ,
65
- } ) ;
46
+ const parsedParams = createVaultContentSchema . parse ( params ) ;
47
+ const {
48
+ userId,
49
+ walletAddress,
50
+ vaultFactoryAddress,
51
+ agentAddress,
52
+ publicClient,
53
+ walletClient,
54
+ } = parsedParams ;
55
+ const typedPublicClient = publicClient as PublicClient ;
56
+ const typedWalletClient = walletClient as WalletClient ;
57
+ const { runtime } = params ;
66
58
67
59
// Create vault through factory
68
- const hash = await walletClient . writeContract ( {
69
- address : env . VAULT_FACTORY_ADDRESS ,
70
- abi : VaultFactoryArtifact . abi ,
60
+ // Approve from the vault address
61
+ const { request } = await typedPublicClient . simulateContract ( {
62
+ account : agentAddress ,
63
+ address : vaultFactoryAddress ,
64
+ abi : VAULT_FACTORY_ABI ,
71
65
functionName : 'createVault' ,
72
- args : [
73
- tokenAddress as `0x${string } `,
74
- vaultName || 'My Sonic Vault' ,
75
- vaultDescription || 'AI-managed vault for Sonic users' ,
76
- 'SONIC_VAULT' ,
77
- ] ,
66
+ args : [ agentAddress ] ,
78
67
} ) ;
79
68
80
- const receipt = await publicClient . waitForTransactionReceipt ( { hash } ) ;
69
+ const hash = await typedWalletClient . writeContract ( request ) ;
70
+ const receipt = await typedPublicClient . waitForTransactionReceipt ( { hash } ) ;
81
71
82
72
// Log the transaction receipt for debugging
83
- elizaLogger . info ( 'Transaction receipt:' , {
84
- logs : receipt . logs ,
85
- status : receipt . status ,
73
+ elizaLogger . info ( 'Successfully created vault' , {
86
74
contractAddress : receipt . contractAddress ,
87
75
} ) ;
88
76
77
+ // TODO Add viem parsing here
89
78
// Look for the VaultCreated event in the transaction receipt
90
79
const vaultCreatedEvent = receipt . logs . find (
91
80
( log ) =>
@@ -114,9 +103,6 @@ async function createVault(
114
103
vaultAddress,
115
104
userId,
116
105
walletAddress,
117
- tokenAddress,
118
- vaultName,
119
- vaultDescription,
120
106
createdAt : new Date ( ) . toISOString ( ) ,
121
107
transactionHash : hash ,
122
108
} ,
@@ -133,9 +119,6 @@ async function createVault(
133
119
userId,
134
120
walletAddress,
135
121
vaultAddress,
136
- tokenAddress,
137
- vaultName,
138
- vaultDescription,
139
122
agentId : runtime . agentId ,
140
123
transactionHash : hash ,
141
124
} ) ;
@@ -180,7 +163,24 @@ export const createVaultAction: Action = {
180
163
} ,
181
164
] ,
182
165
] ,
183
- validate : async ( _runtime : IAgentRuntime ) => {
166
+ validate : async ( runtime : IAgentRuntime , message : Memory ) => {
167
+ const vaultFactoryAddress = runtime . getSetting ( 'VAULT_FACTORY_ADDRESS' ) ;
168
+ if ( ! vaultFactoryAddress ) {
169
+ return false ;
170
+ }
171
+ const rpcUrl = runtime . getSetting ( 'SONIC_RPC_URL' ) ;
172
+ if ( ! rpcUrl ) {
173
+ return false ;
174
+ }
175
+ const privateKey = runtime . getSetting ( 'SONIC_PRIVATE_KEY' ) as `0x${string } `;
176
+ if ( ! privateKey ) {
177
+ return false ;
178
+ }
179
+ const metadata = message . content . metadata as MessageMetadata ;
180
+ const walletAddress = metadata ?. walletAddress ;
181
+ if ( ! walletAddress ) {
182
+ return false ;
183
+ }
184
184
return true ;
185
185
} ,
186
186
handler : async (
@@ -193,10 +193,12 @@ export const createVaultAction: Action = {
193
193
callback ?: HandlerCallback ,
194
194
) => {
195
195
elizaLogger . log ( 'Create Vault handler called' ) ;
196
+ const sonicProvider = await initSonicProvider ( runtime ) ;
196
197
197
198
// Extract wallet address from message metadata
198
199
const metadata = message . content . metadata as MessageMetadata ;
199
200
const walletAddress = metadata ?. walletAddress ;
201
+ // Should not happen, it is validated
200
202
if ( ! walletAddress ) {
201
203
elizaLogger . error ( 'No wallet address provided in message metadata' ) ;
202
204
if ( callback ) {
@@ -208,14 +210,13 @@ export const createVaultAction: Action = {
208
210
}
209
211
210
212
// Use the userId from the message
211
- const createVaultContent = {
213
+ const createVaultContent : CreateVaultContent = {
212
214
userId : message . userId ,
213
215
walletAddress,
214
- tokenAddress :
215
- process . env . DEFAULT_TOKEN_ADDRESS ||
216
- '0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38' , // Sonic (S) token address
217
- vaultName : 'My Sonic Vault' ,
218
- vaultDescription : 'AI-managed vault for Sonic users' ,
216
+ agentAddress : sonicProvider . account . address ,
217
+ vaultFactoryAddress : sonicProvider . vaultFactoryAddress ,
218
+ publicClient : sonicProvider . getPublicClient ( ) ,
219
+ walletClient : sonicProvider . getWalletClient ( ) ,
219
220
} ;
220
221
221
222
try {
0 commit comments