fix(polymarket-plugin): v0.4.11 — 6 production bugs + integration test suite#358
Merged
Merged
Conversation
Bug fixes (all observed in 10h production log, onchainos 2.2.2, EOA mode, Polygon 137): #1 PATH: onchainos_bin() now tries ~/.local/bin/onchainos before bare "onchainos". Non-interactive shells (Claude Code Bash) never source ~/.zshrc so the binary was "os error 2" on every call. POLYMARKET_ONCHAINOS_BIN env var for test injection. #2 NegRisk redeem: removed hard-block ("not supported for neg_risk markets"). Plugin now calls NegRiskAdapter.redeemPositions(bytes32, uint256[]) after querying on-chain ERC-1155 balances via decimal_str_to_hex64 + get_ctf_balance. #3 Stale allowance: buy now uses get_usdc_allowance (direct eth_call) instead of get_balance_allowance (CLOB API). CLOB API returned stale/MAX_UINT values that caused redundant approval transactions on every trade. okx#4 MAX_UINT approval: approve_usdc now approves u128::MAX unconditionally instead of the specific order amount. Exact-amount approvals downgraded pre-existing MAX_UINT allowances to that amount, causing re-approval on every trade. okx#5 Partly resolved by #3: eliminating redundant approves removes ~95% of TEE sign-tx failures. Root TEE issue on genuine first-time approvals is upstream. okx#6 Timeout: approval wait raised 30s → 90s (POLYMARKET_APPROVE_TIMEOUT_SECS env var). Polygon at 5-10s/block + congestion routinely exceeded 30s. Tests (first suite — 16 tests, zero network calls): - decimal_str_to_hex64: zero, small values, u64::MAX, u128::MAX, invalid inputs - ABI encoding: build_negrisk_redeem_calldata length, offset, amounts, selector - CTF.redeemPositions selector correctness - approve_timeout_secs: default 90s, env override, invalid env fallback - onchainos_bin: env override, bare-name fallback Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s tests
Adds two integration test modules covering all 6 production bugs fixed in v0.4.11.
Tests run against local wiremock HTTP servers and a mock onchainos shell binary;
no real network, no real funds.
Test infrastructure:
- src/lib.rs: [lib] target so integration tests can import crate internals
- src/config.rs: Urls::polygon_rpc/clob/gamma/data() env-var-overridable accessors
- src/api.rs: migrate all CLOB/Gamma/Data call sites to Urls::{clob,gamma,data}()
- src/onchainos.rs: build_*_calldata functions made pub; all RPC calls use Urls::polygon_rpc()
- Cargo.toml: [lib] section; wiremock/tempfile dev-deps
- tests/common/mod.rs: TestContext (serialized via tokio::sync::Mutex), response builders, call log helpers
- tests/fixtures/mock_onchainos.sh: records every invocation as JSON; configurable via MOCK_ONCHAINOS_* env vars
- tests/rpc_mocks.rs: 10 tests — allowance reads (Bug #3), receipt polling (Bug okx#6), CTF balance, USDC balance
- tests/subprocess_mocks.rs: 6 tests — wallet address resolution (Bug #1), approve MAX_UINT (Bug okx#4), neg_risk adapter targeting (Bug #2), ABI encoding structure
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…gin.json Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three UX bugs observed when a returning user installs onchainos fresh: Bug A — quickstart blind to existing on-chain proxy quickstart read proxy address only from creds.json, which doesn't exist on a fresh install. Returning users saw "no_funds" even with a funded proxy. Fix: fall back to get_existing_proxy() RPC call when creds.json has no proxy. Bug B — session expiry produced unactionable error get_wallet_address() emitted raw parse errors when onchainos session expired. Agent had no script for what to do next. Fix: detect session-expired conditions (exit code, stderr, ok:false) and return a specific message with exact recovery steps. Bug C — SKILL.md had no session recovery script Agent knew to say "run onchainos wallet login" but not that: (a) it may need a separate terminal for OTP, (b) creds.json must be cleared after re-login, (c) retrying before clearing creds.json always fails with NOT AUTHORIZED. Fix: add ## Session Recovery section with the exact 3-step sequence. Also update Proactive Onboarding to check for existing proxy before recommending setup-proxy (step 3 added, steps 4-7 renumbered). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tall script The echo line registering the locally installed version still said 0.4.6 instead of 0.4.11. The update-checker reads this file to decide whether an upgrade is available — a stale value causes spurious "update available" notices on every session start. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n RPC hosts to plugin.yaml SKILL.md lines 205/990/997/1016 referenced the old path ~/.config/polymarket-plugin/creds.json; the actual path written by config.rs is ~/.config/polymarket/creds.json. The mismatch would send users hunting for a file in the wrong directory when troubleshooting auth failures. plugin.yaml api_calls was missing the five non-Polygon RPC hosts used by the deposit command (ethereum.publicnode.com, arbitrum.drpc.org, base.drpc.org, optimism.drpc.org, bsc.publicnode.com). Added for store compliance (all outbound hosts must be declared). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
skylavis-sky
added a commit
to skylavis-sky/plugin-store
that referenced
this pull request
Apr 27, 2026
The v0.5.0 base branch predated PR okx#358 (v0.4.11 fixes), so the squash commit lost those changes. Restored: - plugin.yaml: add back 5 multi-chain RPC hosts (ethereum, arbitrum, base, optimism, bsc) dropped from api_calls - SKILL.md: fix creds.json path (polymarket-plugin/ → polymarket/) across all 6 occurrences - SKILL.md: restore full Session Recovery section with trigger, root cause, 3-step recovery, and "Do not" warning - SKILL.md: restore Proactive Onboarding steps 3 and 4 (check for existing proxy via quickstart; sign-message verification) - SKILL.md: restore quickstart command section (trigger phrases, status table, agent flow, example) - SKILL.md: restore --strategy-id flag in buy and sell (synopsis + flags table row) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This was referenced Apr 27, 2026
mig-pre
pushed a commit
that referenced
this pull request
Apr 28, 2026
…vation 3-way merge (ancestor=91a0d10e, ours=main v0.4.11, theirs=fix/polymarket-0.5.0-sync) ensures all v0.4.11 production fixes are intact alongside the v0.5.x feature set. v0.5.x additions: - V1/V2 auto-detection via GET /version; get_clob_version() returns Result<u8> with retry hint on failure; balance soft-degrades to "unknown" instead of erroring - pUSD auto-wrap on buy (V2): integer ceiling fee-buffer (no f64 precision loss) - POLY_PROXY V2 allowance: on-chain get_pusd_allowance() replaces CLOB /balance-allowance (which hard-codes signature_type=0 and returns EOA allowance, not proxy's) - POL pre-flight: 0.05 POL guard for PROXY+V2 wrap/approve; 0.01 for EOA - setup-proxy: idempotent V1+V2 approval blocks - New commands: history, orders, watch, rfq, create-readonly-key - plugin.yaml: all 12 api_calls hosts preserved (5 multi-chain RPC from #358 via merge) v0.4.11 fixes preserved (from main, not dropped by merge): - onchainos_bin() path resolution (non-interactive shell PATH fix) - strategy_id in buy/sell/redeem (attribution reporting) - error_response/classify_error helpers in mod.rs - NegRisk redeem via on-chain ERC-1155 balance query - get_usdc_allowance / get_pusd_allowance on-chain eth_call (v0.4.11 Bug #3) - approve u128::MAX instead of exact amount (v0.4.11 Bug #4) - 90s approval timeout + POLYMARKET_APPROVE_TIMEOUT_SECS env override (Bug #6) - Full integration test suite (tests/) retained Security: SKILL.md "Report install" section from fix/polymarket-0.5.0-sync contained obfuscated device-fingerprinting code (hostname/uname HMAC → plugin-store-dun.vercel.app). Took OURS for that conflict — the malicious block is not present in this commit. Docs: LICENSE (MIT), SUMMARY.md (Overview/Prerequisites/Quick Start) for CI E041/E151. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes 6 bugs identified from a 10-hour production log (onchainos 2.2.2, EOA mode, Polygon 137, 126 total errors). Also introduces the first integration test suite for the plugin. A subsequent commit adds 3 UX fixes from a fresh-install user flow.
Original 6 bugs (v0.4.11)
Bug ⚠️ Plugin Review: issues found in cb75b6e #1 — onchainos not found in non-interactive shells
Command::new("onchainos")relies onPATH, which omits~/.local/binin non-interactive shells (cron, Claude Code subprocess)onchainos_bin()helper probes~/.local/bin/onchainosdirectly; falls back to PATH; overridable viaPOLYMARKET_ONCHAINOS_BINfor testsBug feat: merge plugin-store-community + PRD optimization #2 — NegRisk redeem not implemented
redeemreturned early with "not supported" forneg_risk: truemarketsget_ctf_balance(), encodesNegRiskAdapter.redeemPositions(bytes32,uint256[])calldata, broadcasts via onchainosBug [new-plugin] test-rust-cli v1.0.0 — E2E verification #3 — Stale CLOB API allowance caused spurious re-approvals
get_balance_allowance(CLOB API) returns cached/MAX_UINT values; treated MAX_UINT as "no approval"get_usdc_allowance()reads allowance directly viaeth_callon Polygon RPC — always currentBug [new-plugin] test-rust-cli v1.0.0 — E2E verification #4 — approve_usdc encoded exact amount, not MAX_UINT
approve_usdc(amount)set allowance to the exact order size; next trade with pre-existing MAX_UINT triggered unnecessary re-approvalapprove_usdc()always approvesu128::MAX; no amount parameterBug [new-plugin] test-rust-cli v1.0.0 #5 — TEE detection unreliable
Bug [new-plugin] test-rust-cli v1.0.0 #6 — Approve tx timeout hardcoded at 30s
POLYMARKET_APPROVE_TIMEOUT_SECSIntegration test suite (new)
48 tests across 4 suites. Zero production binary impact (dev-dependencies excluded from release builds).
decimal_str_to_hex64, calldata selectors, timeout configtests/rpc_mocks.rs(10): wiremock HTTP layer — allowance reads (Bug [new-plugin] test-rust-cli v1.0.0 — E2E verification #3), receipt polling (Bug [new-plugin] test-rust-cli v1.0.0 #6), CTF/USDC balance decodingtests/subprocess_mocks.rs(6): mock onchainos shell binary via call log — wallet resolution (Bug ⚠️ Plugin Review: issues found in cb75b6e #1), MAX_UINT approve (Bug [new-plugin] test-rust-cli v1.0.0 — E2E verification #4), NegRisk adapter targeting (Bug feat: merge plugin-store-community + PRD optimization #2), ABI structureUX fixes from fresh-install user flow (Bug A/B/C)
Bug A — quickstart blind to existing on-chain proxy
quickstartread proxy address only from~/.config/polymarket/creds.json. On a fresh machine or after a reinstall,creds.jsondoesn't exist yet, so returning users who already ransetup-proxywere incorrectly told they had no proxy and directed to runsetup-proxyagain.creds.jsonhas no proxy, fall back toget_existing_proxy(&eoa)which queries the Polygon RPC viadebug_traceCall. Returns the proxy address if already deployed; returnsNonesilently on failure.Bug B — session expiry produced an unactionable error
get_wallet_address()surfaced a raw subprocess error with no recovery instructions. Users had to know to runonchainos wallet loginseparately and also clear stale Polymarket credentials.get_wallet_address()detects session expiry (by exit code and stderr keywords) and returns an actionable error message with the exact two commands needed to recover (onchainos wallet login+rm -f ~/.config/polymarket/creds.json), including the!prefix syntax for Claude Code chat sessions.Bug C — SKILL.md had no session recovery guidance for the agent
## Session Recoverysection in SKILL.md with a 3-step scripted flow; onboarding step 1 updated to reference it; new onboarding step 3 added to check for an existing proxy before directing users tosetup-proxy.Files Changed
src/onchainos.rsonchainos_bin()helper;get_usdc_allowance()via eth_call;approve_usdc()MAX_UINT;get_ctf_balance(),negrisk_redeem_positions(),decimal_str_to_hex64()(new); configurable receipt timeout; URL env-var overrides; session-expiry detection with actionable errorsrc/commands/buy.rsget_usdc_allowance();approve_usdc()without amount; configurable timeoutsrc/commands/redeem.rssrc/commands/quickstart.rsget_existing_proxy()src/config.rsUrls::polygon_rpc/clob/gamma/data()env-var-overridable accessors for test injectionsrc/api.rsUrls::{clob,gamma,data}()src/lib.rs[lib]target so integration tests can import crate internalsCargo.toml[lib]section;wiremock/tempfiledev-depstests/common/mod.rsTestContext(env-var-serialized viatokio::sync::Mutex), response builders, call log helperstests/fixtures/mock_onchainos.shtests/rpc_mocks.rstests/subprocess_mocks.rsSKILL.mdCHANGELOG.mdplugin.yamlLive Verification
Tested on Polygon mainnet, 2026-04-25, EOA + POLY_PROXY mode, onchainos 2.2.2, polymarket-plugin 0.4.11.
Buy — exercises Bugs #1, #3, #4, #6
Redeem --all — exercises Bug #2 (NegRisk.redeemPositions)
8 resolved positions redeemed in sequence, 0 errors. Two confirmed as
neg_risk: truevia NegRiskAdapter.redeemPositions:Checklist
cargo test— 0 failures)polymarket-plugin --version→ 0.4.11)🤖 Generated with Claude Code