Signature Authentication Code Examples

Below are very simple example secret key signature authentication implementations of authentication in a couple of different languages.

Each example is annotated with todo notes that you must address before the code is usable. Examples contain at least an HTTP JSON API call with a signature against the Wyre production API (the testwyre.com environment URI is commented out but included).

<?php
    function make_authenticated_request($endpoint, $method, $body) {
        // $url = 'https://api.testwyre.com'; // todo use this endpoint for testwyre environment
        $url = 'https://api.sendwyre.com';
      
        // todo please replace these with your own keys for the correct environment
        $api_key = "AK-AAAAAAA-AAAAAAA-AAAAAAA-AAAAAAA";
        $secret_key = "SK-AAAAAAA-AAAAAAA-AAAAAAA-AAAAAAA";

        $timestamp = floor(microtime(true)*1000);
        $request_url = $url . $endpoint;

        if(strpos($request_url,"?"))
            $request_url .= '&timestamp=' . sprintf("%d", $timestamp);
        else
            $request_url .= '?timestamp=' . sprintf("%d", $timestamp);

        if(!empty($body))
            $body = json_encode($body, JSON_FORCE_OBJECT);
        else
            $body = '';

        $headers = array(
            "Content-Type: application/json",
            "X-Api-Key: ". $api_key,
            "X-Api-Signature: ". calc_auth_sig_hash($secret_key, $request_url . $body)
        );
        $curl = curl_init();

        if($method=="POST"){
          $options = array(
            CURLOPT_URL             => $request_url,
            CURLOPT_POST            =>  true,
            CURLOPT_POSTFIELDS      => $body,
            CURLOPT_RETURNTRANSFER  => true);
        }else {
          $options = array(
            CURLOPT_URL             => $request_url,
            CURLOPT_RETURNTRANSFER  => true);
        }
        curl_setopt_array($curl, $options);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        $result = curl_exec($curl);
        curl_close($curl);
        var_dump($result);
        return json_decode($result, true);
    }

    function calc_auth_sig_hash($seckey, $val) {
        $hash = hash_hmac('sha256', $val, $seckey);
        return $hash;
    }

        // try to retrieve the current account
    echo make_authenticated_request("/v2/account", "GET", array());

        // perform a transfer
        $transfer = array(
      "sourceCurrency"=>"USD",
      "dest"=>"account:AC-XXXXXXXX", // replace with your account ID
      "sourceAmount"=> "100.50",
      "destCurrency"=> "BTC",
      "message"=> "convert USD to bitcoin"
      );
        echo make_authenticated_request("/v2/transfers", "POST", $transfer);
?>
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Linq;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;

