Skip to content

Use global CoinPay wallets across all publisher slots - #419

Merged
ralyodio merged 1 commit into
masterfrom
fix/slots-global-coinpay-wallets
Oct 30, 2026
Merged

ralyodio merged 1 commit into
masterfrom
fix/slots-global-coinpay-wallets

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Publishers had to enter a payout address separately for each site, and Connect wallet depended on an unreleased browser extension. The slots page now offers one CoinPay connection and one global destination for all current and future sites.

Add opt-in wallet:read to the existing authorization-code/PKCE S256/OIDC connection flow. Import active account-level and linked global web-wallet receive addresses using the provider-verified subject; exclude business-scoped addresses. Store public metadata only, with no bearer tokens, refresh tokens or signing keys. A central wallet selector controls every owned slot. Backend withdrawal resolution and slot API reads use the same effective destination, and a disconnected/empty global connection fails closed rather than falling back to old per-slot addresses. Existing customers retain legacy destinations until explicitly opting into global wallets.

Add authenticated wallet GET/sync APIs and crawlproof slots wallets [sync], reusing existing CrawlProof and CoinPay CLI sessions. The sync endpoint requires both identities, refuses conflicting links, ignores client-supplied addresses/subjects, and never persists or returns the CoinPay token. Ordinary CoinPay identity sign-in scopes remain unchanged. Return the browser to its original slots page/filter after connecting.

Wallet metadata is a snapshot with a visible sync time. Refresh once after changes in CoinPay; the refreshed destination applies to all sites. No automatic funds movement is introduced.

Validation: full suite 2,995 passed / 9 skipped before five additional API authorization tests; latest focused tests 39 passed, covering actual payout target selection, subject isolation, disconnect/empty fail-closed behavior, PKCE, ignored injected destinations and no token storage. Typecheck and production build passed. Desktop 1440px/mobile 390px browser fixtures passed with no manual address input or horizontal overflow.

Release: apply 20261031000000_coinpay_global_wallets.sql before deploying. The existing CrawlProof OAuth client registration now allows wallet:read (no other scope added); user consent is still required. The operator's existing CoinPay CLI session is expired and the CrawlProof account is not linked, so one fresh CoinPay connection is needed after deployment. No addresses must be entered for any of the 98 slots. No real withdrawals were performed.

@github-actions

Copy link
Copy Markdown

ThreatCrush Security Scan

48 finding(s)

HIGH/CRITICAL: 2 | MEDIUM: 30 | LOW: 16

Severity Rule Location
HIGH tls-verification-disabled lib/onion.ts:48
HIGH secret-generic-credential lib/sp/platforms/facebook.ts:32
MEDIUM js-unescaped-html-sink app/(app)/dashboard/admin/email-broadcast/EmailBroadcastForm.tsx:125
MEDIUM js-unescaped-html-sink app/(app)/dashboard/projects/[id]/autoblog/articles/[articleId]/page.tsx:214
MEDIUM js-unescaped-html-sink app/(marketing)/blog/[slug]/page.tsx:74
MEDIUM js-unescaped-html-sink app/(marketing)/blog/[slug]/page.tsx:102
MEDIUM js-unescaped-html-sink app/(marketing)/recent/page.tsx:177
MEDIUM js-unescaped-html-sink app/(marketing)/recent/page.tsx:181
MEDIUM js-unescaped-html-sink app/c/[project]/[slug]/page.tsx:76
MEDIUM js-unescaped-html-sink app/c/[project]/page.tsx:58
MEDIUM js-unescaped-html-sink app/careers.js/route.ts:228
MEDIUM js-unescaped-html-sink app/careers.js/route.ts:285
MEDIUM js-unescaped-html-sink app/layout.tsx:129
MEDIUM js-open-redirect app/login/form.tsx:40
MEDIUM js-unescaped-html-sink app/r/[token]/page.tsx:164
MEDIUM js-open-redirect app/signup/form.tsx:65
MEDIUM js-unescaped-html-sink app/surveys/[slug]/invite/page.tsx:68
MEDIUM js-unescaped-html-sink components/json-ld.tsx:8
MEDIUM js-unescaped-html-sink components/pit-footer.tsx:17
MEDIUM js-unescaped-html-sink components/report/markdown-view.tsx:16
MEDIUM js-unescaped-html-sink lib/careers/page-templates.ts:198
MEDIUM js-dynamic-code-execution lib/crawl-limits.ts:67
MEDIUM redos-nested-quantifier lib/emailMarkdown.ts:41
MEDIUM redos-nested-quantifier lib/emailMarkdown.ts:324
MEDIUM redos-nested-quantifier lib/lx/articleGen.ts:100
MEDIUM redos-nested-quantifier lib/tracker/agent-gate.ts:61
MEDIUM sh-predictable-temp-path ops/selfhost/server/setup-supabase.sh:218
MEDIUM sql-template-interpolation scripts/detect-slot-themes.ts:31
MEDIUM sql-template-interpolation scripts/purge-constructed-keywords.ts:163
MEDIUM sql-template-interpolation scripts/purge-offniche-keywords.ts:124
MEDIUM js-dynamic-code-execution scripts/test-crawl-limits.mjs:14
MEDIUM js-dynamic-code-execution scripts/test-crawl-limits.mjs:24
LOW secret-generic-credential app/(marketing)/docs/autoblog-webhook/page.tsx:156
LOW secret-generic-credential lib/sealed/migrate.ts:38
LOW secret-generic-credential lib/sp/platforms/linkedin.ts:25
LOW js-dynamic-code-execution tests/careers-page-templates.test.ts:21
LOW js-dynamic-code-execution tests/careers-widget-script.test.ts:19
LOW js-dynamic-code-execution tests/careers-widget-script.test.ts:69
LOW js-dynamic-code-execution tests/contract/ad-visitor-id.test.ts:51
LOW js-dynamic-code-execution tests/contract/ad-visitor-id.test.ts:52
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:20
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:24
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:25
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:26
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:31
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:35
LOW secret-generic-credential tests/contract/posthog-integration.test.ts:13
LOW secret-generic-credential tests/lead-campaign.test.ts:16

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit 478248f into master Oct 30, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant