> For the complete documentation index, see [llms.txt](https://docs.creditcoop.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.creditcoop.xyz/developer-api-docs/wallet-attestation.md).

# Wallet Attestation

Wallet ownership verification via message signing

## Generate wallet attestation challenge

> Generate a challenge message for the given wallet address. The user must sign this message to prove ownership.

```json
{"openapi":"3.0.3","info":{"title":"Credit Coop API","version":"3.0.0"},"tags":[{"name":"Wallet Attestation","description":"Wallet ownership verification via message signing"}],"servers":[{"url":"https://api.creditcoop.xyz"}],"security":[{"BearerAuth":[]},{"OAuth2":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Clerk authentication token (session JWT or Clerk OAuth access token) used by Credit Coop"},"OAuth2":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://clerk.creditcoop.xyz/oauth/authorize","tokenUrl":"https://clerk.creditcoop.xyz/oauth/token","scopes":{"openid":"OpenID Connect","email":"User email","profile":"User profile"}}},"description":"Credit Coop OAuth"}},"schemas":{"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"message":{"type":"string"},"statusCode":{"type":"integer"}}}}},"paths":{"/v3/users/me/wallets/challenge":{"post":{"operationId":"generateWalletChallenge","summary":"Generate wallet attestation challenge","tags":["Wallet Attestation"],"description":"Generate a challenge message for the given wallet address. The user must sign this message to prove ownership.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["address","namespace"],"properties":{"address":{"type":"string","maxLength":42,"pattern":"^0x[0-9a-fA-F]{40}$","description":"EVM wallet address to attest."},"namespace":{"type":"string","enum":["eip155"],"description":"Address namespace. Currently only \"eip155\" (EVM) is supported."}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["message","nonce","expiresIn"],"properties":{"message":{"type":"string","description":"Challenge message to sign"},"nonce":{"type":"string","description":"Challenge nonce"},"expiresIn":{"type":"integer","description":"Nonce TTL in seconds"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Verify wallet attestation

> Submit the signed attestation message to prove wallet ownership and link the address to your account.

```json
{"openapi":"3.0.3","info":{"title":"Credit Coop API","version":"3.0.0"},"tags":[{"name":"Wallet Attestation","description":"Wallet ownership verification via message signing"}],"servers":[{"url":"https://api.creditcoop.xyz"}],"security":[{"BearerAuth":[]},{"OAuth2":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Clerk authentication token (session JWT or Clerk OAuth access token) used by Credit Coop"},"OAuth2":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://clerk.creditcoop.xyz/oauth/authorize","tokenUrl":"https://clerk.creditcoop.xyz/oauth/token","scopes":{"openid":"OpenID Connect","email":"User email","profile":"User profile"}}},"description":"Credit Coop OAuth"}},"schemas":{"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"message":{"type":"string"},"statusCode":{"type":"integer"}}}}},"paths":{"/v3/users/me/wallets/attest":{"post":{"operationId":"verifyWalletAttestation","summary":"Verify wallet attestation","tags":["Wallet Attestation"],"description":"Submit the signed attestation message to prove wallet ownership and link the address to your account.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["address","namespace","signature","message"],"properties":{"address":{"type":"string","maxLength":42,"pattern":"^0x[0-9a-fA-F]{40}$","description":"EVM wallet address being attested."},"namespace":{"type":"string","enum":["eip155"],"description":"Network namespace the user is attesting under. The signature is NOT chain-bound — for EVM ('eip155'), the same attestation covers all eip155 chains."},"signature":{"type":"string","description":"The signed message signature from the wallet."},"message":{"type":"string","description":"The attestation message that was signed (returned from the challenge endpoint)."}}}}}},"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["id","address","networkNamespace","verifiedAt","createdAt"],"properties":{"id":{"type":"string","format":"uuid"},"address":{"type":"string"},"networkNamespace":{"type":"string"},"verifiedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"subscriptions":{"type":"array","items":{"type":"object","required":["type","enabled"],"properties":{"type":{"type":"string","enum":["wallet_transactional","weekly_portfolio"]},"enabled":{"type":"boolean"}}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## List the user's wallets (optionally including org multisigs)

> List the user's attested EOAs. Pass \`?include=multisigs\` to also include org-owned multisigs the user has access to.

```json
{"openapi":"3.0.3","info":{"title":"Credit Coop API","version":"3.0.0"},"tags":[{"name":"Wallet Attestation","description":"Wallet ownership verification via message signing"}],"servers":[{"url":"https://api.creditcoop.xyz"}],"security":[{"BearerAuth":[]},{"OAuth2":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Clerk authentication token (session JWT or Clerk OAuth access token) used by Credit Coop"},"OAuth2":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://clerk.creditcoop.xyz/oauth/authorize","tokenUrl":"https://clerk.creditcoop.xyz/oauth/token","scopes":{"openid":"OpenID Connect","email":"User email","profile":"User profile"}}},"description":"Credit Coop OAuth"}},"schemas":{"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"message":{"type":"string"},"statusCode":{"type":"integer"}}}}},"paths":{"/v3/users/me/wallets":{"get":{"operationId":"listAttestedWallets","summary":"List the user's wallets (optionally including org multisigs)","tags":["Wallet Attestation"],"description":"List the user's attested EOAs. Pass `?include=multisigs` to also include org-owned multisigs the user has access to.","parameters":[{"schema":{"type":"string","enum":["multisigs"]},"in":"query","name":"include","required":false,"description":"Optional extras to include in the response. Currently only `multisigs` is supported."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["wallets"],"properties":{"wallets":{"type":"array","items":{"type":"object","required":["type","address","subscriptions"],"properties":{"type":{"type":"string","enum":["eoa","multisig","org_eoa"]},"id":{"type":"string"},"address":{"type":"string"},"networkNamespace":{"type":"string"},"verifiedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"networkId":{"type":"string"},"organizationId":{"type":"string","format":"uuid"},"organizationName":{"type":"string"},"subscriptions":{"type":"array","items":{"type":"object","required":["type","enabled"],"properties":{"type":{"type":"string","enum":["wallet_transactional","weekly_portfolio"]},"enabled":{"type":"boolean"}}}}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Update email subscription preferences for the authenticated user

> Subscribe or unsubscribe in bulk. Each change is identified by (address, networkId, type); \`enabled: true\` inserts a row, \`enabled: false\` deletes one. All cells are user-editable; defaults at wallet-create / org-join time are managed server-side.

```json
{"openapi":"3.0.3","info":{"title":"Credit Coop API","version":"3.0.0"},"tags":[{"name":"Wallet Attestation","description":"Wallet ownership verification via message signing"}],"servers":[{"url":"https://api.creditcoop.xyz"}],"security":[{"BearerAuth":[]},{"OAuth2":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Clerk authentication token (session JWT or Clerk OAuth access token) used by Credit Coop"},"OAuth2":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://clerk.creditcoop.xyz/oauth/authorize","tokenUrl":"https://clerk.creditcoop.xyz/oauth/token","scopes":{"openid":"OpenID Connect","email":"User email","profile":"User profile"}}},"description":"Credit Coop OAuth"}},"schemas":{"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"message":{"type":"string"},"statusCode":{"type":"integer"}}}}},"paths":{"/v3/users/me/email-subscriptions":{"put":{"operationId":"updateEmailSubscriptions","summary":"Update email subscription preferences for the authenticated user","tags":["Wallet Attestation"],"description":"Subscribe or unsubscribe in bulk. Each change is identified by (address, networkId, type); `enabled: true` inserts a row, `enabled: false` deletes one. All cells are user-editable; defaults at wallet-create / org-join time are managed server-side.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["changes"],"properties":{"changes":{"type":"array","items":{"type":"object","required":["address","networkId","type","enabled"],"properties":{"address":{"type":"string","maxLength":42,"pattern":"^0x[0-9a-fA-F]{40}$","description":"EVM address. The server normalizes to EIP-55 checksum form before lookup, so lowercase or mixed case are accepted."},"networkId":{"type":"string","maxLength":50},"type":{"type":"string","enum":["wallet_transactional","weekly_portfolio"]},"enabled":{"type":"boolean"}}}}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["wallets"],"properties":{"wallets":{"type":"array","items":{"type":"object","required":["type","address","subscriptions"],"properties":{"type":{"type":"string","enum":["eoa","multisig","org_eoa"]},"id":{"type":"string"},"address":{"type":"string"},"networkNamespace":{"type":"string"},"verifiedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"networkId":{"type":"string"},"organizationId":{"type":"string","format":"uuid"},"organizationName":{"type":"string"},"subscriptions":{"type":"array","items":{"type":"object","required":["type","enabled"],"properties":{"type":{"type":"string","enum":["wallet_transactional","weekly_portfolio"]},"enabled":{"type":"boolean"}}}}}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.creditcoop.xyz/developer-api-docs/wallet-attestation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
