 
 Firmwares = ledger.dongle.Firmwares
 
-# Ledger OS pubKey, used for pairing.
-Attestation =
-  String: "04c370d4013107a98dfef01d6db5bb3419deb9299535f0be47f05939a78b314a3c29b51fcaa9b3d46fa382c995456af50cd57fb017c0ce05e4a31864a79b8fbfd6"
-Attestation.Bytes = parseInt(hex, 16) for hex in Attestation.String.match(/\w\w/g)
-Attestation.xPoint = Attestation.String.substr(2,64)
-Attestation.yPoint = Attestation.String.substr(66)
-
-BetaAttestation =
-  String: "04e69fd3c044865200e66f124b5ea237c918503931bee070edfcab79a00a25d6b5a09afbee902b4b763ecf1f9c25f82d6b0cf72bce3faf98523a1066948f1a395f"
-BetaAttestation.Bytes = parseInt(hex, 16) for hex in BetaAttestation.String.match(/\w\w/g)
-BetaAttestation.xPoint = BetaAttestation.String.substr(2,64)
-BetaAttestation.yPoint = BetaAttestation.String.substr(66)
+Attestations = {}
+
+class Attestation
+
+  xPoint: null
+  yPoint: null
+  Bytes: null
+  BatchId: null
+  DerivationId: null
+
+  constructor: (batchId, derivationId, value) ->
+    if _(this).isKindOf(Attestation)
+      @BatchId = batchId
+      @DerivationId = derivationId
+      @Id = Convert.toHexInt(batchId) + Convert.toHexInt(derivationId)
+      @String = value
+      @Bytes = parseInt(hex, 16) for hex in @String.match(/\w\w/g)
+      @xPoint = @String.substr(2,64)
+      @yPoint = @String.substr(66)
+      Attestations[@Id] = this
+    else
+      new Attestation(batchId, derivationId, value)
+
+  isBeta: -> @BatchId is 0
+  isProduction: -> !@isBeta()
+
+  getAttestationId: -> new ByteString(@Id, HEX)
+
+Attestation(0, 0, "04e69fd3c044865200e66f124b5ea237c918503931bee070edfcab79a00a25d6b5a09afbee902b4b763ecf1f9c25f82d6b0cf72bce3faf98523a1066948f1a395f")
+Attestation(1, 1, "04223314cdffec8740150afe46db3575fae840362b137316c0d222a071607d61b2fd40abb2652a7fea20e3bb3e64dc6d495d59823d143c53c4fe4059c5ff16e406")
+Attestation(2, 1, "04c370d4013107a98dfef01d6db5bb3419deb9299535f0be47f05939a78b314a3c29b51fcaa9b3d46fa382c995456af50cd57fb017c0ce05e4a31864a79b8fbfd6")
 
 
 # This path do not need a verified PIN to sign messages.

        d.rejectWithError(Errors.CommunicationError, err)
      .done()
      d.promise

  # Return asynchronously state. Wait until a state is set.
  # @param [Function] callback Optional argument

  # Verify that dongle firmware is "official".
  # @param [Function] callback Optional argument
  # @return [Q.Promise]
  isCertified: (callback=undefined) -> @_checkCertification(no, callback)

  isBetaCertified: (callback=undefined) -> @_checkCertification(yes, callback)

  _checkCertification: (isBeta, callback = undefined) ->
    _btchipQueue.enqueue "checkCertification", =>
      d = ledger.defer(callback)
      return d.resolve(true).promise if @getIntFirmwareVersion() < ledger.dongle.Firmwares.V_L_1_0_0
