ES2017 Javascript Module - Cryptopia API

16 Sep 2017

Here’s a file you can use to connect to the Cryptopia API.

This snippet allows you to programmatically access the Cryptopia API using Promises, which is much, much easier than dealing with callbacks, in my opinion. I generally do not release any crypto-related code, but in this case, I think I can help a few people out.

// Sample Usage
public_api('GetMarkets', {hours: 1}).then(res => console.log(res))

const iso_fetch = require('isomorphic-fetch');

function public_api(method, params = {}) {
    return new Promise((resolve, reject) => {
        try {
            const public_methods = [
                'GetCurrencies',
                'GetTradePairs',
                'GetMarkets',
                'GetMarket',
                'GetMarketHistory',
                'GetMarketOrders'
            ];
            const host_name = 'https://www.cryptopia.co.nz';
            let uri = '/Api/' + method;
            if (public_methods.includes(method)) {
                if (params) {
                    uri += "/" + Object.values(params).join('/');
                }
                iso_fetch(host_name + uri)
                    .then(res => res.json())
                    .catch(err => reject(err))
                    .then(res => resolve(res))
                    .catch(err => reject(err))
            } else {
                return reject(new Error(`${method} does not exist in the Cryptopia Public API!`))
            }
        } catch (e) {
            return reject(e)
        }
    })
}

module.exports = public_api;

ES5 JavaScript - Using Getters to create a self-aware object

25 Aug 2017

Let’s imagine you’re on a large project. You have the following limitation - ES5 Javascript.

Now, what happens in large codebases with 20k+ lines? They will end up with files called config.js and contact_info.js and environments.js, etc. Reference files that are frequently used.

In my case, our project has some code that (for example), shouldn’t run in production, but it should run in a development environment.

We had a file that looked like this:

const ENVs = {
    // Arrays of strings. We use the ENV=[environment] condition when running scripts.
    // E.G. our CI will run ENV=test node script.js
    is_dev: ['development', 'dev_server_2'],
    is_prod: ['production'],
    is_test: ['test', 'aws_test'],
    is_aws: ['aws_test'],
};
module.exports = ENVs;

So here’s how we typically would use this. Let’s say we don’t want a certain part of code to run if we’re in the production environment (a pretty common need).

Using Node.js to get the ENV environmental variable, we would check like this:

const environment = require('./environment.js')

const env = process.env.ENV; // Get the ENV environmental variable using Node

if (environment.is_prod.indexOf(env) > -1) {
    return; // end the script
}

// one liner. this is what ends up happening in real life
if (environment.is_prod.indexOf(process.env.ENV) > -1) return;

If you’re saying dude, just use .includes() - remember, ES5!


Okay, so let’s say we have an urge to make this more readable across the codebase. What’s one way to solve this?

Why, sure, let’s introduce some more overhead to this process! :)

Let’s modify that object we worked with earlier.

const ENVs = {
    dev: ['development', 'dev_server_2'],
    prod: ['production'],
    test: ['test', 'aws_test'],
    aws: ['aws_test'],
   
    get is() {
        // Utility lookup functions added here
    }  
};

We’ve added a getter to the object called is. is is an object that will contain pre-computed responses about the environment we’re working in.

In the end, we want to be able to make a call like this: environment.is.dev. The logic for a self-aware object is as follows:

get is() {
    return Object.keys(this).filter(k => k !== 'is').reduce((accum, key) => {
        accum[key] = this[key].indexOf(process.env.ENV) > -1;
        return accum;
    }, {})
}

The whole thing ends up looking like this.

const ENVs = {
    dev: ['development', 'dev_server_2'],
    prod: ['production'],
    test: ['test', 'aws_test'],
    aws: ['aws_test'],
    get is() {
        return Object.keys(this).filter(k => k !== 'is').reduce((accum, key) => {
            accum[key] = this[key].indexOf(process.env.ENV) > -1;
            return accum;
        }, {})
    }
};

module.exports = ENVs;

Our developers can now do something easy when they’re trying to determine where the hell their code is running.

const env = require('./environment.js')

if (env.is.prod) {
    return; // don't run in prod!!!
} 
if (env.is.dev || env.is.test) {
    // do dev or test stuff
}

This sort of self-aware object makes working with constant data much simpler. If you know a cleaner way to do this, email me :) I’ll give you a prize. The prize is me sending you an email back btw.


Seraphon Bastiladon and Ripperdactyl Riders

14 Jul 2017

Thank you to my girlfriend Amanda for taking these photos of my recently finished Ripperdactyl Riders and Bastiladon.

I used polyurethane on the Solar Crest for the Bastiladon. It makes the gem shine and glint when light hits it. I really like it!

It's really coming together as an army.

Carnosaur vs Tree Lord

14 Jul 2017

A couple pics from a battle this afternoon.