{"openapi":"3.0.0","paths":{"/":{"get":{"operationId":"AppController_getHello","parameters":[],"responses":{"200":{"description":""}},"tags":["App"]}},"/health":{"get":{"operationId":"HealthController_getHealth","parameters":[],"responses":{"200":{"description":"Service is healthy"}},"summary":"Health check endpoint","tags":["Health"]}},"/metadata/network/{chainId}/token/{tokenId}":{"get":{"operationId":"MetadataController_getMetadata","parameters":[{"name":"tokenId","required":true,"in":"path","description":"The token ID to query","schema":{}},{"name":"chainId","required":true,"in":"path","description":"The chain ID to query","schema":{}}],"responses":{"200":{"description":""}},"summary":"Get metadata of name by chain ID and token ID","tags":["Metadata"]}},"/metadata/network/{chainId}/token/{tokenId}/image.png":{"get":{"operationId":"MetadataController_getDefaultAvatar","parameters":[{"name":"tokenId","required":true,"in":"path","description":"The token ID to query","schema":{}},{"name":"chainId","required":true,"in":"path","description":"The chain ID to query","schema":{}}],"responses":{"200":{"description":""}},"summary":"Get avatar image of name by chain ID and token ID","tags":["Metadata"]}},"/auth/nonce":{"post":{"operationId":"AuthController_nonce","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string","example":"0x54b06711C8022faf11EC347F2bDc68A91eA03a3a"},"scope":{"type":"string","enum":["avatar","header","avatar+header"],"example":"avatar+header","default":"avatar+header","description":"Defaults to avatar+header"}},"required":["address"]}}}},"responses":{"200":{"description":"Nonce generated","schema":{"example":{"nonce":"5e3239f5a23becc104aa740d93083559a29707119f5f18643a502a2c122b2d8157402df9385b30f1b4cd8f583017ac27"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NonceResponseDto"}}}}},"summary":"Generate SIWE nonce","tags":["auth"]}},"/profile/{network}/{subname}/avatar":{"post":{"description":"Upload or update an avatar image for an ENS subname with SIWE authentication.","operationId":"AvatarController_upload","parameters":[{"name":"network","required":true,"in":"path","description":"Ethereum network: mainnet (chain ID 1) or sepolia (chain ID 11155111)","schema":{"enum":["mainnet","sepolia"],"type":"string"}},{"name":"subname","required":true,"in":"path","description":"ENS subname (e.g., avatar.offchainsub.eth, alice.eth)","schema":{"example":"avatar.offchainsub.eth","type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"avatar":{"type":"string","format":"binary","description":"Image file (jpg, jpeg, png, gif, webp, svg)"},"siweMessage":{"type":"string","description":"SIWE message string","example":"namespace.ninja wants you to sign in with your Ethereum account:\n0x54b06711C8022faf11EC347F2bDc68A91eA03a3a\n\nSign in to Avatar Service (local test)\n\nURI: http://namespace.ninja \nVersion: 1\nChain ID: 1\nNonce: 99ba8946989dcd142a5802257a5a68580dadaa9c86d66416508ef8627f6cc291bb81400991750db4dd11aefc77aaa0ef\nIssued At: 2025-09-16T20:00:33.597Z"},"siweSignature":{"type":"string","description":"Signature for SIWE message","example":"0xb6eff78a2f96dfdc01a2cf0555256abca11229e240f44a379cb45eca667566bf4a4d8f2e3eb5dd130ff3b01409e82fe54d00a20e296338ee05c3b040a1f6f8111b"},"address":{"type":"string","description":"Wallet address (checks against SIWE)","example":"0x54b06711C8022faf11EC347F2bDc68A91eA03a3a"}},"required":["avatar","siweMessage","siweSignature","address"]}}}},"responses":{"200":{"description":"Avatar uploaded or updated successfully. Returns immediate confirmation if ENS record exists, or pending status if upload is queued for verification.","schema":{"oneOf":[{"description":"Avatar uploaded or updated successfully","example":{"subname":"avatar.offchainsub.eth","network":"mainnet","avatarUrl":"https://avtr.cc/avatar.offchainsub.eth","uploadedAt":"2025-10-24T10:30:00.000Z","fileSize":97500,"isUpdate":true}},{"description":"Pending upload (ENS record not set yet)","example":{"subname":"avatar.offchainsub.eth","network":"mainnet","avatarUrl":"https://avtr.cc/avatar.offchainsub.eth","uploadedAt":"2025-10-24T10:30:00.000Z","fileSize":97500,"isUpdate":false,"pending":true,"message":"Upload queued for verification. Set your ENS record within 5 minutes to confirm."}}]},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvatarUploadResponseDto"}}}}},"summary":"Upload or update avatar for a subname","tags":["profile"]},"delete":{"description":"Delete the avatar image for an ENS subname. Requires SIWE authentication and ownership verification.\n\n**Rate Limit:** 10 requests/minute per IP","operationId":"AvatarController_delete","parameters":[{"name":"network","required":true,"in":"path","description":"Ethereum network: mainnet (chain ID 1) or sepolia (chain ID 11155111)","schema":{"enum":["mainnet","sepolia"],"type":"string"}},{"name":"subname","required":true,"in":"path","description":"ENS subname (e.g., alice.eth, bob.namespace.eth)","schema":{"example":"alice.eth","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvatarDeleteDto"}}}},"responses":{"200":{"description":"Avatar deleted successfully","schema":{"example":{"subname":"alice.eth","network":"mainnet","message":"Avatar deleted successfully","deletedAt":"2025-10-24T10:35:00.000Z"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponseDto"}}}}},"summary":"Delete avatar for a subname","tags":["profile"]}},"/profile/{network}/{subname}/header":{"post":{"description":"Upload or update a header image for an ENS subname with SIWE authentication.","operationId":"AvatarController_uploadHeader","parameters":[{"name":"network","required":true,"in":"path","description":"Ethereum network: mainnet (chain ID 1) or sepolia (chain ID 11155111)","schema":{"enum":["mainnet","sepolia"],"type":"string"}},{"name":"subname","required":true,"in":"path","description":"ENS subname (e.g., alice.eth, bob.namespace.eth)","schema":{"example":"alice.eth","type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"header":{"type":"string","format":"binary","description":"Header image file (jpg, jpeg, png, gif, webp, svg)"},"siweMessage":{"type":"string","description":"SIWE message string","example":"namespace.ninja wants you to sign in with your Ethereum account:\n0x54b06711C8022faf11EC347F2bDc68A91eA03a3a\n\nSign in to Avatar Service (local test)\n\nURI: http://namespace.ninja \nVersion: 1\nChain ID: 1\nNonce: 99ba8946989dcd142a5802257a5a68580dadaa9c86d66416508ef8627f6cc291bb81400991750db4dd11aefc77aaa0ef\nIssued At: 2025-09-16T20:00:33.597Z"},"siweSignature":{"type":"string","description":"Signature for SIWE message","example":"0xb6eff78a2f96dfdc01a2cf0555256abca11229e240f44a379cb45eca667566bf4a4d8f2e3eb5dd130ff3b01409e82fe54d00a20e296338ee05c3b040a1f6f8111b"},"address":{"type":"string","description":"Wallet address (checks against SIWE)","example":"0x54b06711C8022faf11EC347F2bDc68A91eA03a3a"}},"required":["header","siweMessage","siweSignature","address"]}}}},"responses":{"200":{"description":"Header uploaded or updated successfully. Returns immediate confirmation if ENS record exists, or pending status if upload is queued for verification.","schema":{"oneOf":[{"description":"Immediate upload (ENS record exists)","example":{"subname":"alice.eth","network":"mainnet","headerUrl":"https://avtr.cc/alice.eth/h","uploadedAt":"2025-10-24T10:30:00.000Z","fileSize":131131,"isUpdate":false}},{"description":"Pending upload (ENS record not set yet)","example":{"subname":"alice.eth","network":"mainnet","headerUrl":"https://avtr.cc/alice.eth/h","uploadedAt":"2025-10-24T10:30:00.000Z","fileSize":131131,"isUpdate":false,"pending":true,"message":"Upload queued for verification. Set your ENS record within 5 minutes to confirm."}}]},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeaderUploadResponseDto"}}}}},"summary":"Upload or update header image for a subname","tags":["profile"]},"delete":{"description":"Delete the header image for an ENS subname. Requires SIWE authentication and ownership verification.\n\n**Rate Limit:** 10 requests/minute per IP","operationId":"AvatarController_deleteHeader","parameters":[{"name":"network","required":true,"in":"path","description":"Ethereum network: mainnet (chain ID 1) or sepolia (chain ID 11155111)","schema":{"enum":["mainnet","sepolia"],"type":"string"}},{"name":"subname","required":true,"in":"path","description":"ENS subname (e.g., alice.eth, bob.namespace.eth)","schema":{"example":"alice.eth","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeaderDeleteDto"}}}},"responses":{"200":{"description":"Header deleted successfully","schema":{"example":{"subname":"alice.eth","network":"mainnet","message":"Header deleted successfully","deletedAt":"2025-10-24T10:35:00.000Z"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponseDto"}}}}},"summary":"Delete header image for a subname","tags":["profile"]}}},"info":{"title":"Metadata Service API","description":"API for generating ENS subname metadata and images","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"schemas":{"NonceResponseDto":{"type":"object","properties":{"nonce":{"type":"string","example":"5e3239f5a23becc104aa740d93083559a29707119f5f18643a502a2c122b2d8157402df9385b30f1b4cd8f583017ac27"},"expiresAt":{"type":"number","example":1758039223689}},"required":["nonce","expiresAt"]},"AvatarUploadResponseDto":{"type":"object","properties":{"subname":{"type":"string","example":"avatar.offchainsub.eth","description":"ENS subname"},"network":{"type":"string","example":"mainnet","enum":["mainnet","sepolia"],"description":"Network identifier"},"avatarUrl":{"type":"string","example":"https://avtr.cc/avatar.offchainsub.eth","description":"Public URL to access the avatar image"},"uploadedAt":{"type":"string","example":"2025-10-24T10:30:00.000Z","description":"ISO 8601 timestamp of upload"},"fileSize":{"type":"number","example":97500,"description":"File size in bytes"},"isUpdate":{"type":"boolean","example":true,"description":"Whether this was an update (true) or new upload (false)"},"pending":{"type":"boolean","example":true,"description":"If true, upload is pending ENS record verification (pre-registration upload)"},"message":{"type":"string","example":"Upload queued for verification. Set your ENS record within 5 minutes to confirm.","description":"Additional message for pending uploads"}},"required":["subname","network","avatarUrl","uploadedAt","fileSize","isUpdate"]},"AvatarDeleteDto":{"type":"object","properties":{"siweMessage":{"type":"string","description":"SIWE message string","example":"namespace.ninja wants you to sign in with your Ethereum account:\n0x54b06711C8022faf11EC347F2bDc68A91eA03a3a\n\nSign in to Avatar Service (local test)\n\nURI: http://namespace.ninja \nVersion: 1\nChain ID: 1\nNonce: 99ba8946989dcd142a5802257a5a68580dadaa9c86d66416508ef8627f6cc291bb81400991750db4dd11aefc77aaa0ef\nIssued At: 2025-09-16T20:00:33.597Z"},"siweSignature":{"type":"string","description":"Signature for SIWE message","example":"0xb6eff78a2f96dfdc01a2cf0555256abca11229e240f44a379cb45eca667566bf4a4d8f2e3eb5dd130ff3b01409e82fe54d00a20e296338ee05c3b040a1f6f8111b"},"address":{"type":"string","description":"Wallet address (checks against SIWE)","example":"0x54b06711C8022faf11EC347F2bDc68A91eA03a3a"}},"required":["siweMessage","siweSignature","address"]},"DeleteResponseDto":{"type":"object","properties":{"subname":{"type":"string","example":"avatar.offchainsub.eth","description":"ENS subname"},"network":{"type":"string","example":"mainnet","enum":["mainnet","sepolia"],"description":"Network identifier"},"message":{"type":"string","example":"Avatar deleted successfully","description":"Success message"},"deletedAt":{"type":"string","example":"2025-10-24T10:35:00.000Z","description":"ISO 8601 timestamp of deletion"}},"required":["subname","network","message","deletedAt"]},"HeaderUploadResponseDto":{"type":"object","properties":{"subname":{"type":"string","example":"avatar.offchainsub.eth","description":"ENS subname"},"network":{"type":"string","example":"mainnet","enum":["mainnet","sepolia"],"description":"Network identifier"},"headerUrl":{"type":"string","example":"https://avtr.cc/avatar.offchainsub.eth/h","description":"Public URL to access the header image"},"uploadedAt":{"type":"string","example":"2025-10-24T10:30:00.000Z","description":"ISO 8601 timestamp of upload"},"fileSize":{"type":"number","example":131131,"description":"File size in bytes"},"isUpdate":{"type":"boolean","example":false,"description":"Whether this was an update (true) or new upload (false)"},"pending":{"type":"boolean","example":true,"description":"If true, upload is pending ENS record verification (pre-registration upload)"},"message":{"type":"string","example":"Upload queued for verification. Set your ENS record within 5 minutes to confirm.","description":"Additional message for pending uploads"}},"required":["subname","network","headerUrl","uploadedAt","fileSize","isUpdate"]},"HeaderDeleteDto":{"type":"object","properties":{"siweMessage":{"type":"string","description":"SIWE message string","example":"namespace.ninja wants you to sign in with your Ethereum account:\n0x54b06711C8022faf11EC347F2bDc68A91eA03a3a\n\nSign in to Avatar Service (local test)\n\nURI: http://namespace.ninja \nVersion: 1\nChain ID: 1\nNonce: 99ba8946989dcd142a5802257a5a68580dadaa9c86d66416508ef8627f6cc291bb81400991750db4dd11aefc77aaa0ef\nIssued At: 2025-09-16T20:00:33.597Z"},"siweSignature":{"type":"string","description":"Signature for SIWE message","example":"0xb6eff78a2f96dfdc01a2cf0555256abca11229e240f44a379cb45eca667566bf4a4d8f2e3eb5dd130ff3b01409e82fe54d00a20e296338ee05c3b040a1f6f8111b"},"address":{"type":"string","description":"Wallet address (checks against SIWE)","example":"0x54b06711C8022faf11EC347F2bDc68A91eA03a3a"}},"required":["siweMessage","siweSignature","address"]}}}}