namespace testauthwyre
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            WyreApi wyre = new WyreApi();

            HttpWebResponse accountResponse = wyre.Get("/v2/account");

            Console.WriteLine(GetResponseBody(accountResponse));

            Dictionary<string, object> body = new Dictionary<string, object>();
            body.Add("sourceCurrency", "USD");
            body.Add("destCurrency", "BTC");
            body.Add("sourceAmount", "50.50");
            body.Add("dest", "account:AC-XXXXXX"); // todo use your real account ID here
            HttpWebResponse transferResponse = wyre.Post("/v2/transfers", body);

            Console.WriteLine(GetResponseBody(transferResponse));
        }

        private static string GetResponseBody(HttpWebResponse response)
        {
            return JObject.Parse(new StreamReader(response.GetResponseStream()).ReadToEnd()).ToString(Formatting.Indented);
        }
    }

    public class WyreApi
    {
        private const String domain = "https://api.sendwyre.com";
        // private const String domain = "https://api.testwyre.com"; // todo use this endpoint for Wyre's testing environmnemt
      
        // todo replace these with your api private and secret keys
        private const String apiKey = "AK-AAAAAAAA-AAAAAAAA-AAAAAAAA-AAAAAAAA";
        private const String secKey = "SK-AAAAAAAA-AAAAAAAA-AAAAAAAA-AAAAAAAA";

        public HttpWebResponse Get(string path)
        {
            return Get(path, new Dictionary<string, object>());
        }

        public HttpWebResponse Get(string path, Dictionary<string, object> queryParams)
        {
            return Request("GET", path, queryParams);
        }

        public HttpWebResponse Post(string path, Dictionary<string, object> body)
        {
            return Request("POST", path, body);
        }

        private HttpWebResponse Request(string method, string path, Dictionary<string, object> body)
        {
            Dictionary<string, object> queryParams = new Dictionary<string, object>();

            if (method.Equals("GET"))
                queryParams = body;

            queryParams.Add("timestamp", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());

            string queryString = queryParams.Aggregate("", (previous, current) => previous + "&" + current.Key + "=" + current.Value).Remove(0, 1);

            string url = domain + path + "?" + queryString;

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = method;
            request.ContentType = "application/json";
            request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

            if (!method.Equals("GET"))
            {
                url += JsonConvert.SerializeObject(body);
                using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
                    writer.Write(JsonConvert.SerializeObject(body));
            }

            request.Headers["X-Api-Key"] = apiKey;
            request.Headers["X-Api-Signature"] = CalcAuthSigHash(secKey, url);

            try 
            {
                return (HttpWebResponse)request.GetResponse();
            }
            catch(WebException e) 
            {
                string msg = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
                Console.WriteLine(msg);
                throw new SystemException(msg);
            }
        }

        private byte[] GetBytes(string str)
        {
            return Encoding.UTF8.GetBytes(str);
        }

        private string GetString(byte[] bytes)
        {
            return BitConverter.ToString(bytes);
        }

        private String CalcAuthSigHash(string key, string value)
        {
            HMACSHA256 hmac = new HMACSHA256(GetBytes(key));
            string hash = GetString(hmac.ComputeHash(GetBytes(value))).Replace("-", "");
            return hash;
        }
    }
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.Integer;
import java.lang.String;
import java.lang.StringBuffer;
import java.net.HttpURLConnection;
import java.net.URL;

public class TestAuth {
    public static void main(String[] args) {
    // todo replace with your actual credentials
        String apiKey = "AK-AAAAAAAA-AAAAAAAA-AAAAAAAA-AAAAAAAA";
        String secretKey = "SK-AAAAAAAA-AAAAAAAA-AAAAAAAA-AAAAAAAA";

    // String baseUrl = "https://api.testwyre.com"; // todo use this for Wyre's testing environment 
    String baseUrl = "https://api.sendwyre.com";
        String data = "";

        String result = executeWyreRequest(baseUrl + "/v2/account", "", "GET", apiKey, secretKey);
        System.out.println(result);
    
    // todo encode request data - you probably want to use a JSON serialization library such as Jackson for this!
        data = "{" +
                "  \"dest\": \"account:AC-XXXXX\"," + // todo replace with your account ID
                "  \"destCurrency\": \"USD\"," +
                "  \"sourceCurrency\" : \"BTC\"," +
                "  \"sourceAmount\" : \"1\"," +
                "  \"message\": \"$1 worth of bitcoin!\"" +
                "}";
        result = executeWyreRequest(baseUrl + "/v2/transfers", data, "POST", apiKey, secretKey);

        System.out.println(result);
    }

    public static String executeWyreRequest(String targetURL, String requestBody, String method, String apiKey, String secretKey) {
        URL url;
        HttpURLConnection connection = null;
        try {

            targetURL += ((targetURL.indexOf("?")>0)?"&":"?") + "timestamp=" + System.currentTimeMillis();

            //Create connection
            url = new URL(targetURL);
            connection = (HttpURLConnection)url.openConnection();
            connection.setRequestMethod(method);
            System.out.println(connection.getRequestMethod());

            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Content-Length", Integer.toString(requestBody.getBytes().length));

            // Provide API key and signature
            connection.setRequestProperty("X-Api-Key", apiKey);
            connection.setRequestProperty("X-Api-Signature",computeSignature(secretKey,targetURL,requestBody));

            //Send request
            if(method.equals("POST")) {
                connection.setDoOutput(true);
                connection.setRequestMethod(method);

                DataOutputStream wr = new DataOutputStream(
                        connection.getOutputStream());

                wr.write(requestBody.getBytes("UTF-8"));
                wr.flush();
                wr.close();
            }

            //Get Response
            InputStream is;
            if (connection.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
                is = connection.getInputStream();
            } else {

                is = connection.getErrorStream();
            }

            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            String line;
            StringBuffer response = new StringBuffer();
            while((line = rd.readLine()) != null) {
                response.append(line);
                response.append('\r');
            }
            rd.close();
            return response.toString();

        } catch (Exception e) {

            e.printStackTrace();
            return null;

        } finally {

            if(connection != null) {
                connection.disconnect();
            }
        }
    }

