clihelper.polymarket.psm1
|
#!/usr/bin/env pwsh using namespace System.IO using namespace System.Numerics using namespace System.Net.Http using namespace System.Management.Automation using namespace System.Security.Cryptography #Requires -Modules PsModuleBase, argparser, cliHelper.logger #region Classes enum CallType { Invalid = 0 Call = 1 DelegateCall = 2 } class PolymarketConstants { static [string] $WALLET_FACTORY_SALT = "0x95b55433048f12da29cefb1c3d26bd930c115b4cebf578715c569c1b281a0c1f" # Pre-computed implementation hash - avoids storing full bytecode static [string] $WALLET_IMPLEMENTATION_HASH = "0x933430a293d31ac8fbd9852d4c46b6d23bf20a49d1c1964f30bd674e598e38b1" } class Transaction { [ValidatePattern('^0x[0-9a-fA-F]{40}$')] [string] $To [CallType] $TypeCode [ValidatePattern('^0x[0-9a-fA-F]*$')] [string] $Data [ValidatePattern('^\d+$')] [string] $Value Transaction([string]$to, [CallType]$typeCode, [string]$data, [string]$value = "0") { $this.To = $to $this.TypeCode = $typeCode $this.Data = $data $this.Value = $value } [bool] Equals([object]$obj) { if ($obj -isnot [Transaction]) { return $false } return $this.To -eq $obj.To -and $this.TypeCode -eq $obj.TypeCode -and $this.Data -eq $obj.Data -and $this.Value -eq $obj.Value } [int] GetHashCode() { return $this.To.GetHashCode() -bxor $this.TypeCode.GetHashCode() -bxor $this.Data.GetHashCode() -bxor $this.Value.GetHashCode() } } class Address { static [bool] IsValid([string]$address) { return $address -match '^0x[0-9a-fA-F]{40}$' } static [string] Normalize([string]$address) { if (-not [Address]::IsValid($address)) { throw [ArgumentException] "Invalid address format: $address" } return $address.ToLower() } } class HexString { static [bool] IsValid([string]$hex) { return $hex -match '^0x[0-9a-fA-F]*$' } static [byte[]] ToBytes([string]$hex) { if (-not [HexString]::IsValid($hex)) { throw [ArgumentException] "Invalid hex format: $hex" } $hex = $hex.Substring(2) if (($hex.Length % 2) -ne 0) { $hex = "0$hex" } $bytes = New-Object byte[] ($hex.Length / 2) for ($i = 0; $i -lt $hex.Length; $i += 2) { $bytes[$i / 2] = [Convert]::ToByte($hex.Substring($i, 2), 16) } return $bytes } static [string] FromBytes([byte[]]$bytes) { return "0x" + [BitConverter]::ToString($bytes).Replace("-", "").ToLower() } static [string] Normalize([string]$hex) { if (-not [HexString]::IsValid($hex)) { throw [ArgumentException] "Invalid hex format: $hex" } return $hex.ToLower() } } class AbiEncoding { static [string] Strip0x([string]$value) { if ($null -eq $value) { throw [ArgumentNullException]::new("value") } return $value.StartsWith("0x") ? $value.Substring(2) : $value } static [string] UInt256Word([string]$value) { if ([string]::IsNullOrWhiteSpace($value)) { throw [ArgumentException] "uint256 value cannot be empty" } $word = if ($value.StartsWith("0x")) { [AbiEncoding]::Strip0x($value).ToLower() } else { [BigInteger]::Parse($value).ToString("x") } if ($word.Length -gt 64) { throw [ArgumentException] "uint256 value out of range: $value" } return $word.PadLeft(64, '0') } static [string] AddressWord([string]$address) { return [Address]::Normalize($address).Substring(2).PadLeft(64, '0') } static [string] Bytes32Word([string]$hex) { if (-not [HexString]::IsValid($hex)) { throw [ArgumentException] "Invalid hex format: $hex" } $raw = [AbiEncoding]::Strip0x($hex).ToLower() if ($raw.Length -gt 64) { throw [ArgumentException] "bytes32 value too long: $hex" } return $raw.PadLeft(64, '0') } static [string] DynamicUint256Array([string[]]$values) { $encoded = [AbiEncoding]::UInt256Word(($values.Count).ToString()) foreach ($value in $values) { $encoded += [AbiEncoding]::UInt256Word($value) } return $encoded } static [string] DynamicString([string]$value) { $bytes = [System.Text.Encoding]::UTF8.GetBytes($value) $hex = [BitConverter]::ToString($bytes).Replace("-", "").ToLower() $padding = (64 - ($hex.Length % 64)) % 64 return [AbiEncoding]::UInt256Word($bytes.Length.ToString()) + $hex + ("0" * $padding) } } #region Polymarket.Crypto class PolymarketCrypto { static [string] Keccak256([byte[]]$data) { $sha3 = [System.Security.Cryptography.SHA3_256]::Create() $hash = $sha3.ComputeHash($data) return "0x" + [BitConverter]::ToString($hash).Replace("-", "").ToLower() } static [string] Keccak256([string]$hex) { if (-not [HexString]::IsValid($hex)) { throw [ArgumentException] "Invalid hex format: $hex" } $bytes = [HexString]::ToBytes($hex) return [PolymarketCrypto]::Keccak256($bytes) } static [string] EncodePacked($types, $values) { $bytes = @() for ($i = 0; $i -lt $types.Count; $i++) { $type = $types[$i] $value = $values[$i] switch ($type) { "string" { $bytes += [System.Text.Encoding]::UTF8.GetBytes($value) } "address" { $bytes += [HexString]::ToBytes($value) } "bytes" { $bytes += [HexString]::ToBytes($value) } "uint256" { $bigInt = [BigInteger]::Parse($value) $byteArray = $bigInt.ToByteArray() [Array]::Reverse($byteArray) $padded = New-Object byte[] 32 [Array]::Copy($byteArray, 0, $padded, 32 - $byteArray.Length, $byteArray.Length) $bytes += $padded } } } return [HexString]::FromBytes($bytes) } static [string] GetCreate2Address([string]$from, [string]$salt, [string]$bytecodeHash) { $fromBytes = [HexString]::ToBytes($from) $saltBytes = [HexString]::ToBytes($salt) $bytecodeHashBytes = [HexString]::ToBytes($bytecodeHash) $prefix = [HexString]::ToBytes("0xff") $data = $prefix + $fromBytes + $saltBytes + $bytecodeHashBytes $hash = [PolymarketCrypto]::Keccak256($data) $hashBytes = [HexString]::ToBytes($hash) $addressBytes = $hashBytes[12..31] return "0x" + [BitConverter]::ToString($addressBytes).Replace("-", "").ToLower() } } #endregion Polymarket.Crypto class PolymarketUtils { static [string] GetIndexSet([int[]]$indexes) { $result = [BigInteger]::Zero foreach ($index in $indexes) { if ($index -lt 0 -or $index -gt 255) { throw [ArgumentException] "Index must be between 0 and 255" } $result = $result -bor ([BigInteger]::One -shl $index) } # Convert to hex and ensure exactly 64 characters # BigInteger.ToString("X") may add a leading zero if the high bit is set $hex = $result.ToString("X").ToLower() if ($hex.StartsWith("0") -and $hex.Length -gt 1) { $hex = $hex.Substring(1) } return "0x" + $hex.PadLeft(64, '0') } static [int] GetMarketIndex([string]$marketId) { if (-not [HexString]::IsValid($marketId)) { throw [ArgumentException] "Invalid market ID format" } $bytes = [HexString]::ToBytes($marketId) if ($bytes.Length -ne 32) { throw [ArgumentException] "Market ID must be 32 bytes" } return [Convert]::ToInt32($marketId.Substring($marketId.Length - 2), 16) } static [Transaction] Erc20ApprovalTransaction([string]$token, [string]$spender, [string]$amount) { $token = [Address]::Normalize($token) $spender = [Address]::Normalize($spender) $data = "0x095ea7b3" + $spender.Substring(2).PadLeft(64, '0') + [AbiEncoding]::UInt256Word($amount) return [Transaction]::new($token, [CallType]::Call, $data, "0") } static [Transaction] Erc1155ApprovalTransaction([string]$token, [string]$spender, [bool]$approved) { $token = [Address]::Normalize($token) $spender = [Address]::Normalize($spender) $approvedHex = if ($approved) { "1".PadLeft(64, '0') } else { "0".PadLeft(64, '0') } $data = "0xa22cb465" + $spender.Substring(2).PadLeft(64, '0') + $approvedHex return [Transaction]::new($token, [CallType]::Call, $data, "0") } static [Transaction] Erc20TransferTransaction([string]$token, [string]$to, [string]$value) { $token = [Address]::Normalize($token) $to = [Address]::Normalize($to) $data = "0xa9059cbb" + $to.Substring(2).PadLeft(64, '0') + [AbiEncoding]::UInt256Word($value) return [Transaction]::new($token, [CallType]::Call, $data, "0") } static [Transaction] EthTransferTransaction([string]$to, [string]$value) { $to = [Address]::Normalize($to) return [Transaction]::new($to, [CallType]::Call, "0x", $value) } } class ConditionalTokens { static [string] $ZeroHash = "0x0000000000000000000000000000000000000000000000000000000000000000" static [Transaction[]] SplitPosition( [string]$conditionalTokensAddress, [string]$collateralTokenAddress, [string]$conditionId, [int]$outcomeSlotCount, [string]$amount ) { $conditionalTokensAddress = [Address]::Normalize($conditionalTokensAddress) $collateralTokenAddress = [Address]::Normalize($collateralTokenAddress) $parentCollectionId = [ConditionalTokens]::ZeroHash $partition = @() for ($i = 0; $i -lt $outcomeSlotCount; $i++) { $partition += [BigInteger]::One -shl $i } $data = [ConditionalTokens]::EncodeSplit( $collateralTokenAddress, $parentCollectionId, $conditionId, $partition, $amount ) return @([Transaction]::new($conditionalTokensAddress, [CallType]::Call, $data, "0")) } static [Transaction[]] MergePositions( [string]$conditionalTokensAddress, [string]$collateralTokenAddress, [string]$conditionId, [int]$outcomeSlotCount, [string]$amount ) { $conditionalTokensAddress = [Address]::Normalize($conditionalTokensAddress) $collateralTokenAddress = [Address]::Normalize($collateralTokenAddress) $parentCollectionId = [ConditionalTokens]::ZeroHash $partition = @() for ($i = 0; $i -lt $outcomeSlotCount; $i++) { $partition += [BigInteger]::One -shl $i } $data = [ConditionalTokens]::EncodeMerge( $collateralTokenAddress, $parentCollectionId, $conditionId, $partition, $amount ) return @([Transaction]::new($conditionalTokensAddress, [CallType]::Call, $data, "0")) } static [Transaction[]] RedeemPositions( [string]$conditionalTokensAddress, [string]$collateralTokenAddress, [string]$conditionId, [int]$outcomeSlotCount ) { $conditionalTokensAddress = [Address]::Normalize($conditionalTokensAddress) $collateralTokenAddress = [Address]::Normalize($collateralTokenAddress) $parentCollectionId = [ConditionalTokens]::ZeroHash $partition = @() for ($i = 0; $i -lt $outcomeSlotCount; $i++) { $partition += [BigInteger]::One -shl $i } $data = [ConditionalTokens]::EncodeRedeem( $collateralTokenAddress, $parentCollectionId, $conditionId, $partition ) return @([Transaction]::new($conditionalTokensAddress, [CallType]::Call, $data, "0")) } hidden static [string] EncodeSplit( [string]$collateralTokenAddress, [string]$parentCollectionId, [string]$conditionId, [BigInteger[]]$partition, [string]$amount ) { $selector = "0x1859a15a" $collateral = $collateralTokenAddress.Substring(2).PadLeft(64, '0') $parent = $parentCollectionId.Substring(2).PadLeft(64, '0') $condition = $conditionId.Substring(2).PadLeft(64, '0') $offset = "00000000000000000000000000000000000000000000000000000000000000a0" $amountHex = [AbiEncoding]::UInt256Word($amount) $partitionLength = $partition.Count.ToString("X").PadLeft(64, '0') $partitionHex = "" foreach ($p in $partition) { $partitionHex += $p.ToString("X64").ToLower() } return $selector + $collateral + $parent + $condition + $offset + $amountHex + $partitionLength + $partitionHex } hidden static [string] EncodeMerge( [string]$collateralTokenAddress, [string]$parentCollectionId, [string]$conditionId, [BigInteger[]]$partition, [string]$amount ) { $selector = "0x7a29d439" $collateral = $collateralTokenAddress.Substring(2).PadLeft(64, '0') $parent = $parentCollectionId.Substring(2).PadLeft(64, '0') $condition = $conditionId.Substring(2).PadLeft(64, '0') $offset = "00000000000000000000000000000000000000000000000000000000000000a0" $amountHex = [AbiEncoding]::UInt256Word($amount) $partitionLength = $partition.Count.ToString("X").PadLeft(64, '0') $partitionHex = "" foreach ($p in $partition) { $partitionHex += $p.ToString("X64").ToLower() } return $selector + $collateral + $parent + $condition + $offset + $amountHex + $partitionLength + $partitionHex } hidden static [string] EncodeRedeem( [string]$collateralTokenAddress, [string]$parentCollectionId, [string]$conditionId, [BigInteger[]]$partition ) { $selector = "0x721bf40f" $collateral = $collateralTokenAddress.Substring(2).PadLeft(64, '0') $parent = $parentCollectionId.Substring(2).PadLeft(64, '0') $condition = $conditionId.Substring(2).PadLeft(64, '0') $offset = "0000000000000000000000000000000000000000000000000000000000000080" $partitionLength = $partition.Count.ToString("X").PadLeft(64, '0') $partitionHex = "" foreach ($p in $partition) { $partitionHex += $p.ToString("X64").ToLower() } return $selector + $collateral + $parent + $condition + $offset + $partitionLength + $partitionHex } } #region Polymarket.Debt class Debt { static [Transaction[]] PayDebt([string]$debtTracker, [string]$tokenAddress, [string]$amount) { $debtTracker = [Address]::Normalize($debtTracker) $tokenAddress = [Address]::Normalize($tokenAddress) $approvalTx = [PolymarketUtils]::Erc20ApprovalTransaction($tokenAddress, $debtTracker, $amount) $selector = "0x74179a25" $amountHex = $amount.PadLeft(64, '0') $data = $selector + $amountHex $payTx = [Transaction]::new($debtTracker, [CallType]::Call, $data, "0") return @($approvalTx, $payTx) } static [Transaction[]] TakeOnDebt([string]$debtTracker, [string]$amount, [string]$txHash) { $debtTracker = [Address]::Normalize($debtTracker) $selector = "0x80b27022" $amountHex = [AbiEncoding]::UInt256Word($amount) $txHashHex = [AbiEncoding]::Bytes32Word($txHash) $data = $selector + $amountHex + $txHashHex return @([Transaction]::new($debtTracker, [CallType]::Call, $data, "0")) } } #endregion Polymarket.Debt #region Polymarket.Markets class Markets { static [Transaction[]] BuyMarketOutcome( [string]$marketMakerAddress, [string]$collateralTokenAddress, [string]$investmentAmount, [int]$outcomeIndex, [string]$minOutcomeTokensToBuy ) { $marketMakerAddress = [Address]::Normalize($marketMakerAddress) $collateralTokenAddress = [Address]::Normalize($collateralTokenAddress) $approvalTx = [PolymarketUtils]::Erc20ApprovalTransaction($collateralTokenAddress, $marketMakerAddress, $investmentAmount) $selector = "0x6d4ce63c" $investmentHex = [AbiEncoding]::UInt256Word($investmentAmount) $outcomeHex = $outcomeIndex.ToString("X64").ToLower() $minTokensHex = [AbiEncoding]::UInt256Word($minOutcomeTokensToBuy) $data = $selector + $investmentHex + $outcomeHex + $minTokensHex $buyTx = [Transaction]::new($marketMakerAddress, [CallType]::Call, $data, "0") return @($approvalTx, $buyTx) } static [Transaction[]] SellMarketOutcome( [string]$marketMakerAddress, [string]$conditionalTokensAddress, [string]$returnAmount, [int]$outcomeIndex, [string]$maxOutcomeTokensToSell ) { $marketMakerAddress = [Address]::Normalize($marketMakerAddress) $conditionalTokensAddress = [Address]::Normalize($conditionalTokensAddress) $approveOn = [PolymarketUtils]::Erc1155ApprovalTransaction($conditionalTokensAddress, $marketMakerAddress, $true) $selector = "0xd96a094a" $returnHex = [AbiEncoding]::UInt256Word($returnAmount) $outcomeHex = $outcomeIndex.ToString("X64").ToLower() $maxTokensHex = [AbiEncoding]::UInt256Word($maxOutcomeTokensToSell) $data = $selector + $returnHex + $outcomeHex + $maxTokensHex $sellTx = [Transaction]::new($marketMakerAddress, [CallType]::Call, $data, "0") $approveOff = [PolymarketUtils]::Erc1155ApprovalTransaction($conditionalTokensAddress, $marketMakerAddress, $false) return @($approveOn, $sellTx, $approveOff) } static [Transaction[]] AddFundingToMarket( [string]$marketMakerAddress, [string]$collateralTokenAddress, [string]$investmentAmount, [BigInteger[]]$distributionHint = @() ) { $marketMakerAddress = [Address]::Normalize($marketMakerAddress) $collateralTokenAddress = [Address]::Normalize($collateralTokenAddress) $approvalTx = [PolymarketUtils]::Erc20ApprovalTransaction($collateralTokenAddress, $marketMakerAddress, $investmentAmount) $selector = "0x21a0848a" $investmentHex = [AbiEncoding]::UInt256Word($investmentAmount) $offset = "0000000000000000000000000000000000000000000000000000000000000060" $hintLength = $distributionHint.Count.ToString("X").PadLeft(64, '0') $hintHex = "" foreach ($hint in $distributionHint) { $hintHex += $hint.ToString("X64").ToLower() } $data = $selector + $investmentHex + $offset + $hintLength + $hintHex $addFundingTx = [Transaction]::new($marketMakerAddress, [CallType]::Call, $data, "0") return @($approvalTx, $addFundingTx) } static [Transaction[]] SafeAddFundingToMarket( [string]$slippageCheckerAddress, [string]$marketMakerAddress, [string]$collateralTokenAddress, [string]$investmentAmount, [string[]]$distributionHint = @(), [string[]]$positionIds, [string[]]$minRefunds, [string[]]$maxRefunds ) { $slippageCheckerAddress = [Address]::Normalize($slippageCheckerAddress) $marketMakerAddress = [Address]::Normalize($marketMakerAddress) $collateralTokenAddress = [Address]::Normalize($collateralTokenAddress) $approvalTx = [PolymarketUtils]::Erc20ApprovalTransaction($collateralTokenAddress, $marketMakerAddress, $investmentAmount) $selector = "0x5ff9af63" $headSizeBytes = 32 * 6 $tail1 = [AbiEncoding]::DynamicUint256Array($distributionHint) $tail2 = [AbiEncoding]::DynamicUint256Array($positionIds) $tail3 = [AbiEncoding]::DynamicUint256Array($minRefunds) $tail4 = [AbiEncoding]::DynamicUint256Array($maxRefunds) $offset1 = [AbiEncoding]::UInt256Word(($headSizeBytes).ToString()) $offset2 = [AbiEncoding]::UInt256Word(($headSizeBytes + ($tail1.Length / 2)).ToString()) $offset3 = [AbiEncoding]::UInt256Word(($headSizeBytes + ($tail1.Length / 2) + ($tail2.Length / 2)).ToString()) $offset4 = [AbiEncoding]::UInt256Word(($headSizeBytes + ($tail1.Length / 2) + ($tail2.Length / 2) + ($tail3.Length / 2)).ToString()) $data = $selector + [AbiEncoding]::AddressWord($marketMakerAddress) + [AbiEncoding]::UInt256Word($investmentAmount) + $offset1 + $offset2 + $offset3 + $offset4 + $tail1 + $tail2 + $tail3 + $tail4 $safeAddFundingTx = [Transaction]::new($slippageCheckerAddress, [CallType]::DelegateCall, $data, "0") return @($approvalTx, $safeAddFundingTx) } static [Transaction[]] RemoveFundingFromMarket( [string]$marketMakerAddress, [string]$shares ) { $marketMakerAddress = [Address]::Normalize($marketMakerAddress) $selector = "0xc5d36504" $sharesHex = [AbiEncoding]::UInt256Word($shares) $data = $selector + $sharesHex return @([Transaction]::new($marketMakerAddress, [CallType]::Call, $data, "0")) } } #endregion Polymarket.Markets #region Polymarket.Matic class Matic { static [Transaction[]] WithdrawFundsOnMatic( [string]$tokenAddress, [string]$withdrawAmount ) { $tokenAddress = [Address]::Normalize($tokenAddress) $selector = "0x2e1a7d4d" $amountHex = $withdrawAmount.PadLeft(64, '0') $data = $selector + $amountHex return @([Transaction]::new($tokenAddress, [CallType]::Call, $data, "0")) } } #endregion Polymarket.Matic #region Polymarket.NegRisk class NegRisk { static [Transaction] ConvertPositions( [string]$negRiskAdapterAddress, [string]$marketId, [string]$indexSet, [string]$amount ) { $negRiskAdapterAddress = [Address]::Normalize($negRiskAdapterAddress) $selector = "0x18509c6b" $marketIdHex = [AbiEncoding]::Bytes32Word($marketId) $indexSetHex = [AbiEncoding]::UInt256Word($indexSet) $amountHex = [AbiEncoding]::UInt256Word($amount) $data = $selector + $marketIdHex + $indexSetHex + $amountHex return [Transaction]::new($negRiskAdapterAddress, [CallType]::Call, $data, "0") } static [Transaction] RedeemPositions([string]$negRiskAdapterAddress, [string]$conditionId, [string[]]$amounts) { $negRiskAdapterAddress = [Address]::Normalize($negRiskAdapterAddress) $selector = "0xb5d00289" $conditionIdHex = [AbiEncoding]::Bytes32Word($conditionId) $offset = "0000000000000000000000000000000000000000000000000000000000000040" $length = [AbiEncoding]::UInt256Word("2") $amount0 = [AbiEncoding]::UInt256Word($amounts[0]) $amount1 = [AbiEncoding]::UInt256Word($amounts[1]) $data = $selector + $conditionIdHex + $offset + $length + $amount0 + $amount1 return [Transaction]::new($negRiskAdapterAddress, [CallType]::Call, $data, "0") } } class Liquidity { static [Transaction[]] AddLiquidityRequest( [string]$liquidityRequestLogAddress, [string]$reason, [string]$marketMakerAddress, [string]$tradeAmount ) { $liquidityRequestLogAddress = [Address]::Normalize($liquidityRequestLogAddress) $marketMakerAddress = [Address]::Normalize($marketMakerAddress) $selector = "0xde17a736" $offsetReason = [AbiEncoding]::UInt256Word("96") $head = $offsetReason + [AbiEncoding]::AddressWord($marketMakerAddress) + [AbiEncoding]::UInt256Word($tradeAmount) $tail = [AbiEncoding]::DynamicString($reason) $data = $selector + $head + $tail return @([Transaction]::new($liquidityRequestLogAddress, [CallType]::Call, $data, "0")) } } #endregion Polymarket.NegRisk # Main class class Polymarket { # Main Polymarket SDK class static [string] WriteBanner() { return [string][PsModuleBase]::ReadModuledata("clihelper.polymarket", "polymarketlogo") } static [string] GetProxyWalletAddress([string]$factory, [string]$user) { $factory = [Address]::Normalize($factory) $user = [Address]::Normalize($user) $userSalt = [PolymarketCrypto]::Keccak256([PolymarketCrypto]::EncodePacked(@("address"), @($user))) $deployCode = [Polymarket]::AssembleProxyWalletDeployCode($factory) $bytecodeHash = [PolymarketCrypto]::Keccak256($deployCode) return [PolymarketCrypto]::GetCreate2Address($factory, $userSalt, $bytecodeHash) } hidden static [string] AssembleProxyWalletDeployCode([string]$factory) { $factory = [Address]::Normalize($factory) $encodedBytes = "0x" $encodedBytes = $encodedBytes.Substring(2) $implAddress = [Polymarket]::GetProxyWalletImplementationAddress($factory) $implAddress = $implAddress.Substring(2).ToLower() $code = '0x3d3d606380380380913d393d73{0}5af4602a57600080fd5b602d8060366000396000f3363d3d373d3d3d363d73{1}5af43d82803e903d91602b57fd5bf352e831dd{2}' -f $($factory.Substring(2).ToLower()), $implAddress, $encodedBytes return $code } hidden static [string] GetProxyWalletImplementationAddress([string]$factory) { $factory = [Address]::Normalize($factory) return [PolymarketCrypto]::GetCreate2Address( $factory, [PolymarketConstants]::WALLET_FACTORY_SALT, [PolymarketConstants]::WALLET_IMPLEMENTATION_HASH ) } static [string] GetIndexSet([int[]]$indexes) { return [PolymarketUtils]::GetIndexSet($indexes) } static [int] GetMarketIndex([string]$marketId) { return [PolymarketUtils]::GetMarketIndex($marketId) } static [Transaction] Erc20ApprovalTransaction([string]$token, [string]$spender, [string]$amount) { return [PolymarketUtils]::Erc20ApprovalTransaction($token, $spender, $amount) } static [Transaction] Erc1155ApprovalTransaction([string]$token, [string]$spender, [bool]$approved) { return [PolymarketUtils]::Erc1155ApprovalTransaction($token, $spender, $approved) } static [Transaction] Erc20TransferTransaction([string]$token, [string]$to, [string]$value) { return [PolymarketUtils]::Erc20TransferTransaction($token, $to, $value) } static [Transaction] EthTransferTransaction([string]$to, [string]$value) { return [PolymarketUtils]::EthTransferTransaction($to, $value) } static [Transaction[]] SplitPosition( [string]$conditionalTokensAddress, [string]$collateralTokenAddress, [string]$conditionId, [int]$outcomeSlotCount, [string]$amount ) { return [ConditionalTokens]::SplitPosition( $conditionalTokensAddress, $collateralTokenAddress, $conditionId, $outcomeSlotCount, $amount ) } static [Transaction[]] MergePositions( [string]$conditionalTokensAddress, [string]$collateralTokenAddress, [string]$conditionId, [int]$outcomeSlotCount, [string]$amount ) { return [ConditionalTokens]::MergePositions( $conditionalTokensAddress, $collateralTokenAddress, $conditionId, $outcomeSlotCount, $amount ) } static [Transaction[]] RedeemPositions( [string]$conditionalTokensAddress, [string]$collateralTokenAddress, [string]$conditionId, [int]$outcomeSlotCount ) { return [ConditionalTokens]::RedeemPositions( $conditionalTokensAddress, $collateralTokenAddress, $conditionId, $outcomeSlotCount ) } static [Transaction[]] PayDebt( [string]$debtTracker, [string]$tokenAddress, [string]$amount ) { return [Debt]::PayDebt($debtTracker, $tokenAddress, $amount) } static [Transaction[]] TakeOnDebt( [string]$debtTracker, [string]$amount, [string]$txHash ) { return [Debt]::TakeOnDebt($debtTracker, $amount, $txHash) } static [Transaction[]] BuyMarketOutcome( [string]$marketMakerAddress, [string]$collateralTokenAddress, [string]$investmentAmount, [int]$outcomeIndex, [string]$minOutcomeTokensToBuy ) { return [Markets]::BuyMarketOutcome( $marketMakerAddress, $collateralTokenAddress, $investmentAmount, $outcomeIndex, $minOutcomeTokensToBuy ) } static [Transaction[]] SellMarketOutcome( [string]$marketMakerAddress, [string]$conditionalTokensAddress, [string]$returnAmount, [int]$outcomeIndex, [string]$maxOutcomeTokensToSell ) { return [Markets]::SellMarketOutcome( $marketMakerAddress, $conditionalTokensAddress, $returnAmount, $outcomeIndex, $maxOutcomeTokensToSell ) } static [Transaction[]] AddFundingToMarket( [string]$marketMakerAddress, [string]$collateralTokenAddress, [string]$investmentAmount, [BigInteger[]]$distributionHint = @() ) { return [Markets]::AddFundingToMarket( $marketMakerAddress, $collateralTokenAddress, $investmentAmount, $distributionHint ) } static [Transaction[]] SafeAddFundingToMarket( [string]$slippageCheckerAddress, [string]$marketMakerAddress, [string]$collateralTokenAddress, [string]$investmentAmount, [string[]]$distributionHint = @(), [string[]]$positionIds, [string[]]$minRefunds, [string[]]$maxRefunds ) { return [Markets]::SafeAddFundingToMarket( $slippageCheckerAddress, $marketMakerAddress, $collateralTokenAddress, $investmentAmount, $distributionHint, $positionIds, $minRefunds, $maxRefunds ) } static [Transaction[]] AddLiquidityRequest( [string]$liquidityRequestLogAddress, [string]$reason, [string]$marketMakerAddress, [string]$tradeAmount ) { return [Liquidity]::AddLiquidityRequest($liquidityRequestLogAddress, $reason, $marketMakerAddress, $tradeAmount) } static [Transaction[]] RemoveFundingFromMarket( [string]$marketMakerAddress, [string]$shares ) { return [Markets]::RemoveFundingFromMarket($marketMakerAddress, $shares) } static [Transaction[]] WithdrawFundsOnMatic( [string]$tokenAddress, [string]$withdrawAmount ) { return [Matic]::WithdrawFundsOnMatic($tokenAddress, $withdrawAmount) } static [Transaction] ConvertPositions( [string]$negRiskAdapterAddress, [string]$marketId, [string]$indexSet, [string]$amount ) { return [NegRisk]::ConvertPositions($negRiskAdapterAddress, $marketId, $indexSet, $amount) } static [Transaction] RedeemPositionsNegRisk( [string]$negRiskAdapterAddress, [string]$conditionId, [string[]]$amounts ) { return [NegRisk]::RedeemPositions($negRiskAdapterAddress, $conditionId, $amounts) } } #endregion Classes # Types that will be available to users when they import the module. $typestoExport = @( [Polymarket], [CallType], [Transaction], [Address], [HexString], [PolymarketCrypto], [PolymarketConstants], [PolymarketUtils], [ConditionalTokens], [Debt], [Markets], [Matic], [NegRisk], [Liquidity], [AbiEncoding] ) $TypeAcceleratorsClass = [PsObject].Assembly.GetType('System.Management.Automation.TypeAccelerators') foreach ($Type in $typestoExport) { if ($Type.FullName -in $TypeAcceleratorsClass::Get.Keys) { $Message = @( "Unable to register type accelerator '$($Type.FullName)'" 'Accelerator already exists.' ) -join ' - ' "TypeAcceleratorAlreadyExists $Message" | Write-Debug } } # Add type accelerators for every exportable type. foreach ($Type in $typestoExport) { $TypeAcceleratorsClass::Add($Type.FullName, $Type) } # Remove type accelerators when the module is removed. $MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { foreach ($Type in $typestoExport) { $TypeAcceleratorsClass::Remove($Type.FullName) } }.GetNewClosure(); $scripts = @(); $Public = Get-ChildItem "$PSScriptRoot/Public" -Filter "*.ps1" -Recurse -ErrorAction SilentlyContinue $scripts += Get-ChildItem "$PSScriptRoot/Private" -Filter "*.ps1" -Recurse -ErrorAction SilentlyContinue $scripts += $Public foreach ($file in $scripts) { try { if ([string]::IsNullOrWhiteSpace($file.fullname)) { continue } . "$($file.fullname)" } catch { Write-Warning "Failed to import function $($file.BaseName): $_" $host.UI.WriteErrorLine($_) } } $Param = @{ Function = $Public.BaseName Cmdlet = '*' Alias = '*' Verbose = $false } Export-ModuleMember @Param |