@@ -4,6 +4,8 @@ import {OfferStatus, TradeOfferStatus, TradeOffersType} from '../bridge/handlers
4
4
import { clearAccessTokenFromStorage , getAccessToken } from './access_token' ;
5
5
import { AnnotateOffer } from '../bridge/handlers/annotate_offer' ;
6
6
import { PingCancelTrade } from '../bridge/handlers/ping_cancel_trade' ;
7
+ import { CancelTradeOffer } from '../bridge/handlers/cancel_trade_offer' ;
8
+ import { FetchSteamUser } from '../bridge/handlers/fetch_steam_user' ;
7
9
8
10
export async function pingSentTradeOffers ( pendingTrades : Trade [ ] ) {
9
11
const { offers, type} = await getSentTradeOffers ( ) ;
@@ -94,6 +96,57 @@ export async function pingCancelTrades(pendingTrades: Trade[]) {
94
96
}
95
97
}
96
98
}
99
+
100
+ // cancelUnconfirmedTradeOffers related to sales on CSFloat that haven't been confirmed for a while
101
+ // Helps prevent the user from sending a trade offer _way after_ the sale has already failed
102
+ export async function cancelUnconfirmedTradeOffers ( pendingTrades : Trade [ ] ) {
103
+ const offerIDsToCancel = [
104
+ ...new Set (
105
+ pendingTrades
106
+ . filter (
107
+ ( e ) =>
108
+ e . steam_offer . state === TradeOfferState . CreatedNeedsConfirmation &&
109
+ new Date ( e . steam_offer . sent_at ) . getTime ( ) < Date . now ( ) - 60 * 60 * 1000
110
+ )
111
+ . map ( ( e ) => e . steam_offer . id )
112
+ ) ,
113
+ ] ;
114
+
115
+ if ( offerIDsToCancel . length === 0 ) {
116
+ return ;
117
+ }
118
+
119
+ const resp = await getSentTradeOffers ( ) ;
120
+
121
+ const offersIDsStillNeedsConfirmation = offerIDsToCancel . filter ( ( id ) => {
122
+ const sentOffer = resp . offers . find ( ( offer ) => offer . offer_id === id ) ;
123
+ if ( ! sentOffer ) {
124
+ return false ;
125
+ }
126
+
127
+ return sentOffer . state === TradeOfferState . CreatedNeedsConfirmation ;
128
+ } ) ;
129
+
130
+ if ( offersIDsStillNeedsConfirmation . length === 0 ) {
131
+ return ;
132
+ }
133
+
134
+ const steamUser = await FetchSteamUser . handleRequest ( { } , { } ) ;
135
+ if ( ! steamUser . sessionID ) {
136
+ // Can't cancel offers without a session
137
+ return ;
138
+ }
139
+
140
+ for ( const offerID of offersIDsStillNeedsConfirmation ) {
141
+ try {
142
+ await CancelTradeOffer . handleRequest ( { trade_offer_id : offerID , session_id : steamUser . sessionID } , { } ) ;
143
+ } catch ( e : any ) {
144
+ console . error ( `failed to cancel needs confirmation trade, returning early: ${ e . toString ( ) } ` ) ;
145
+ return ;
146
+ }
147
+ }
148
+ }
149
+
97
150
async function getEnglishSentTradeOffersHTML ( ) : Promise < string > {
98
151
const resp = await fetch ( `https://steamcommunity.com/id/me/tradeoffers/sent` , {
99
152
credentials : 'include' ,
0 commit comments