Skip to content

Allow users to customize retirement jurisdiction #119

@CShear

Description

@CShear

Context

Currently all credit retirements default to "US" jurisdiction (config.defaultJurisdiction in src/config.ts:95). This applies to MsgRetire, MsgBuyDirect, and MsgSend — all three on-chain message types include a jurisdiction field (ISO 3166-1 alpha-2 country code).

The MCP tool retire_credits accepts an optional jurisdiction parameter that overrides the default, but subscribers have no way to set their jurisdiction — all scheduled retirements use the hardcoded default.

Raised by Marie — retirement records on-chain should accurately reflect where the beneficiary is located.

Proposed Solution

1. Add country field to users table

ALTER TABLE users ADD COLUMN country TEXT; -- ISO 3166-1 alpha-2

2. Allow setting country at multiple touchpoints

  • Signup flow (optional field) — country dropdown during subscription checkout
  • Dashboard settings — editable from profile/settings page after signup
  • Stripe sync — pull customer.address.country from Stripe if available (Stripe collects billing address for tax purposes). Could sync on customer.updated webhook or on first login after subscription.

3. Jurisdiction resolution order

When retiring credits, resolve jurisdiction in this priority:

  1. Explicit jurisdiction param (MCP tool callers)
  2. user.country (if set in profile)
  3. Stripe customer country (if available)
  4. config.defaultJurisdiction ("US" fallback)

4. Affected code paths

File What changes
src/server/db.ts Add country column to users table
src/server/dashboard.ts Add country field to settings/profile UI
src/server/routes.ts Accept country during checkout flow
src/services/retirement.ts Use user's country in executeRetirement()
src/services/retire-subscriber.ts Look up subscriber's country for scheduled retirements
src/services/pool.ts Same — use subscriber country instead of global default
src/config.ts Keep defaultJurisdiction as final fallback

5. On-chain fields for reference

All three retirement message types include jurisdiction:

  • MsgBuyDirect: orders[].retirementJurisdiction
  • MsgRetire: jurisdiction
  • MsgSend: credits[].retirementJurisdiction

Format is ISO 3166-1 alpha-2 (e.g., "US", "CO", "DE", "KE"). Optionally supports subnational: "US-WA", "CO-ANT".

Design Notes (from Marie)

  • Keep it optional — don't add friction to signup
  • Let users customize it later from their dashboard
  • Stripe billing address is a good automatic source if we can get it
  • The goal is accuracy on-chain, not gatekeeping

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions