Server's CanonicalQueryString uses url.QueryEscape on all keys and values,
but buildMessage was using raw string interpolation. Cursor values (base64)
contain +, =, / which diverge under encoding — causing 401 on all paginated
signed requests (e.g. portfolio holdings page 2+).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GET /v1/trade/follow_wallet requires X-Signature (critical auth) but was
called via normalRequest (API Key only), causing HTTP 401 AUTH_INVALID
with "missing signature".
- OpenApiClient: getFollowWallet now calls criticalRequest; criticalRequest
queryExtra type widened to accept string[] to support the --filter option
- signer: buildMessage handles string[] values as sorted repeated k=v pairs,
consistent with buildUrl / URLSearchParams serialization
- config: update PRIVATE_KEY_REQUIRED_MSG to include follow-wallet
- SKILL.md: prerequisites note GMGN_PRIVATE_KEY for follow-wallet; first-time
setup now saves private key to ~/.config/gmgn/.env and removes /tmp copy;
Notes section corrected to reflect split auth modes
- CLAUDE.md: Auth Modes table updated — follow-wallet moved to Critical row
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>