openapi: 3.0.3 info: title: Wallet Registry API version: 1.0.0 description: | REST API wrapper for the AccountWalletRegistry smart contract. Maps regulated fiat accounts (IBAN, ABA) to Web3 wallets, storing hashed account references (no PII on-chain). Supports 1-to-many mappings between accounts and wallets. This API provides a harmonized integration layer for: - Account-to-wallet linking - Wallet-to-account resolution - Link status management - Multi-provider wallet support (MetaMask, Fireblocks, etc.) contact: name: DBIS API Support email: api-support@dbis.org license: name: MIT url: https://opensource.org/licenses/MIT servers: - url: https://api.d-bis.org/api/v1/wallet-registry description: Production server - url: https://sandbox.d-bis.org/api/v1/wallet-registry description: Sandbox server - url: http://localhost:8080/api/v1/wallet-registry description: Development server security: - BearerAuth: [] - OAuth2MTLS: [] tags: - name: Wallet Registry description: Account-to-wallet mapping operations - name: Health description: Health check endpoints paths: /health: get: tags: [Health] summary: Health check description: Returns the health status of the Wallet Registry API and contract connection operationId: getHealth security: [] responses: '200': description: Service is healthy content: application/json: schema: type: object properties: status: type: string example: "healthy" contract: type: object properties: address: type: string example: "0xBeEF0128B7ff030e25beeda6Ff62f02041Dedbd0" connected: type: boolean example: true chainId: type: integer example: 138 timestamp: type: string format: date-time /accounts/{accountRefId}/wallets: post: tags: [Wallet Registry] summary: Link account to wallet description: Creates a link between an account reference and a wallet reference operationId: linkAccountToWallet parameters: - $ref: '#/components/parameters/AccountRefId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LinkAccountWalletRequest' examples: metamask: value: walletRefId: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5" provider: "METAMASK" responses: '201': description: Account linked to wallet successfully content: application/json: schema: $ref: '#/components/schemas/WalletLinkResponse' example: success: true data: accountRefId: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" walletRefId: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5" provider: "METAMASK" linkedAt: 1704067200 active: true transactionHash: "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" timestamp: "2024-01-01T00:00:00Z" '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '409': $ref: '#/components/responses/Conflict' '500': $ref: '#/components/responses/InternalServerError' get: tags: [Wallet Registry] summary: Get wallets for account description: Returns all wallet links associated with an account reference operationId: getWalletsForAccount parameters: - $ref: '#/components/parameters/AccountRefId' - name: active in: query description: Filter by active status required: false schema: type: boolean responses: '200': description: List of wallet links content: application/json: schema: $ref: '#/components/schemas/WalletLinkListResponse' example: success: true data: accountRefId: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" wallets: - walletRefId: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5" provider: "METAMASK" linkedAt: 1704067200 active: true - walletRefId: "0x8ba1f109551bD432803012645Hac136c85C3e06b" provider: "FIREBLOCKS" linkedAt: 1704070800 active: false timestamp: "2024-01-01T00:00:00Z" '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' /accounts/{accountRefId}/wallets/{walletRefId}: delete: tags: [Wallet Registry] summary: Unlink account from wallet description: Deactivates the link between an account reference and wallet reference operationId: unlinkAccountFromWallet parameters: - $ref: '#/components/parameters/AccountRefId' - $ref: '#/components/parameters/WalletRefId' responses: '200': description: Account unlinked from wallet successfully content: application/json: schema: $ref: '#/components/schemas/WalletLinkResponse' example: success: true data: accountRefId: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" walletRefId: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5" active: false transactionHash: "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" timestamp: "2024-01-01T00:01:00Z" '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' /wallets/{walletRefId}/accounts: get: tags: [Wallet Registry] summary: Get accounts for wallet description: Returns all account references associated with a wallet reference operationId: getAccountsForWallet parameters: - $ref: '#/components/parameters/WalletRefId' responses: '200': description: List of account references content: application/json: schema: $ref: '#/components/schemas/AccountListResponse' example: success: true data: walletRefId: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5" accounts: - accountRefId: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" - accountRefId: "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" timestamp: "2024-01-01T00:00:00Z" '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' /accounts/{accountRefId}/wallets/{walletRefId}/status: get: tags: [Wallet Registry] summary: Check link status description: Checks if an account and wallet are linked and/or active operationId: getLinkStatus parameters: - $ref: '#/components/parameters/AccountRefId' - $ref: '#/components/parameters/WalletRefId' responses: '200': description: Link status content: application/json: schema: $ref: '#/components/schemas/LinkStatusResponse' example: success: true data: accountRefId: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" walletRefId: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5" isLinked: true isActive: true timestamp: "2024-01-01T00:00:00Z" '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalServerError' components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT description: JWT token for authentication OAuth2MTLS: type: oauth2 flows: clientCredentials: tokenUrl: https://auth.d-bis.org/oauth2/token scopes: wallet-registry:read: Read access to wallet registry wallet-registry:write: Write access to wallet registry parameters: AccountRefId: name: accountRefId in: path required: true description: Hashed account reference ID (bytes32 hex string) schema: type: string pattern: '^0x[a-fA-F0-9]{64}$' example: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" WalletRefId: name: walletRefId in: path required: true description: Hashed wallet reference ID (bytes32 hex string) or wallet address schema: type: string pattern: '^0x[a-fA-F0-9]{40,64}$' example: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5" schemas: LinkAccountWalletRequest: type: object required: - walletRefId - provider properties: walletRefId: type: string description: Hashed wallet reference ID or wallet address pattern: '^0x[a-fA-F0-9]{40,64}$' example: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5" provider: type: string description: Wallet provider identifier enum: [METAMASK, FIREBLOCKS, CUSTODY_X, LEDGER, TREZOR, OTHER] example: "METAMASK" WalletLink: type: object properties: walletRefId: type: string description: Hashed wallet reference ID example: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5" provider: type: string description: Wallet provider identifier example: "METAMASK" linkedAt: type: integer format: int64 description: Unix timestamp when the link was created example: 1704067200 active: type: boolean description: Whether the link is currently active example: true WalletLinkResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: object properties: accountRefId: type: string example: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" walletRefId: type: string example: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5" provider: type: string example: "METAMASK" linkedAt: type: integer format: int64 example: 1704067200 active: type: boolean example: true transactionHash: type: string description: Transaction hash of the blockchain operation example: "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" WalletLinkListResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: object properties: accountRefId: type: string example: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" wallets: type: array items: $ref: '#/components/schemas/WalletLink' AccountListResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: object properties: walletRefId: type: string example: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5" accounts: type: array items: type: object properties: accountRefId: type: string example: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" LinkStatusResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: object properties: accountRefId: type: string example: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" walletRefId: type: string example: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5" isLinked: type: boolean description: Whether the account and wallet are linked (regardless of active status) example: true isActive: type: boolean description: Whether the link is currently active example: true BaseResponse: type: object properties: success: type: boolean example: true timestamp: type: string format: date-time ErrorResponse: type: object properties: success: type: boolean example: false error: type: object properties: code: type: string example: "VALIDATION_ERROR" message: type: string example: "Invalid request parameters" details: type: object timestamp: type: string format: date-time responses: BadRequest: description: Bad request - validation error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "VALIDATION_ERROR" message: "Invalid accountRefId format" details: field: "accountRefId" reason: "Must be a 64-character hex string prefixed with 0x" timestamp: "2024-01-01T00:00:00Z" Unauthorized: description: Unauthorized - missing or invalid authentication content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "UNAUTHORIZED" message: "Missing or invalid authentication token" timestamp: "2024-01-01T00:00:00Z" Forbidden: description: Forbidden - insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "FORBIDDEN" message: "Insufficient permissions. ACCOUNT_MANAGER_ROLE required" timestamp: "2024-01-01T00:00:00Z" NotFound: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "NOT_FOUND" message: "Account or wallet not found" timestamp: "2024-01-01T00:00:00Z" Conflict: description: Conflict - link already exists content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "CONFLICT" message: "Account and wallet are already linked" timestamp: "2024-01-01T00:00:00Z" InternalServerError: description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "INTERNAL_ERROR" message: "An internal error occurred" timestamp: "2024-01-01T00:00:00Z"