UNPKG

pmarket-cli

Version:
115 lines (98 loc) 4.68 kB
import { ethers } from "ethers"; import { PolymarketService } from "../services/polymarket.service.js"; import { ContractService } from "../services/contract.service.js"; import { Strategy } from "./strategy.js"; interface GroupedPosition { title: string; yesSize: number; noSize: number; } export class RedeemStrategy implements Strategy { constructor( private polymarketService: PolymarketService, private contractService: ContractService ) { } async execute(): Promise<void> { try { const address = this.polymarketService.getWalletAddress(); console.log(`Fetching redeemable positions for ${address}...`); console.log(''); const positions = await this.polymarketService.getPositions(); const redeemable = positions.filter(p => p.redeemable); if (redeemable.length === 0) { console.log('No redeemable positions found.'); return; } // Group by conditionId const grouped = new Map<string, GroupedPosition>(); for (const pos of redeemable) { const current = grouped.get(pos.conditionId) || { title: pos.title, yesSize: 0, noSize: 0 }; if (pos.outcome === 'Yes') { current.yesSize = pos.size; } else { current.noSize = pos.size; } grouped.set(pos.conditionId, current); } console.log(`Found ${grouped.size} resolved market(s) with redeemable positions:`); console.log(''); for (const [conditionId, data] of grouped) { const sizes = []; if (data.yesSize > 0) sizes.push(`Yes: ${data.yesSize.toFixed(2)}`); if (data.noSize > 0) sizes.push(`No: ${data.noSize.toFixed(2)}`); console.log(` ${data.title}`); console.log(` Condition: ${conditionId}`); console.log(` Shares: ${sizes.join(', ')}`); console.log(''); } console.log('Redeeming positions...'); console.log(''); let redeemed = 0; const delay = (seconds: number) => { console.log(` Waiting ${seconds}s to avoid RPC rate limits...`); return new Promise(resolve => setTimeout(resolve, seconds * 1000)); }; for (const [conditionId, data] of grouped) { console.log(`Redeeming: ${data.title}`); try { // Check if user holds USDC.e-backed tokens (standard) or wrapped collateral tokens (neg_risk) const isStandard = await this.contractService.isStandardRedemption(conditionId); await delay(5); if (isStandard) { console.log(' Detected: standard market'); const tx = await this.contractService.redeemPositions(conditionId); console.log(` tx submitted: ${tx.hash}`); await tx.wait(); console.log(' Confirmed (standard market)'); } else { console.log(' Detected: neg_risk market'); const amounts = [ ethers.parseUnits(data.yesSize.toFixed(6), 6), ethers.parseUnits(data.noSize.toFixed(6), 6) ]; const tx = await this.contractService.redeemNegRiskPositions(conditionId, amounts); console.log(` tx submitted: ${tx.hash}`); await tx.wait(); console.log(' Confirmed (neg_risk market)'); } redeemed++; } catch (error) { const msg = error instanceof Error ? error.message : String(error); console.error(` Failed to redeem: ${msg}`); } console.log(''); // Delay between redemptions to avoid RPC rate limits if (grouped.size > 1) { await delay(15); } } console.log(`Redeemed ${redeemed}/${grouped.size} market(s). USDC.e has been returned to your wallet.`); } catch (error) { if (error instanceof Error) { console.error('Failed to redeem positions:', error.message); } else { console.error('Failed to redeem positions:', error); } } } }