You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: security_token_request.rb
    path of file: ./repos/identity-idp/app/services/proofing/aamva/request
    
    the code of the file until where you have to start completion: require 'erb'
require 'faraday'
require 'openssl'
require 'retries'
require 'securerandom'
require 'time'
require 'xmldsig'

module Proofing
  module Aamva
    module Request
      class SecurityTokenRequest
        DEFAULT_AUTH_URL = 'https://authentication-cert.aamva.org/Authentication/Authenticate.svc'.freeze
        CONTENT_TYPE = 'application/soap+xml;charset=UTF-8'.freeze
        SOAP_ACTION =
          '"http://aamva.org/authentication/3.1.0/IAuthenticationService/Authenticate"'.freeze

        attr_reader :config, :body, :headers, :url

        def initialize(config)
          @config = config
          @url = auth_url
          @body = build_request_body
          @headers = build_request_headers
        end

        def nonce
          @nonce ||= SecureRandom.base64(32)
        end

        def send
          with_retries(max_tries: 2, rescue: [Faraday::TimeoutError, Faraday::ConnectionFailed]) do
            Response::SecurityTokenResponse.new(
              http_client.post(url, body, headers) do |req|
                req.options.context = { service_name: 'aamva_security_token' }
              end,
            )
          end
        rescue Faraday::TimeoutError, Faraday::ConnectionFailed => err
          message = "AAMVA raised #{err.class} waiting for security token response: #{err.message}"
          raise ::Proofing::TimeoutError, message
        end

        def auth_url
          config.auth_url || DEFAULT_AUTH_URL
        end

        private

        def http_client
          Faraday.new(request: { open_timeout: timeout, timeout: timeout }) do |faraday|
            faraday.request :instrumentation, name: 'request_metric.faraday'
            faraday.adapter :net_http
          end
        end

        def build_request_body
          renderer = ERB.new(request_body_template)
          xml = renderer.result(binding)
          xml = xml.gsub(/^\s+/, '').gsub(/\s+$/, '').delete("\n")
          document = Xmldsig::SignedDocument.new(xml)
          document.sign(private_key).gsub("<?xml version=\"1.0\"?>\n", '')
        end

        def build_request_headers
          {
            'SOAPAction' => SOAP_ACTION,
            'Content-Type' => CONTENT_TYPE,
            'Content-Length' => body.length.to_s,
          }
        end

        def certificate
          @certificate = public_key.to_s.gsub(/\n?-----.+-----\n/, '')
        end

        def created_at
          @created_at ||= Time.zone.now.utc
        end

        def expires_at
          created_at + 300
        en
    
        def send
          with_retries(max_tries: 2, rescue: [Faraday::TimeoutError, Faraday::ConnectionFailed]) do
            Response::SecurityTokenResponse.new(
              http_client.post(url, body, headers) do |req|
                req.options.context = { service_name: 'aamva_security_token' }
              end,
            )
          end
        rescue Faraday::TimeoutError, Faraday::ConnectionFailed => err
          message = "AAMVA raised #{err.class} waiting for security token response: #{err.message}"
          raise ::Proofing::TimeoutError, message
        end

        def auth_url
          config.auth_url || DEFAULT_AUTH_URL
        end

        private

        def http_client
          Faraday.new(request: { open_timeout: timeout, timeout: timeout }) do |faraday|
            faraday.request :instrumentation, name: 'request_metric.faraday'
            faraday.adapter :net_http
          end
        end

        def build_request_body
          renderer = ERB.new(request_body_template)
          xml = renderer.result(binding)
          xml = xml.gsub(/^\s+/, '').gsub(/\s+$/, '').delete("\n")
          document = Xmldsig::SignedDocument.new(xml)
          document.sign(private_key).gsub("<?xml version=\"1.0\"?>\n", '')
        end

        def build_request_headers
          {
            'SOAPAction' => SOAP_ACTION,
            'Content-Type' => CONTENT_TYPE,
            'Content-Length' => body.length.to_s,
          }
        end

        def certificate
          @certificate = public_key.to_s.gsub(/\n?-----.+-----\n/, '')
        end

        def created_at
          @created_at ||= Time.zone.now.utc
        end

        def expires_at
          created_at + 300
        end

        def key_identifier
          @key_identifier ||=
            begin
              digest = OpenSSL::Digest::SHA1.digest(public_key.to_der)
              Base64.encode64(digest)
            end.strip
        end

        def message_timestamp_uuid
          @message_timestamp_uuid ||= SecureRandom.uuid
        end

        def message_to_uuid
          @message_to_uuid ||= SecureRandom.uuid
        end

        def private_key
          @private_key ||= OpenSSL::PKey::RSA.new(
            Base64.decode64(config.private_key),
          )
        end

        def public_key
          @public_key ||= OpenSSL::X509::Certificate.new(
            Base64.decode64(config.public_key),
          )
        end

        def reply_to_uuid
          @reply_to_uuid ||= SecureRandom.uuid
        end

        def request_body_template
          template_file_path = Rails.root.join(
            'app',
            'services',
            'proofing',
            'aamva',
            'request',
            'templates',
            'security_token.xml.erb',
          )
          File.read(template_file_path)
        end

        def uuid
          SecureRandom.uuid
        end

        def timeout
          (config.auth_request_timeout || 5).to_i
        end
      end