@@ -8,11 +8,13 @@ import {
8
8
stringToUuid ,
9
9
composeContext ,
10
10
generateText ,
11
- ModelClass
11
+ ModelClass ,
12
+ State
12
13
} from "@elizaos/core" ;
13
14
import { postTweet } from "@elizaos/plugin-twitter" ;
14
15
import express from "express" ;
15
16
import { WebhookEvent } from "./types" ;
17
+ import { pnlProvider } from "@elizaos/plugin-coinbase" ;
16
18
17
19
export class CoinbaseClient implements Client {
18
20
private runtime : IAgentRuntime ;
@@ -93,19 +95,17 @@ export class CoinbaseClient implements Client {
93
95
} ) ;
94
96
}
95
97
96
- private async generateTweetContent ( event : WebhookEvent , _tradeAmount : number , formattedTimestamp : string ) : Promise < string > {
98
+ private async generateTweetContent ( event : WebhookEvent , amountInCurrency : number , pnlText : string , formattedTimestamp : string , state : State ) : Promise < string > {
97
99
try {
98
- const roomId = stringToUuid ( "coinbase-trading" ) ;
99
- const amount = Number ( this . runtime . getSetting ( 'COINBASE_TRADING_AMOUNT' ) ) ?? 1 ;
100
-
101
100
const tradeTweetTemplate = `
102
101
# Task
103
102
Create an engaging and unique tweet announcing a Coinbase trade. Be creative but professional.
104
103
105
104
Trade details:
106
105
- ${ event . event . toUpperCase ( ) } order for ${ event . ticker }
107
- - Trading amount: $${ amount . toFixed ( 2 ) }
106
+ - Trading amount: $${ amountInCurrency . toFixed ( 2 ) }
108
107
- Current price: $${ Number ( event . price ) . toFixed ( 2 ) }
108
+ - Overall Unrealized PNL: $${ pnlText }
109
109
- Time: ${ formattedTimestamp }
110
110
111
111
Requirements:
@@ -118,42 +118,23 @@ Requirements:
118
118
7. Include the key information: action, amount, ticker, and price
119
119
120
120
Example variations for buys:
121
- "📈 Just added $1,000 of BTC to the portfolio at $50,000.00"
122
- "🎯 Strategic BTC purchase: $1,000 at $50,000.00"
121
+ "📈 Just added $1,000 of BTC to the portfolio at $50,000.00. Overall Unrealized PNL: $ ${ pnlText } "
122
+ "🎯 Strategic BTC purchase: $1,000 at $50,000.00. Overall Unrealized PNL: $ ${ pnlText } "
123
123
124
124
Example variations for sells:
125
- "💫 Executed BTC position: Sold $1,000 at $52,000.00"
126
- "📊 Strategic exit: Released $1,000 of BTC at $52,000.00"
125
+ "💫 Executed BTC position: Sold $1,000 at $52,000.00. Overall Unrealized PNL: $ ${ pnlText } "
126
+ "📊 Strategic exit: Released $1,000 of BTC at $52,000.00. Overall Unrealized PNL: $ ${ pnlText } "
127
127
128
128
Generate only the tweet text, no commentary or markdown.` ;
129
-
130
129
const context = composeContext ( {
131
130
template : tradeTweetTemplate ,
132
- state : {
133
- event : event . event . toUpperCase ( ) ,
134
- ticker : event . ticker ,
135
- amount : `${ amount . toFixed ( 2 ) } ` ,
136
- price : `${ Number ( event . price ) . toFixed ( 2 ) } ` ,
137
- timestamp : formattedTimestamp ,
138
- bio : '' ,
139
- lore : '' ,
140
- messageDirections : '' ,
141
- postDirections : '' ,
142
- persona : '' ,
143
- personality : '' ,
144
- role : '' ,
145
- scenario : '' ,
146
- roomId,
147
- actors : '' ,
148
- recentMessages : '' ,
149
- recentMessagesData : [ ]
150
- }
131
+ state
151
132
} ) ;
152
133
153
134
const tweetContent = await generateText ( {
154
135
runtime : this . runtime ,
155
136
context,
156
- modelClass : ModelClass . SMALL ,
137
+ modelClass : ModelClass . LARGE ,
157
138
} ) ;
158
139
159
140
const trimmedContent = tweetContent . trim ( ) ;
@@ -179,7 +160,7 @@ Generate only the tweet text, no commentary or markdown.`;
179
160
agentId : this . runtime . agentId ,
180
161
roomId,
181
162
content : {
182
- text : `Place an advanced market order to ${ event . event . toLowerCase ( ) } $${ amount } worth of ${ event . ticker } ` ,
163
+ text : `Place an advanced trade market order to ${ event . event . toLowerCase ( ) } $${ amount } worth of ${ event . ticker } ` ,
183
164
action : "EXECUTE_ADVANCED_TRADE" ,
184
165
source : "coinbase" ,
185
166
metadata : {
@@ -194,15 +175,11 @@ Generate only the tweet text, no commentary or markdown.`;
194
175
} ;
195
176
196
177
await this . runtime . messageManager . createMemory ( memory ) ;
197
-
198
- const callback : HandlerCallback = async ( content : Content ) => {
199
- elizaLogger . info ( "Trade execution result:" , content ) ;
200
- return [ ] ;
201
- } ;
202
-
203
178
const state = await this . runtime . composeState ( memory ) ;
204
- await this . runtime . processActions ( memory , [ memory ] , state , callback ) ;
205
-
179
+ const callback : HandlerCallback = async ( content : Content ) => {
180
+ if ( ! content . text . includes ( "Trade executed successfully" ) ) {
181
+ return [ ] ;
182
+ }
206
183
// Generate tweet content
207
184
const formattedTimestamp = new Intl . DateTimeFormat ( 'en-US' , {
208
185
hour : '2-digit' ,
@@ -211,14 +188,22 @@ Generate only the tweet text, no commentary or markdown.`;
211
188
timeZoneName : 'short'
212
189
} ) . format ( new Date ( event . timestamp ) ) ;
213
190
191
+ const pnl = await pnlProvider . get ( this . runtime , memory ) ;
192
+
193
+ const pnlText = `Unrealized PNL: $${ pnl . toFixed ( 2 ) } ` ;
194
+
214
195
try {
215
- const tweetContent = await this . generateTweetContent ( event , amount , formattedTimestamp ) ;
196
+ const tweetContent = await this . generateTweetContent ( event , amount , pnlText , formattedTimestamp , state ) ;
216
197
elizaLogger . info ( "Generated tweet content:" , tweetContent ) ;
217
198
const response = await postTweet ( tweetContent ) ;
218
199
elizaLogger . info ( "Tweet response:" , response ) ;
219
200
} catch ( error ) {
220
201
elizaLogger . error ( "Failed to post tweet:" , error ) ;
221
202
}
203
+ return [ ] ;
204
+ } ;
205
+
206
+ await this . runtime . processActions ( memory , [ memory ] , state , callback ) ;
222
207
}
223
208
224
209
async stop ( ) : Promise < void > {
0 commit comments