openapi: 3.0.3
info:
  title: AML API v1 (Info & Risk Score)
  version: 1.0.0
  description: >
    Endpoints for retrieving blockchain address & transaction information, 
    and AML risk scores.  
    **Note:** `token=supported` returns aggregated report for all supported tokens.

servers:
  - url: https://{blockchain}.glprotocol.com/api
    variables:
      blockchain:
        default: eth
        enum:
          - btc
          - ltc
          - bsv
          - eth
          - avax
          - trx
        description: Blockchain ticker (selects API subdomain)

tags:
  - name: Info
    description: Info about address or transaction
  - name: Risk Report
    description: AML Risk Report for address or transaction

paths:
  /explorer/txBrowserIO:
    get:
      tags:
        - Info
      summary: Get Transaction Info
      description: >
        Retrieve detailed information about a specific transaction.  
        Response format differs depending on blockchain type:
        - **BTC/LTC/BSV**: includes inputs, outputs and detailed address data
        - **ETH/TRON/BNB**: includes prevNextInfo, txs array and rate info
      parameters:
        - name: tx_hash
          in: query
          required: true
          description: Transaction hash to query
          schema:
            type: string
        - name: x-api-key
          in: header
          required: true
          description: API key for authentication
          schema:
            type: string
      responses:
        "200":
          description: Transaction information successfully retrieved
          content:
            application/json:
              schema:
                oneOf:
                  - description: BTC/LTC/BSV transaction structure
                    type: object
                    properties:
                      tx_hash: { type: string }
                      inputsCount: { type: number }
                      outputsCount: { type: number }
                      blockHeight: { type: number }
                      timestamp: { type: number }
                      inputs:
                        type: array
                        items:
                          type: object
                          properties:
                            address: { type: string }
                            addressData:
                              type: object
                              properties:
                                address: { type: string }
                                amountReceived: { type: number }
                                amountSent: { type: number }
                                balance: { type: number }
                                block_hash: { type: string }
                                firstSeen: { type: number }
                                lastSeen: { type: number }
                                txCount: { type: number }
                                txReceivedCount: { type: number }
                                txSentCount: { type: number }
                            amount: { type: number }
                      outputs:
                        type: array
                        items:
                          type: object
                          properties:
                            address: { type: string }
                            addressData:
                              type: object
                              properties:
                                address: { type: string }
                                amountReceived: { type: number }
                                amountSent: { type: number }
                                balance: { type: number }
                                block_hash: { type: string }
                                firstSeen: { type: number }
                                lastSeen: { type: number }
                                txCount: { type: number }
                                txReceivedCount: { type: number }
                                txSentCount: { type: number }
                            amount: { type: number }
                      totalInputs: { type: number }
                      inputsAmount: { type: number }
                      outputsAmount: { type: number }
                      totalOutputs: { type: number }
                  - description: ETH/TRON/BNB transaction structure
                    type: object
                    properties:
                      prevNextInfo:
                        type: object
                        properties:
                          disabled:
                            type: array
                            items: {}
                      txs:
                        type: array
                        items:
                          type: object
                          properties:
                            _id: { type: string }
                            blockHeight: { type: number }
                            block_hash: { type: string }
                            tx_hash: { type: string }
                            index: { type: number }
                            from: { type: string }
                            to: { type: string }
                            value: { type: number }
                            gas: { type: number }
                            gasPrice: { type: number }
                            gasUsed: { type: number }
                            isParent: { type: boolean }
                            timestamp: { type: number }
                            txType: { type: string }
                            simpleView: { type: boolean }
                            prevTx:
                              type: array
                              items:
                                type: string
                            nextTx:
                              type: array
                              items:
                                type: string
                            fromData:
                              type: object
                              properties:
                                address: { type: string }
                                decimals: { type: number }
                                isContract: { type: boolean }
                            toData:
                              type: object
                              properties:
                                address: { type: string }
                                decimals: { type: number }
                                isContract: { type: boolean }
                            valuePrice: { type: number }
                            valuePriceTimestamp: { type: number }
                      total: { type: number }
                      isTransfer: { type: boolean }
                      rate: { type: number }
                      rateTimestamp: { type: number }
              examples:
                btcExample:
                  summary: BTC transaction example
                  value:
                    tx_hash: "3a007ce55103..."
                    inputsCount: 1
                    outputsCount: 2
                    blockHeight: 842459
                    timestamp: 1715094673
                    inputs:
                      - address: "1Mr8TLDtLsViCZ..."
                        addressData:
                          address: "1Mr8TLDtLsViCZ..."
                          amountReceived: 153297500
                          amountSent: 153297500
                          balance: 0
                          block_hash: "00000000000000..."
                          firstSeen: 1714815981
                          lastSeen: 1715094673
                          txCount: 4
                          txReceivedCount: 3
                          txSentCount: 3
                        amount: 125000000
                    outputs: []
                    totalInputs: 1
                    inputsAmount: 125000000
                    outputsAmount: 124932200
                    totalOutputs: 2
                ethExample:
                  summary: ETH transaction example
                  value:
                    prevNextInfo:
                      disabled: []
                    txs:
                      - _id: "663a90a0d448..."
                        blockHeight: 19820605
                        block_hash: "0xd96b0379..."
                        tx_hash: "0x78d67679b4..."
                        index: 140
                        from: "0xd6bbb1a2ab..."
                        to: "0x47da741e9f..."
                        value: 25939689827838284
                        gas: 0
                        gasPrice: 4775636831
                        gasUsed: 21000
                        isParent: true
                        timestamp: 1715114063
                        txType: "parent"
                        simpleView: true
                        prevTx: []
                        nextTx: []
                        fromData:
                          address: "0xd6bbb1a2ab..."
                          decimals: 0
                          isContract: false
                        toData:
                          address: "0x47da741e9f..."
                          decimals: 0
                          isContract: false
                        valuePrice: 82.74972510166738
                        valuePriceTimestamp: 1708985414743
                    total: 1
                    isTransfer: false
                    rate: 3190.081517970234
                    rateTimestamp: 1708985414743
        "400":
          description: Transaction hash not specified or invalid
          content:
            application/json:
              example:
                response:
                  errors:
                    - instancePath: ""
                      schemaPath: "#/anyOf/0/required"
                      keyword: "required"
                      params:
                        missingProperty: "tx_hash"
                      message: "must have required property 'tx_hash'"
                      schema: ["tx_hash"]
                      data:
                        inputsPerPage: 10
                        outputsPerPage: 10
                        inputsSkip: 0
                        outputsSkip: 0
                        userId: "USER_ID"
                        preferredCurrency: "USD"
                  status: 400
                success: false
                data:
                  messageType: "error"
                  message: "user.Http Exception"
        "401":
          description: Unauthorized request
          content:
            application/json:
              example:
                response: "User not found"
                status: 401
                message: "User not found"
                name: "HttpException"
                code: 401
                success: false
                path: "{REQUEST_URL}"
                method: "GET"
                timestamp: "5/3/2024, 6:16:56 AM"
                data:
                  messageType: "error"
                  message: "user.User not found"
        "404":
          description: Transaction not found
          content:
            application/json:
              example:
                messageType: "HttpException"
                message: "Transaction not found!"
                stack: "HttpException: TRANSACTION_NOT_FOUND"
                response: "TRANSACTION_NOT_FOUND"
                status: 400
                name: "HttpException"

  /explorer/getAddressInfo/{address}:
    get:
      tags:
        - Info
      summary: Get Address Info
      description: >
        Retrieve general information about a blockchain address.  
        Response structure differs depending on blockchain family (BTC-like vs ETH-like).
      parameters:
        - name: address
          in: path
          required: true
          description: Blockchain address to query
          schema:
            type: string
        - name: x-api-key
          in: header
          required: true
          description: API key for authentication
          schema:
            type: string
      responses:
        "200":
          description: Address information successfully retrieved
          content:
            application/json:
              schema:
                oneOf:
                  - description: BTC-like response
                    type: object
                    properties:
                      success:
                        type: boolean
                      data:
                        type: object
                        properties:
                          _id: { type: string }
                          address: { type: string }
                          amountReceived: { type: number }
                          amountSent: { type: number }
                          balance: { type: number }
                          blockHeight: { type: number }
                          block_hash: { type: string }
                          lastSeen: { type: number }
                          txCount: { type: number }
                          txReceivedCount: { type: number }
                          txSentCount: { type: number }
                          firstSeen: { type: number }
                          cluster: { type: number }
                          historyClusters:
                            type: array
                            items:
                              type: number
                          updatedAt: { type: string }
                          description: { type: string }
                          owner: { type: string }
                          tags:
                            type: array
                            items:
                              type: string
                          type:
                            type: object
                            properties:
                              _id: { type: string }
                              name: { type: string }
                              score: { type: number }
                          conflict: { type: boolean }
                          meta:
                            type: array
                            items: {}
                          clusterData:
                            type: object
                            properties:
                              _id: { type: string }
                              cluster: { type: number }
                              addressCount: { type: number }
                              address: { type: string }
                              owner: { type: string }
                              description: { type: string }
                              updatedAt: { type: string }
                              tags:
                                type: array
                                items:
                                  type: string
                              type:
                                type: object
                                properties:
                                  _id: { type: string }
                                  name: { type: string }
                                  score: { type: number }
                              meta:
                                type: array
                                items: {}
                              clusterSize: { type: number }
                              conflict: { type: boolean }
                          price: { type: string, nullable: true }
                          priceTimestamp: { type: number }
                          amountSentPrice: { type: number }
                          amountSentPriceTimestamp: { type: number }
                          amountReceivedPrice: { type: number }
                          amountReceivedPriceTimestamp: { type: number }
                          isMonitoring: { type: boolean }
                  - description: ETH-like response
                    type: object
                    properties:
                      success: { type: boolean }
                      data:
                        type: object
                        properties:
                          address: { type: string }
                          owner: { type: string }
                          type:
                            type: object
                            properties:
                              _id: { type: string }
                              name: { type: string }
                              score: { type: number }
                          description: { type: string }
                          typeName: { type: string, nullable: true }
                          parentCount: { type: number }
                          parentNativeCount: { type: number }
                          txCount: { type: number }
                          txReceivedCount: { type: number }
                          txSentCount: { type: number }
                          tags:
                            type: array
                            items:
                              type: string
                          contractInfo: { type: string, nullable: true }
                          meta:
                            type: array
                            items: {}
                          addressType: { type: string }
                          conflict: { type: boolean }
                          ens: { type: string, nullable: true }
                          totalTxs: { type: number }
                          totalETHTxs: { type: number }
                          totalInternalTxs: { type: number }
                          totalTokensTxs: { type: number }
                          isMonitoring: { type: boolean }


  /report/tx_hash/{tx_hash}:
    get:
      tags:
        - Risk Report
      summary: Get Transaction Risk Score
      description: >
        Calculate and retrieve the risk score of a specific transaction based on historical funds flow.  
        Supports:
          - Native coin analysis (BTC, ETH, LTC, TRX, BSV, etc.)
          - Token-specific analysis (`token={contract_address}`)
          - Unified token analysis (`token=supported`)
          - Directional analysis (`direction=0|1|2`)
          - Minimal response with only risk score (`$project[totalFunds]=1`)
      parameters:
        - name: tx_hash
          in: path
          required: true
          description: Transaction hash to query.
          schema:
            type: string
        - name: token
          in: query
          required: false
          description: >
            Token contract address.  
            - `supported` → unified search of all supported tokens  
            - empty → search by native coin  
            - contract address → search by specific token
          schema:
            type: string
        - name: direction
          in: query
          required: false
          description: >
            Transaction search direction.  
            - `0` → Source of Funds (default)  
            - `1` → Use of Funds  
            - `2` → Common (Source + Use of Funds)
          schema:
            type: integer
            enum: [0, 1, 2]
        - name: $project[totalFunds]
          in: query
          required: false
          description: >
            If set to `1`, only `totalFunds` field (risk score) will be returned.
          schema:
            type: integer
            enum: [0, 1]
        - name: x-api-key
          in: header
          required: true
          description: API key for authentication.
          schema:
            type: string
      responses:
        "200":
          description: Successful risk report.
          content:
            application/json:
              schema:
                type: object
                properties:
                  totalAmount:
                    type: number
                    description: Amount of incoming transaction funds for calculation
                  progress:
                    type: number
                    description: Internal processing progress (0-100)
                  depth:
                    type: number
                    description: Maximum depth of the found source
                  directTxCount:
                    type: number
                    description: Direct transaction count
                  totalFunds:
                    type: number
                    description: Calculated risk score value (default or sensitive formula)
                  sources:
                    type: array
                    description: Array of discovered sources
                    items:
                      type: object
                      properties:
                        directTx:
                          type: string
                        tx_hash:
                          type: string
                        address:
                          type: string
                        depth:
                          type: number
                        funds:
                          type: object
                          properties:
                            name:
                              type: string
                            score:
                              type: number
                            default:
                              type: boolean
                        amount:
                          type: number
                        share:
                          type: number
                        owner:
                          type: string
                        listType:
                          type: string
                          enum: ["Known sources", "Risky sources", "Unknown sources", "Swap"]
                        directStamp:
                          type: number
                        timestamp:
                          type: number
                        issuer:
                          type: string
                        currency:
                          type: string
              examples:
                nativeCoin:
                  summary: Native coin transaction analysis
                  value:
                    totalAmount: 251000000000000000
                    progress: 100
                    depth: 3
                    directTxCount: 10
                    totalFunds: 75
                    sources:
                      - directTx: "0xbd54a...750bbec0407dc7dc04"
                        tx_hash: "0x0fd34...dc61b8abc95021d17b"
                        address: "0xca258d51a825c82d16ce54dc61b8abc95021d17b"
                        depth: 3
                        funds:
                          name: "TAG_NAME"
                          score: 50
                          default: true
                        amount: 31643005583457000
                        share: 10
                        owner: "OWNER_NAME"
                        listType: "Unknown sources"
                        directStamp: 1697553611
                        timestamp: 1697525855
                token:
                  summary: Token-specific transaction analysis
                  value:
                    totalAmount: 251000000000000000
                    progress: 100
                    depth: 3
                    directTxCount: 10
                    totalFunds: 75
                    sources:
                      - directTx: "0xbd54a...750bbec0407dc7dc04"
                        tx_hash: "0x0fd34...dc61b8abc95021d17b"
                        address: "0xca258d51a825c82d16ce54dc61b8abc95021d17b"
                        depth: 3
                        funds:
                          name: "TAG_NAME"
                          score: 50
                          default: true
                        amount: 31643005583457000
                        share: 10
                        owner: "OWNER_NAME"
                        listType: "Unknown sources"
                        directStamp: 1697553611
                        timestamp: 1697525855
                        issuer: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
                        currency: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
                riskScoreOnly:
                  summary: Only risk score
                  value:
                    totalFunds: 75
        "400":
          description: Bad request (invalid parameters or $project value)
          content:
            application/json:
              example:
                success: false
                response:
                  statusCode: 400
                  message: "must be equal to one of the allowed values"
                  schema: [0, 1]
                data:
                  messageType: "error"
                  message: "user.ENOENT"
        "401":
          description: Unauthorized (API key missing or invalid)
          content:
            application/json:
              example:
                success: false
                response: "User not found"
                data:
                  messageType: "error"
                  message: "user.User not found"
        "404":
          description: Transaction not found
          content:
            application/json:
              example:
                success: false
                data:
                  messageType: "error"
                  message: "user.ENOENT"

  /report/address/{address}:
    get:
      tags:
        - Risk Report
      summary: Get Address Risk Score
      description: >
        Calculate and retrieve the risk score of a blockchain address based on historical transactions.  
        Supports:
          - Native coin analysis (BTC, ETH, LTC, TRX, BSV, etc.)
          - Token-specific analysis (`token={contract_address}`)
          - Unified token analysis (`token=supported`)
          - Directional analysis (`direction=0|1|2`)
          - Minimal response with only risk score (`$project[totalFunds]=1`)
      parameters:
        - name: address
          in: path
          required: true
          description: Blockchain address to query.
          schema:
            type: string
        - name: token
          in: query
          required: false
          description: >
            Token contract address.  
            - `supported` → unified search of all supported tokens  
            - empty → search by native coin  
            - contract address → search by specific token
          schema:
            type: string
        - name: direction
          in: query
          required: false
          description: >
            Transaction search direction.  
            - `0` → Source of Funds (default)  
            - `1` → Use of Funds  
            - `2` → Common (Source + Use of Funds)
          schema:
            type: integer
            enum: [0, 1, 2]
        - name: $project[totalFunds]
          in: query
          required: false
          description: >
            If set to `1`, only `totalFunds` field (risk score) will be returned.
          schema:
            type: integer
            enum: [0, 1]
        - name: x-api-key
          in: header
          required: true
          description: API key for authentication
          schema:
            type: string
      responses:
        "200":
          description: Successful risk report.
          content:
            application/json:
              schema:
                type: object
                properties:
                  totalAmount:
                    type: number
                    description: Amount of incoming transaction funds for calculation
                  progress:
                    type: number
                    description: Internal processing progress (0-100)
                  depth:
                    type: number
                    description: Maximum depth of the found source
                  directTxCount:
                    type: number
                    description: Direct transaction count
                  totalFunds:
                    type: number
                    description: Calculated risk score value (default or sensitive formula)
                  sources:
                    type: array
                    description: Array of discovered sources
                    items:
                      type: object
                      properties:
                        directTx:
                          type: string
                          description: Hash of the incoming transaction
                        tx_hash:
                          type: string
                          description: Hash of the transaction where the source was found
                        address:
                          type: string
                          description: Address of the found source
                        depth:
                          type: number
                          description: Depth at which the source was found
                        funds:
                          type: object
                          description: Tag or type information of the found source
                          properties:
                            name:
                              type: string
                            score:
                              type: number
                            default:
                              type: boolean
                        amount:
                          type: number
                          description: Amount of funds received
                        share:
                          type: number
                          description: Percentage of funds received from a source
                        owner:
                          type: string
                          description: Owner name of the source
                        listType:
                          type: string
                          description: Type of source
                          enum: ["Known sources", "Risky sources", "Unknown sources", "Swap"]
                        directStamp:
                          type: number
                          description: Timestamp of the direct transaction
                        timestamp:
                          type: number
                          description: Timestamp of the source transaction
                        issuer:
                          type: string
                          description: Token issuer (if applicable)
                        currency:
                          type: string
                          description: Currency contract (if applicable)
              examples:
                nativeCoin:
                  summary: Native coin analysis
                  value:
                    totalAmount: 251000000000000000
                    progress: 100
                    depth: 3
                    directTxCount: 10
                    totalFunds: 75
                    sources:
                      - directTx: "0xbd54a...750bbec0407dc7dc04"
                        tx_hash: "0x0fd34...dc61b8abc95021d17b"
                        address: "0xca258d51a825c82d16ce54dc61b8abc95021d17b"
                        depth: 3
                        funds:
                          name: "TAG_NAME"
                          score: 50
                          default: true
                        amount: 31643005583457000
                        share: 10
                        owner: "OWNER_NAME"
                        listType: "Unknown sources"
                        directStamp: 1697553611
                        timestamp: 1697525855
                token:
                  summary: Token-specific analysis
                  value:
                    totalAmount: 251000000000000000
                    progress: 100
                    depth: 3
                    directTxCount: 10
                    totalFunds: 75
                    sources:
                      - directTx: "0xbd54a...750bbec0407dc7dc04"
                        tx_hash: "0x0fd34...dc61b8abc95021d17b"
                        address: "0xca258d51a825c82d16ce54dc61b8abc95021d17b"
                        depth: 3
                        funds:
                          name: "TAG_NAME"
                          score: 50
                          default: true
                        amount: 31643005583457000
                        share: 10
                        owner: "OWNER_NAME"
                        listType: "Unknown sources"
                        directStamp: 1697553611
                        timestamp: 1697525855
                        issuer: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
                        currency: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
                riskScoreOnly:
                  summary: Only risk score
                  value:
                    totalFunds: 75
        "400":
          description: Bad request (invalid address or parameters)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  response:
                    type: object
                  data:
                    type: object
              example:
                success: false
                response:
                  errors:
                    - instancePath: "/address"
                      schemaPath: "#/properties/address/$ts"
                      keyword: "required"
                      params: {}
                      message: "must pass \"$ts\" keyword validation"
                      schema: "AddressId"
                      data: "SomeInvalidAddress"
                  status: 400
                data:
                  messageType: "error"
                  message: "user.Http Exception"
        "401":
          description: Unauthorized (API key missing or invalid)
          content:
            application/json:
              example:
                success: false
                response: "User not found"
                data:
                  messageType: "error"
                  message: "user.User not found"
        "404":
          description: Address not found
          content:
            application/json:
              example:
                success: false
                data:
                  messageType: "error"
                  message: "user.ENOENT"