    public static String computeSignature(String secretKey, String url, String reqData) {

        String data = url + reqData;

        System.out.println(data);

        try {
            Mac sha256Hmac = Mac.getInstance("HmacSHA256");
            SecretKeySpec key = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
            sha256Hmac.init(key);

            byte[] macData = sha256Hmac.doFinal(data.getBytes("UTF-8"));

            String result = "";
            for (final byte element : macData){
                result += Integer.toString((element & 0xff) + 0x100, 16).substring(1);
            }
            return result;

        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}
require 'uri'
require 'net/http'
require 'digest/hmac'
require 'json'

class WyreApi
  # todo replace these with your real Wyre credentials
  ACCOUNT_ID = 'AC-XXXXXXX'
  API_KEY = 'AK-AAAAAAAA-AAAAAAAA-AAAAAAAA-AAAAAAAA'
  SEC_KEY = 'SK-AAAAAAAA-AAAAAAAA-AAAAAAAA-AAAAAAAA'
  API_URL = 'https://api.sendwyre.com'
  # API_URL = 'https://api.testwyre.com' # todo use this for Wyre's testing environment

  def create_transfer options
    api_post '/v2/transfers', options
  end

  private

  def api_post path, post_data = {}
    params = {
      'timestamp' => (Time.now.to_i * 1000).to_s
    }

    url = API_URL + path + '?' + URI.encode_www_form(params)

    headers = {
      'X-Api-Key' => API_KEY,
      'X-Api-Signature' => calc_auth_sig_hash(url + post_data.to_json.to_s)
    }

    uri = URI API_URL
    Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
      http.request_post(url, post_data.to_json.to_s, headers) do |res|
        response = JSON.parse res.body
        raise response['message'] if res.code != '200'
        return response
      end
    end
  end

  def calc_auth_sig_hash url_body
    return Digest::HMAC.hexdigest url_body, SEC_KEY, Digest::SHA256
  end
end

api = WyreApi.new
api.create_transfer({'sourceAmount'=>50,'sourceCurrency'=>'USD','dest'=>'account:' + ACCOUNT_ID, 'destCurrency'=>'BTC', 'message'=>'buy some bitcoin')
// This sample assumes use of Express Node.js framework 
const axios = require('axios');
const CryptoJS = require('crypto-js');

// Store API keys in your environment configuration.
const YOUR_WYRE_API_KEY = AK-XXXX-XXXX-XXXX;
const YOUR_WYRE_SECRET_KEY = SK-XXXX-XXXX-XXXX;

const productionUrl = "https://api.senwyre.com";
const testUrl = "https://api.testwyre.com"

// Signature Calculation using Crypto-js
const signature = (url, data) => {
    const dataToSign = url + data;
    const token = CryptoJS.enc.Hex.stringify(CryptoJS.HmacSHA256(dataToSign.toString(CryptoJS.enc.Utf8), YOUR_WYRE_SECRET_KEY));
    return token;
}

/*Wallet Order Quotation POST request: 
https://docs.sendwyre.com/docs/wallet-order-quotation
*/
async rateQuote(req, res, next) {
        try {
            const timestamp = new Date().getTime();
            const url = `${testUrl}/v3/orders/quote/partner?timestamp=${timestamp}`;
            const headers = {};
            const body = {
                amount: "100.75",
                sourceCurrency: "USD",
                destCurrency: "BTC",
                dest: "bitcoin:1xxxxxxxxxxxxxxx",
                country: "US",
                accountId: "AC_xxxxxxxx",
                walletType: "DEBIT_CARD"
            }
            const details = JSON.stringify(body);

            headers['Content-Type'] = 'application/json';
            headers['X-Api-Key'] = YOUR_WYRE_API_KEY;
            headers['X-Api-Signature'] = signature(url, details);

            const config = {
                method: "POST",
                url: url,
                headers: headers,
                data: details
            }

            const response = await axios(config);
            res.send(response.data);

        } catch (error) {
            next(error)
        }
    }