How can I create a list that has a length of a 64 bit unsigned integer in c#?

I am trying to create a blockchain based cryptocurrancy in c#. I have my blockchain class built but I realize on big problem with the current implementation. The blockchain is stored in memory in a List>. The problem I see with this is that the length of the list is a 32 bit signed integer. This is a problem if the chain get too big. Is there a way of making a List<> that has a maximum length of 9,223,372,036,854,775,807

I am trying to create a blockchain based cryptocurrancy in c#. I have my blockchain class built but I realize on big problem with the current implementation. The blockchain is stored in memory in a List>. The problem I see with this is that the length of the list is a 32 bit signed integer. This is a problem if the chain get too big. Is there a way of making a List<> that has a maximum length of 9,223,372,036,854,775,807

The current way of storing the blockchain is by initializing

static Dictionary<string, Socket[]> connections = new Dictionary<string, Socket[]>();

and adding a new Dictionary for every block

How to Plot Cryptocurrency Price Charts with Python in 10 minutes

How to Plot Cryptocurrency Price Charts with Python in 10 minutes

Starting from complete scratch, you will plot your first Cryptocurrency candlestick data charts by the end of this article

Starting from complete scratch, you will plot your first cryptocurrency candlestick data chart by the end of this article - In less than 10 minutes.

Building tools which take advantage of exchange data is a nightmare in the cryptocurrency space. The limited number of available tools means you need to develop features from nothing.

Since every exchange provides different endpoints for collecting data, this quickly turns into a black hole which will consume your time.

Each exchange requires custom code and infrastructure to handle the intricacies of what they offer.

Thankfully, the Universal Crypto Exchange APIs normalize this data for us. An API which you can freely use to access historical and live data.

This article will describe how to set up your first script to access live market data from any exchange, normalize it into a cohesive format, and plot it. There is no complex configuration or development.

Let’s get started!

Install Libraries

Before we get started writing the script, we need to install a few libraries. If you use pip, this can be done simply by running the following commands.

pip install shrimpy-python
pip install pandas
pip install plotly==4.1.0

Generate API Keys

After installing the necessary libraries, sign up for a Shrimpy Developer API account. These are the APIs which provide the exchange data. It’s free and takes only a few seconds to sign up.

After signing up, generate your master key. These keys are used to sign requests to Shrimpy and access crypto market data.

Make sure to securely store your public and secret keys. They will be needed for later steps.

Writing Our First Script

We’re now ready to begin writing our first script. The script for this article will collect candlestick market data from the exchange we specify, organize it in a way that’s understandable for the plotting library, and display it.

Import Libraries

In this script, we will be using the Plotly Library. This will provide a convenient way for us to get up and running without much effort.

Import these libraries into your script so we can collect our data and graph it.

import shrimpy
import plotly.graph_objects as go

Assign Keys

Before we can access any data from Shrimpy, we need to make sure we correctly sign our requests. This requires us to pass in our public and private keys. For now, let’s just assign them for later use.

public_key = '8x71n32d8cfbnnn1xzimjustkeyboardmashing8xn1t8jyv5098'
secret_key = '771dc5nxct4709672v4n09xn0morekeyboardmashing9475c029374n0xx4n50'

Create Client

To create the client, pass in the public and secret keys which were assigned in the previous step. The client will then conveniently handle the signing of each request, so you can focus on accessing the data and building tools with the data.

client = shrimpy.ShrimpyApiClient(public_key, secret_key)

Get Candles

It’s time to get our candlestick data from Shrimpy. Use the client to call the endpoint for retrieving the candlesticks.

Just make sure to pass in the exchange, trading pair, and interval you wish to access.

Example 1:

candles = client.get_candles(
    'binance',  # exchange
    'XLM',      # base_trading_symbol
    'BTC',      # quote_trading_symbol
    '15m'       # interval
)

Example 2:

candles = client.get_candles(
    'bittrex',  # exchange
    'LTC',      # base_trading_symbol
    'BTC',      # quote_trading_symbol
    '1h'        # interval
)

Example 3:

candles = client.get_candles(
    'kucoin',   # exchange
    'ETH',      # base_trading_symbol
    'USDT',     # quote_trading_symbol
    '1d'        # interval
)

Observe how we are able to change each of these parameters to configure the data we want to access.

The supported time intervals for each candle include the following:

1m, 5m, 15m, 1h, 6h, or 1d

Convert Data

Once the data has been collected from Shrimpy, we want to convert the data to the format which is accepted by the plotting library Plotly. To do this, we will go through the candlesticks we collected from Shrimpy and assign each of the candlestick components to an element of the candle.

dates = []
open_data = []
high_data = []
low_data = []
close_data = []

for candle in candles:
    dates.append(candle['time'])
    open_data.append(candle['open'])
    high_data.append(candle['high'])
    low_data.append(candle['low'])
    close_data.append(candle['close'])

The result of this step is each individual candlestick will be broken out into a list which holds the individual component of every candlestick.

Generate Figure

Finally, it’s time to generate the figure. Use the Plotly library to create the chart that we will display, then display the chart.

fig = go.Figure(data=[go.Candlestick(x=dates,
                       open=open_data, high=high_data,
                       low=low_data, close=close_data)])

fig.show()

Calling fig.show() displays the graph. This will look something like the following chart.

This is image title

The end result of the script is a graph which displays the candlesticks for an individual asset on an individual exchange over time.

Putting It All Together

Now that we’ve walked through each element of the script step-by-step, it’s time to put everything together.

# import the libraries we need
import shrimpy
import plotly.graph_objects as go

# insert your public and secret keys here
public_key = '8x71n32d8cfbnnn1xzimjustkeyboardmashing8xn1t8jyv5098'
secret_key = '771dc5nxct4709672v4n09xn0morekeyboardmashing9475c029374n0xx4n50'

# create the client
client = shrimpy.ShrimpyApiClient(public_key, secret_key)

# get the candles
candles = client.get_candles(
    'binance',  # exchange
    'XLM',      # base_trading_symbol
    'BTC',      # quote_trading_symbol
    '15m'       # interval
)

# create lists to hold our different data elements
dates = []
open_data = []
high_data = []
low_data = []
close_data = []

# convert from the Shrimpy candlesticks to the plotly graph objects format
for candle in candles:
    dates.append(candle['time'])
    open_data.append(candle['open'])
    high_data.append(candle['high'])
    low_data.append(candle['low'])
    close_data.append(candle['close'])

# construct the figure
fig = go.Figure(data=[go.Candlestick(x=dates,
                       open=open_data, high=high_data,
                       low=low_data, close=close_data)])

# display our graph
fig.show()

The final script can be run, altered, and leveraged to generate graphs similar to the one depicted above. Just make sure to insert your own public and secret keys so your client can properly sign requests.

More Scripts

If you want more ideas for developing your own scripts, explore everything that’s offered by the Universal Crypto Exchange APIs. You can find the Node and Python libraries for these APIs here:

Node

Python

Thank for reading! Please share if you liked it!

Go Top Programming Languages in 2020 from Authentic Surveys

Go Top Programming Languages in 2020 from Authentic Surveys

This article going to present the trends of top Programming Languages which will continue in the coming year 2020. This article uses data from authentic surveys, various collected statistics, search results and salary trends according to programming languages.

Comparing Programming Languages is a very complex thing and so there are many graphical illustration/jokes trying to symbolize Programming language. I found few and I am starting this article with those.

This is image title

In simple words, Programming Language empowers human to instruct and control machine. So, it is natural that there will be so many languages which try to make this process more powerful and simple. For this very reason there are hundreds of programming languages, many of those programming languages are now out of active use, few are going to be obsolete in coming years and then there are languages which is going to continue and prove its usage in coming years and then there are new programming language fighting for it acceptance.

This article going to present the trends of top Programming Languages which will continue in the coming year 2020. To predict the trend of the programming language in 2020 this article uses data from authentic surveys, various collected statistics, search results and salary trends according to programming languages. This article will help the new learner to pick a programming language to learn and for expert, it will help to decide either to switch to another language or to continue with his expertise language.

In the next section, I have prepared two tables which summarize the popularity trend of Programming Languages in the last five years (2015-19). The data is taken from Stackoverflow popularity survey 2015-2019. For a clear and accurate understanding, the programming languages are divided into two groups, first, languages which have origin before 2000 and the second group has languages which came after 2000. The selection of 2000 as the boundary is just random but very helpful to understand the programming trend under these two groups. The table also lists origin year and main or documented purpose of these programming/scripting languages.

This is image title
This is image title

Observations:

There is a decrease in the popularity of all languages from 2018 to 2019 except Python.

Python

Python is the only language continuously on rising since last five years. It is a general-purpose language, so someone wants to learn just one programming in 2020 and want to cover more area of software development then Python could be chosen**.**

Java

Java was on rising but fall in 2019, the reason could Kotlin gaining popularity on the Android platform. Java is a good choice for a programming language but now it is under Oracle and Google is promoting Kotlin so it is in the conflicted zone. As a matter of fact still, the large number of the company is using Java and going to continue with Java due to its developers base, framework, and legacy application.

C/C++

C and C++ are still holding with approx 20% and it will be there due to its inherent features and legacy system.

JavaScript

JavaScript popularity can be attributed to the growth of popular JavaScript library and framework like node.js, etc. JS is the language for the dynamic website and this going to be top for coming years because of its active development, support from Mozilla and penalty of libraries and frameworks. So, if someone wants to be web development, javascript is a must.

R

R is gaining popularity in recent years and reason would be growth and popularity of data analysis. It is used by data scientist but again much behind in comparison to Python which has established as general-purpose languages and enjoy active developers with lots of data science libraries and modules. So, one can prefer Python over R if they have to choose only one otherwise if wanted carrier in Data Sciences then learning both will a good option.

Ruby

Like PHP, Ruby is also facing tough competition from JavaScript and even Python to establish as back-end web development programming language. So, again for web development javascript and Python (server-side (Flask, Django, etc.) would be a good choice and will offer more domain flexibility than Ruby.

PHP

There is a sharp decline in PHP popularity in 2019 and it can be traced back to server-side acceptance of javascript and Python. So, if someone wants to go to server-side web development then still PHP is a good choice with a large number of popular framework like CakePHP, Codeigniter, etc. otherwise choosing a general-purpose programming language would be better.

Objective-C

Objective-C was the main language for Apple’s software such as macOS, iOS, etc. before Apple moved to Swift language. So this transition is reflected in the popularity of both languages, i.e. there is a fall in popularity for Objective-C and the popularity of Swift is rising. So, again if someone wants to be a developer for Apple’s products then Swift should be the language of choice.

This is image title

Observations:

Swift

Swift has replaced the Objective-C as the main language for Apple-related software and application. Since it is supported and promoted by Apple so there is an increase in popularity since its inception and as Apple is going to continue with it so if someone is looking for Apple-specific development platform then Swift is going to be a must-know programming language. This is mostly vendor and product-specific language with very less usage outside Apple’s eco-system.

Go

Go (Golang) is getting popularity as maintain, use and promoted by Google. The motivation of Go development was to address criticism of some of the popular languages and keeping the best of them in one place. Since 2017, Go is moving upward in popularity and with Google support, it is going to enjoy this in coming years. Google is also making Go as a primary language for new projects and replacing other languages with Go, this trend going to make useful and important to learn in coming years so one can pick Go as a new programming language.

Kotlin

Kotlin is being offered as an alternative of Java for Android development and again it is supported and promoted by Google so it is also picking up by developers and gaining popularity in recent years. So, with the growth of Android, support of Google and with clean and short syntax it is going to be a choice of Android application developers and is a good choice to learn for Android App developer. Kotlin going to be shine as a prominent programming environment for Android development.

Scala

Scala tries to establish as an alternative to Java but didn’t get very well among developers. It doesn’t have big support from any multi-national company, perceive as functional languages and dependency on JVM doesn’t provide much scope to rise in popularity. There could be steady growth but very slow and surely not a language to learn as a beginner.

Julia

Julia aims to bring the speed of ‘C’ and simplicity of Python but it is strange that didn’t found any popularity in Stackoverflow survey but gaining popularity among data science domain and being seen as a challenger for R and Python in long run. Surely, there will be growth in Julia but still, Python or R is better for job and growth.

C#

C# is the language for the .NET framework and developed by Microsoft. Its popularity is approx constant over past years and going to continue with a similar trend. This is vendor-specific language so one can pick this language if want to work in the Microsoft development environment. Recently, Microsoft has open-sourced the .NET so there would be some upward trend but again it is vendor-specific so there won’t be much affected.

Rust

Rust, Clojure, etc. are languages which have a user-base but not so popular so surely not going to have an upward swing in popularity.


A Picture Says a Thousand Words

To understand a clear trend and picture of top programming language growth let keep a picture of it by the various chart. The figure 1 and figure2 gives a very clear picture that in old language stack JavaScript is far ahead than others and credit goes to boom in web development, then C and C++ together competing very closer to Java. Python is moving upward in popularity and only language which popularity is constantly increasing in the last 5 years. New languages are getting popularity and most of them are supported by the multi-national company and bit IT giant like Microsoft, Google and Apple.

This is image title

This is image title

Loved and Wanted Languages

This is image title

This is image title

From above Table and Figure, few observations are very obvious, Love of Rust is growing in last five years whereas Swift is loosing love from developers and Python is in between these two and last two years have gain for Python. One more unique observation is that out of 5 loved languages 4 are from post 2000 group while only Python is the older language and Kotlin love started with addition of Kotlin for Android development post 2017.

This is image title

From above table, wish of developing in javascript and Python is growing in last years and this reflect in popularity and love for the language. There is a sharp decline in Java and this is due to the addition of Kotlin as alternative for Android app development and also change of policy by Oracle who own Java now.

This is image title

Technologies and Programming Languages

This is image title

In this figure, one can see that the largest cluster is for Web development and JavaScript and its various framework is dominating the cluster this is USP of JavaScript growth. The second-largest cluster is of Microsoft technologies and Python technologies which again clear the popularity and love for the language. Python cluster is linked with data science technologies which highlight the growth story of Python.

TIOBE Index

TIOBE index rank programming language based on search engine search result. The selection of search engines and programming language is defined in its page. The ratings are calculated by counting hits of the most popular search engines. The search query that is used is +” programming”. In TIOBE index Java is dominating the ranking in the last two decades where C is holding the 1st and 2nd rank for the last 30 years. Python has come a long way in the last two decades i.e. 24th in 1999 to 3rd in 2019. If someone merges the C and C++ then it would hold the 1st positions forever.

This is image title

In the new languages (post-2000), Rust moved up in ranking i.e. from 33rd to 28th, and Julia from 50th to 39th. It is also interesting to note that Kotlin doesn’t seem to come closer to the top 20.

Popularity of Programming Language (PYPL) Index

The PYPL index is created by analyzing how often language tutorials are searched on Google. The more a language tutorial is searched, the more popular the language is assumed to be. It is a leading indicator. The raw data comes from Google Trends.

Below Figure verifies that the top 3 languages are Python, Java, and JavaScript. C#, PHP, C/C++ also secure top position, this trend is again similar to stack-overflow, and TIOBE index.

This is image title

Above Figure indicates that among new programming Language i.e. post 2000 Kotlin, Go, Rust, and Julia is moving up in the ranking.

This is image title

Job Market and Salary

Salary depends upon the geographical area and demand of the products, a programming language based salary comparison is just a tool to predict or estimate the salary trend. We have summarized salary based on programming language from popular survey i.e. Dice salary survey 2018 and Stack-overflow survey 2018 and 2019.

This is image title

From the above table, it is very clear from both survey that Go/Golang is a very high paid job in the market and even stands 1st rank in a high paid job in stack-overflow 2019 survey and Dice Salary Survey 2018.

Language Predictability

So, as closing remarks, It is easy to predict a language trend but choosing only one language to learn is a really difficult choice and totally depend upon the individual choice and their future plans, for example, if you want to work in Web Development you can’t afford neglecting Javascript, if you want to work with Apple’s products you can’t neglect Swift now, if your taste is in system-level programming then C and C++ is your friend, Python makes you run faster in many domains and currently darling in Data science. You see each language takes you on a different journey. Choose your destination and then drive with the language of that path.

You may also like: Programming Languages - Trend Predictions in 2020 and Next Years.

We’ll love to know your opinion. What is the Best Programming Language for you?

Thank for reading! If you enjoyed this article, please share it with others who may enjoy it as well.!

Automating Crypto Portfolios Value with Trading Scripts using Python

Automating Crypto Portfolios Value with Trading Scripts using Python

A Python Script to Check Your Crypto Portfolio Value. Install Library. Import Library. API Keys. Create Client. Create User. Link Exchange Account. Get Asset Balances.

Instead of collecting more market data, let’s try something different. Most cryptocurrency users currently have funds located on an exchange. We can leverage the exchange’s APIs to access the asset balances and calculate their value without ever going to the exchange.

The following tutorial will take a step-by-step approach to detail how you can connect to an exchange account through APIs and access your balance data without ever logging into your exchanges.

Install Library

Before we can start writing our scripts and connecting to exchanges, let’s set up our development environment by first installing the libraries we need to complete our project.

pip install shrimpy-python

For this script, we will only need access to the Shrimpy Developer API Python library. This library makes it easy to connect to exchanges, manage assets, collect data, and build applications. The full APIs and their documentation can be found here.

Import Library

Once the library is installed, we can import it into our script to access all the features it provides.

import shrimpy

That’s it for libraries, so we’re ready to start constructing the meat of our script.

API Keys

There are 2 different sets of API keys we need in order to access our balance data on the exchange.

Exchange Account

The first set of API keys we need is the exchange API keys. These keys are found by going to your exchange of choice and creating a new set of API keys.

Our script will require the ability to access balance data, so make sure you have enabled the permissions on your exchange API keys for reading balance data from your exchange account. In this tutorial, you won’t need to enable the permissions for trading or withdrawals.

You can find a number of helpful tutorials on how to access exchange API keys here.

Once you’ve generated your API keys, save them as variables which we will use in the next steps to access your exchange account balances.

exchange_name = 'bittrex'
exchange_public_key = 'fbnnn1xzimjustkeyboardmashing8xn1t8'
exchange_secret_key = '09672v4n09xn0morekeyboardmashing947'

Note: Shrimpy supports 16 different exchanges. Use the following names when creating your exchange_name variable: binance, bittrex, bittrexinternational, kucoin, poloniex, bibox, huobi, hitbtc, bitstamp, bitfinex, coinbasepro, kraken, gemini, huobiglobal, bitmart, and okex.

Shrimpy Account

The second set of API keys we need to access our balance data on the exchange is the Shrimpy Developer API Master Keys.

To get your set of keys, sign up for your free Shrimpy account and select the option to “Create Api Master Key”.

When selecting the permissions for this key, ensure you have enabled the options for “User” and “Account”. These are required to link and access exchange accounts for users.

With your Shrimpy Developer API key in hand, assign it to variables which can be accessed in a future step.

shrimpy_public_key = '8x7138n1xzimjustkeyboardmashing8xn1t8jv5098'
shrimpy_secret_key = '771dc5n72v4n09xn0morekeyboardmashing9475c0294n50'
Create Client

Use the keys we generated in the previous step to create your Shrimpy client.

client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)
Create User

The Shrimpy APIs require exchange accounts to be connected to users. That way we can generate any number of users who manage multiple individual exchange accounts. This provides a built-in way to determine who owns which exchange account.

Let’s create our user who will be the one which gets linked to our exchange accounts.

create_user_response = client.create_user('Satoshi Nakamoto')
user_id = create_user_response['id']
Link Exchange Account

Once the user is created, linking an exchange to the user is straight forward. Simply specify the user, exchange name, and the API keys for that exchange.

link_account_response = client.link_account(
    user_id,
    exchange_name,
    exchange_public_key,
    exchange_secret_key
)

account_id = link_account_response['id']

As soon as the exchange account is linked, Shrimpy will automatically begin collecting data from the exchange regarding the account’s balances. This process can take a moment, so let’s take 5 seconds before going on to the next step.

Note: You can link up to 20 exchange accounts to a single user. That means if you have accounts with Bittrex, Binance, KuCoin, BitStamp, Kraken, and Coinbase Pro (and more) you can link them all to a single user.

Get Asset Balances

We’re almost done. Let’s grab the exchange account balance from Shrimpy. Simply call the library and ask for the balance data for a specific user and account.

The response to this call will return every asset we own, the balances for these assets, and the dollar values.

balance = client.get_balance(user_id, account_id)
holdings = balance['balances']
Print Out Balances

The final step is to calculate the balances and display them. In this case, we will just print them out, but you can certainly do anything you wish with the balances.

We will iterate over each asset in the returned list and display the asset and the value of our asset holdings.

total = 0

for asset in holdings:
    print(asset['symbol'] + ' ' + str(asset['usdValue']))
    total += asset['usdValue']

print("Total" + ' $' + str(total))

That’s it! You have successfully connected to your exchange account and accessed your balances without logging into the exchange through the UI.

Whenever you wish to update your balances, you can simply request the latest balances from Shrimpy again by passing in your user ID and account ID. Shrimpy will handle the rest by accessing your linked exchange account and collecting the balance data. You DO NOT need to re-link your keys every time or create a new user each time. Those steps are a one-time thing.

Putting it All Together

This is image title

The first time you want to connect to an exchange and access the balance data for the assets you hold on the exchange, you can run the entire script here. Each subsequent time, you only need to run the portion which collects the balance data

This script can also easily be modified to link multiple exchanges, so you can access your balances across every exchange for which you have an account.

First Run

Fill in the information for your Shrimpy Master API keys and Exchange Keys to run this script. I’ve used fake keys for this tutorial.

# import required libraries
import shrimpy
import time

# assign your Shrimpy Master API keys for later use
shrimpy_public_key = '8x7138n1xzimjustkeyboardmashing8xn1t8jv5098'
shrimpy_secret_key = '771dc5n72v4n09xn0morekeyboardmashing9475c0294n50'

# assign your exchange keys for which you wish to access the balance data
exchange_name = "bittrex"
exchange_public_key = 'fbnnn1xzimjustkeyboardmashing8xn1t8'
exchange_secret_key = '09672v4n09xn0morekeyboardmashing947'

# create the Shrimpy client
client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

# create a user which will be linked to our exchange
create_user_response = client.create_user('The Shrimp Master')
user_id = create_user_response['id']

# link our first exchange so we can access balance data
link_account_response = client.link_account(
    user_id,
    exchange_name,
    exchange_public_key,
    exchange_secret_key
)

account_id = link_account_response['id']

# wait while Shrimpy collects data for the exchange account
# only required the first time linking
time.sleep(5)

# collect asset balances on the exchange
balance = client.get_balance(user_id, account_id)
holdings = balance['balances']

total = 0

# calculate and print balances for each asset. 
for asset in holdings:
    print(asset['symbol'] + ' $' + str(round(asset['usdValue'], 2)))
    total += asset['usdValue']

print("Total" + ' $' + str(round(total, 2)))

Subsequent Runs

After running the initial script, you can simply access your balances at any time by running this second script.

Notice this script removed the steps to create a user, link an exchange account, and sleep for a few seconds.

Shrimpy will automatically remember this information for you, so all you need to do is connect to the Shrimpy APIs again, tell Shrimpy what account you want balance data for, and print out the balance data which is returned in the response.

# import required libraries
import shrimpy

# input your user and account IDs
user_id = 'dc12349b-1234-12k4-123n12n12nnf'
account_id = 12345

# assign your Shrimpy Master API keys for later use
shrimpy_public_key = '8x7138n1xzimjustkeyboardmashing8xn1t8jv5098'
shrimpy_secret_key = '771dc5n72v4n09xn0morekeyboardmashing9475c0294n50'

# create the Shrimpy client
client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

# collect asset balances on the exchange
balance = client.get_balance(user_id, account_id)
holdings = balance['balances']

total = 0

# calculate and print balances for each asset. 
for asset in holdings:
    print(asset['symbol'] + ' $' + str(asset['usdValue']))
    total += asset['usdValue']

print("Total" + ' $' + str(total))
Crypto Developers

The Shrimpy community is becoming the largest network of builders. People who are looking to push the bounds of what’s possible with crypto application development, trading, and market data analysis.

Find the full Python and Node libraries here:

Node

Python

We would love to hear more about what you’re building, so don’t hesitate to reach out and share your story!

Thank for reading! Please share if you liked it!

How to Write Node.js Addons using C++ and N-API for Beginners

How to Write Node.js Addons using C++ and N-API for Beginners

This article will only focus on C++ addons for NodeJs using N-API. For this we will use the node-addon-api package from the N-API team which contains header-only C++ wrapper classes for the N-API. I suggest you follow through by coding live as you read.

Node.js Addons are dynamically-linked shared objects, written in C++, that can be loaded into Node.js using the [require()](https://nodejs.org/api/modules.html#modules_require) function, and used just as if they were an ordinary Node.js module. They are used primarily to provide an interface between JavaScript running in Node.js and C/C++ libraries.

There can be many reasons to write nodejs addons:
1. You may want to access some native apis that is difficult using JS alone.
2. You may want to integrate a third party library written in C/C++ and use it directly in NodeJs.
3. You may want to rewrite some of the modules in C++ for performance reasons.
Whatever your reason is, this blog focuses on explaining the N-API and how you can use it to build C/C++ based NodeJS addons.

The complete source code from this blog is available at github

So, If you are not interested in reading through, you can directly take a look at the code there also.

What is N-API?

N-API (pronounced N as in the letter, followed by API) is an API for building native Addons. It is independent from the underlying JavaScript runtime (ex V8) and is maintained as part of Node.js itself. This API will be Application Binary Interface (ABI) stable across versions of Node.js. It is intended to insulate Addons from changes in the underlying JavaScript engine and allow modules compiled for one version to run on later versions of Node.js without recompilation.

In essence , N-API can be used to build NodeJS Addons using C or C++. And the addons built using this would not break across different implementations or versions of NodeJS.

N-API is a stable API as of Node v10 (latest stable release when writing this article). N-API was experimental in Node v8 and v9.

To see a demo of N-API in action watch this youtube video:

This article will only focus on C++ addons for NodeJs using N-API. For this we will use the node-addon-api (github) package from the N-API team which contains header-only C++ wrapper classes for the N-API ( basically it provides C++ object model and exception handling semantics with low overhead).

Since this blog post covers very minimal theory, I suggest you follow through by coding live as you read.

Lets Code: Boilerplate setup

Create a basic node project test-addon

mkdir test-addon
cd test-addon
git init
npm init

Install the dependencies:

npm install node-gyp --save-dev
npm install node-addon-api

node-gyp is the toolchain to compile the addons.
node-addon-api is a helper project as described earlier that will make writing C++ addons easier.

In the package.json set the attribute gypfile:true and setup the following files as below:

node_modules
*.log
build
{
    "targets": [{
        "target_name": "testaddon",
        "cflags!": [ "-fno-exceptions" ],
        "cflags_cc!": [ "-fno-exceptions" ],
        "sources": [
            "cppsrc/main.cpp"
        ],
        'include_dirs': [
            "<[email protected](node -p \"require('node-addon-api').include\")"
        ],
        'libraries': [],
        'dependencies': [
            "<!(node -p \"require('node-addon-api').gyp\")"
        ],
        'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ]
    }]
}
{
  "name": "test-addon",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "gypfile": true,
  "scripts": {
    "build": "node-gyp rebuild",
    "clean": "node-gyp clean"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "node-gyp": "^3.7.0"
  },
  "dependencies": {
    "node-addon-api": "^1.3.0"
  }
}

binding.gyp file contains all the files that need to be compiled and all the include files / libraries that the project will be using. If you notice we have added cppsrc/main.cpp file as our source file.

Also our package.json mentions a index.js file as its main file.

Lets create both of them :

//index.js
const testAddon = require('./build/Release/testaddon.node');

module.exports = testAddon;
/* cppsrc/main.cpp */
#include <napi.h>

Napi::Object InitAll(Napi::Env env, Napi::Object exports) {
  return exports;
}

NODE_API_MODULE(testaddon, InitAll)

The base boilerplate is complete. Lets try and build our addon

type npm run build

You should have an output similar to this:

npm run build
> [email protected] build /Users/atulr/Projects/Hobby/test-addon
> node-gyp rebuild
SOLINK_MODULE(target) Release/nothing.node
  CXX(target) Release/obj.target/testaddon/cppsrc/main.o
  SOLINK_MODULE(target) Release/testaddon.node

Wohoo ! compilation was successful. Lets run it !

Type node index.js . Sadly you will not get any output here.

Ideally you should use a debugger tool to debug and see what the contents of testAddon is but for demo here lets just add a console.log like this:

//index.js
const testAddon = require('./build/Release/testaddon.node');
console.log('addon',testAddon);
module.exports = testAddon;

Now run index.js again. You should see an output like this :

node index.js
addon {}

Awesome !! Now we have a working setup to start with.

Before we go ahead, lets take a look at cppsrc/main.cpp in detail:
1. #include<napi.h> includes the napi header file so that we can access all the helper macros, classes and functions.
2. NODE_API_MODULE is a macro that accepts modulename and registerfunction as parameters.
3. In our case registerfunction is InitAll and it takes two parameters which are passed by N-API. First parameter env is the context that needs to be passed on to most N-API function and exports is the object used to set the exported functions and classes via N-API.

The source code documentation for NODE_API_MODULE says:

/**
* This code defines the entry-point for the Node addon, it tells Node where to go
* once the library has been loaded into active memory. The first argument must
* match the "target" in our *binding.gyp*. Using NODE_GYP_MODULE_NAME ensures
* that the argument will be correct, as long as the module is built with
* node-gyp (which is the usual way of building modules). The second argument
* points to the function to invoke. The function must not be namespaced.
*/
NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)

To read in more depth you can visit the documentation of node-gyp here

Exporting a Hello World C++ function using N-API

Now lets add an example of exporting a C++ function to NodeJS.

Lets take an example of a simple function

std::string hello(){
  return "Hello World";
}

Lets try to export hello to Javascript side with our addon.

Create the following files: cppsrc/Samples/functionexample.h

#include <napi.h>
namespace functionexample {
  std::string hello();
  Napi::String HelloWrapped(const Napi::CallbackInfo& info);
  Napi::Object Init(Napi::Env env, Napi::Object exports);
}

The corresponding cppsrc/Samples/functionexample.cpp

#include "functionexample.h"
std::string functionexample::hello(){
  return "Hello World";
}
Napi::String functionexample::HelloWrapped(const Napi::CallbackInfo& info) 
{
  Napi::Env env = info.Env();
  Napi::String returnValue = Napi::String::New(env, functionexample::hello());
  
  return returnValue;
}
Napi::Object functionexample::Init(Napi::Env env, Napi::Object exports) 
{
  exports.Set(
"hello", Napi::Function::New(env, functionexample::HelloWrapped)
  );
 
  return exports;
}

Wow ! Looks like a lot. But if you look closely, its not as complex as it looks. For every function in C++ we want to export we will basically create a NAPI wrapped function (HelloWrapped in this example) and add it to the exports object using Init.

Lets take some time to understand HelloWrapped function. Every wrapped function that needs to be exported to JS should have input params/return value from the Napi namespace.
Every wrapped function takes in CallbackInfo as the input parameter. This contains things like the context and the input parameters that needs to be passed to the function.

Initfunction is used to just set the export key as hello with corresponding wrapped function HelloWrapped .

Now we need to make our node-gyp know that we have added extra c++ files. So make the following changes to binding.gyp,main.cpp and index.js

diff --git a/binding.gyp b/binding.gyp
index 23b9976..2d188af 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -4,7 +4,8 @@
         "cflags!": [ "-fno-exceptions" ],
         "cflags_cc!": [ "-fno-exceptions" ],
         "sources": [
-            "cppsrc/main.cpp"
+            "cppsrc/main.cpp",
+            "cppsrc/Samples/functionexample.cpp"
         ],
         'include_dirs': [
             "<[email protected](node -p \"require('node-addon-api').include\")"



diff --git a/cppsrc/main.cpp b/cppsrc/main.cpp
index f016c4e..f62ed77 100644
--- a/cppsrc/main.cpp
+++ b/cppsrc/main.cpp
@@ -1,7 +1,8 @@
 #include <napi.h>
+#include "Samples/functionexample.h"
 
 Napi::Object InitAll(Napi::Env env, Napi::Object exports) {
-  return exports;
+  return functionexample::Init(env, exports);
 }
 
 NODE_API_MODULE(testaddon, InitAll)



diff --git a/index.js b/index.js
index 65f955e..e91b98f 100644
--- a/index.js
+++ b/index.js
@@ -1,3 +1,4 @@
 const testAddon = require('./build/Release/testaddon.node');
 console.log('addon',testAddon);
+console.log(testAddon.hello());
 module.exports = testAddon;

Remember : Any change in c++ src files will need recompilation before you can use the changes in NodeJS. So make sure you run npm run build again after changing c++ files.

Also when you add a new header file/cpp file :
1. Add it to binding.gyp
2. Add it to main.cpp
3. Do npm rebuild and access it via JS.

Now run it ! node index.js .You should see the output as follows:

node index.js
addon { hello: [Function] }
Hello World

Voila ! Now we have a hello world from C++ world into JS World!

How about functions with input parameters ?

Lets say that the function that we want to export has both input and output params. For example:

int add(int a, int b){
  return a + b;
}

To add the function we will make the following changes:

diff --git a/cppsrc/Samples/functionexample.cpp b/cppsrc/Samples/functionexample.cpp
index 0bd9bc2..37b7eb9 100644
--- a/cppsrc/Samples/functionexample.cpp
+++ b/cppsrc/Samples/functionexample.cpp
@@ -4,13 +4,33 @@ std::string functionexample::hello(){
     return "Hello World";
 }
 
+int functionexample::add(int a, int b){
+  return a + b;
+}
+
 Napi::String functionexample::HelloWrapped(const Napi::CallbackInfo& info) {
     Napi::Env env = info.Env();
     Napi::String returnValue = Napi::String::New(env, functionexample::hello());
     return returnValue;
 }
 
+
+Napi::Number functionexample::AddWrapped(const Napi::CallbackInfo& info) {
+    Napi::Env env = info.Env();
+    if (info.Length() < 2 || !info[0].IsNumber() || !info[1].IsNumber()) {
+        Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
+    } 
+
+    Napi::Number first = info[0].As<Napi::Number>();
+    Napi::Number second = info[1].As<Napi::Number>();
+
+    int returnValue = functionexample::add(first.Int32Value(), second.Int32Value());
+    
+    return Napi::Number::New(env, returnValue);
+}
+
 Napi::Object functionexample::Init(Napi::Env env, Napi::Object exports) {
     exports.Set("hello", Napi::Function::New(env, functionexample::HelloWrapped));
+    exports.Set("add", Napi::Function::New(env, functionexample::AddWrapped));
     return exports;
 }
 
 
diff --git a/cppsrc/Samples/functionexample.h b/cppsrc/Samples/functionexample.h
index 44563aa..e15aa7b 100644
--- a/cppsrc/Samples/functionexample.h
+++ b/cppsrc/Samples/functionexample.h
@@ -4,6 +4,10 @@ namespace functionexample {
 
     std::string hello();
     Napi::String HelloWrapped(const Napi::CallbackInfo& info);
-    Napi::Object Init(Napi::Env env, Napi::Object exports);
 
+    int add(int a, int b);
+    Napi::Number AddWrapped(const Napi::CallbackInfo& info);
+
+    Napi::Object Init(Napi::Env env, Napi::Object exports);
+    
 }
 
 
diff --git a/index.js b/index.js
index e91b98f..72860f8 100644
--- a/index.js
+++ b/index.js
@@ -1,4 +1,5 @@
 const testAddon = require('./build/Release/testaddon.node');
 console.log('addon',testAddon);
-console.log(testAddon.hello());
+console.log('hello ', testAddon.hello());
+console.log('add ', testAddon.add(5, 10));
 module.exports = testAddon;

Explanation:
1. We added a simple add function.
2. We added the wrapper for the add function : AddWrapped which is used to interface the add function with N-API.
3. We added the key add to export the AddWrapped function to the JS.

I believe the example is fairly straightforward and self explanatory. If more explanation is needed, let me know in the comments and I ll add more details here. Passing complex references and objects to the functions will be covered in the later sections below.

Output:

node index.js
addon { hello: [Function], add: [Function] }
hello  Hello World
add  15

Awesome !!

Exporting a Hello World C++ Class using N-API

Lets create a simple C++ class that stores a double value. The member functions are pretty self explanatory.

/* cppsrc/Samples/actualclass.cpp */

#include "actualclass.h"

ActualClass::ActualClass(double value){
    this->value_ = value;
}

double ActualClass::getValue()
{
  return this->value_;
}

double ActualClass::add(double toAdd)
{
  this->value_ += toAdd;
  return this->value_;
}
/* cppsrc/Samples/actualclass.h */

class ActualClass {
 public:
  ActualClass(double value); //constructor
  double getValue(); //getter for the value
  double add(double toAdd); //adds the toAdd value to the value_
 private:
  double value_;
};

I believe the above code is pretty straightforward and self explanatory.

To export this class to JS side we will need to create a wrapper class. Lets name the wrapper class as ClassExample .

Create the wrapper Class as follows: Please look at the classexample.h first and try to grasp the intent of the Wrapper class before going to the implementation.

/* cppsrc/Samples/classexample.cpp */

#include "classexample.h"

Napi::FunctionReference ClassExample::constructor;

Napi::Object ClassExample::Init(Napi::Env env, Napi::Object exports) {
  Napi::HandleScope scope(env);

  Napi::Function func = DefineClass(env, "ClassExample", {
    InstanceMethod("add", &ClassExample::Add),
    InstanceMethod("getValue", &ClassExample::GetValue),
  });

  constructor = Napi::Persistent(func);
  constructor.SuppressDestruct();

  exports.Set("ClassExample", func);
  return exports;
}

ClassExample::ClassExample(const Napi::CallbackInfo& info) : Napi::ObjectWrap<ClassExample>(info)  {
  Napi::Env env = info.Env();
  Napi::HandleScope scope(env);

  int length = info.Length();
  if (length != 1 || !info[0].IsNumber()) {
    Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
  }

  Napi::Number value = info[0].As<Napi::Number>();
  this->actualClass_ = new ActualClass(value.DoubleValue());
}

Napi::Value ClassExample::GetValue(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  Napi::HandleScope scope(env);

  double num = this->actualClass_->getValue();
  return Napi::Number::New(env, num);
}


Napi::Value ClassExample::Add(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  Napi::HandleScope scope(env);

  if (  info.Length() != 1 || !info[0].IsNumber()) {
    Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
  }

  Napi::Number toAdd = info[0].As<Napi::Number>();
  double answer = this->actualClass_->add(toAdd.DoubleValue());

  return Napi::Number::New(info.Env(), answer);
}
/* cppsrc/Samples/classexample.h */

#include <napi.h>
#include "actualclass.h"

class ClassExample : public Napi::ObjectWrap<ClassExample> {
 public:
  static Napi::Object Init(Napi::Env env, Napi::Object exports); //Init function for setting the export key to JS
  ClassExample(const Napi::CallbackInfo& info); //Constructor to initialise

 private:
  static Napi::FunctionReference constructor; //reference to store the class definition that needs to be exported to JS
  Napi::Value GetValue(const Napi::CallbackInfo& info); //wrapped getValue function 
  Napi::Value Add(const Napi::CallbackInfo& info); //wrapped add function
  ActualClass *actualClass_; //internal instance of actualclass used to perform actual operations.
};

Lets take a good look at the header file of our wrapper class classexample.h:

As mentioned before, Anything that needs to be exported to JS world needs to be wrapped with N-API. Hence:
1. First step is to create a wrapper class which extends Napi::ObjectWrap<ClassExample> .
2. Just like in case of functions we need a Init method to set the export key.
3. Except the static Napi::FunctionReference constructor; rest all the methods are self explanatory.

Now, lets take a look at the actual implementation classexample.cpp .
1. ClassExample::Init function is responsible to create and set the export key. Here we will export the class as ClassExample to the JS side.

Important part here is :

Napi::Function func = DefineClass(env, "ClassExample", 
{
  InstanceMethod("add", &ClassExample::Add),
  InstanceMethod("getValue", &ClassExample::GetValue),
});

func is used to define the class that will be exported to JS and then the func is assigned to constructor which is a static function reference in c++. This is where the earlier defined static Napi::FunctionReference constructor; comes in. Similar to InstanceMethod there are various methods defined in NAPI to export different types of class methods. For example: Static methods can be exported using StaticMethod .

If you are wondering what env is :

env is the environment that represent an independent instance of the JavaScript runtime,

I think of it as the js context that needs to be passed around to most NAPI functions as the first argument.

2. Now lets see the implementation of ClassExample::Add function.

Napi::Value ClassExample::Add(const Napi::CallbackInfo& info) 
{
  Napi::Env env = info.Env();
  Napi::HandleScope scope(env);
  
  if (info.Length() != 1 || !info[0].IsNumber()) {
     Napi::TypeError::New(env, "Numberexpected").ThrowAsJavaScriptException();
  }
  Napi::Number toAdd = info[0].As<Napi::Number>();
  double answer = this->actualClass_->add(toAdd.DoubleValue());
  return Napi::Number::New(info.Env(), answer);
}

Here input params are checked first using info from env. Now, to read a value from JS side we read it like info[0].As<Napi::Number>();. Since C++ is a strongly typed language and JS is not. We have to convert every value that we get from JS side to its appropriate type. After we convert the value we simply call the internal actualClass
instance and return the value. But since the value is a double we need to wrap it with a Napi::Number instance so that it can be passed to the JS side.

We are not done yet. Remember we need to now add entries to tell the compiler to compile the new source files we added.

diff --git a/binding.gyp b/binding.gyp
index 2d188af..031bf18 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -5,7 +5,9 @@
         "cflags_cc!": [ "-fno-exceptions" ],
         "sources": [
             "cppsrc/main.cpp",
-            "cppsrc/Samples/functionexample.cpp"
+            "cppsrc/Samples/functionexample.cpp",
+            "cppsrc/Samples/actualclass.cpp",
+            "cppsrc/Samples/classexample.cpp"
         ],
         'include_dirs': [
             "<[email protected](node -p \"require('node-addon-api').include\")"
             
             
diff --git a/cppsrc/main.cpp b/cppsrc/main.cpp
index f62ed77..2b739d3 100644
--- a/cppsrc/main.cpp
+++ b/cppsrc/main.cpp
@@ -1,8 +1,10 @@
 #include <napi.h>
 #include "Samples/functionexample.h"
+#include "Samples/classexample.h"
 
 Napi::Object InitAll(Napi::Env env, Napi::Object exports) {
-  return functionexample::Init(env, exports);
+  functionexample::Init(env, exports);
+  return ClassExample::Init(env, exports);
 }
 
-NODE_API_MODULE(testaddon, InitAll)
+NODE_API_MODULE(NODE_GYP_MODULE_NAME, InitAll)


diff --git a/index.js b/index.js
index 72860f8..d849e0e 100644
--- a/index.js
+++ b/index.js
@@ -2,4 +2,9 @@ const testAddon = require('./build/Release/testaddon.node');
 console.log('addon',testAddon);
 console.log('hello ', testAddon.hello());
 console.log('add ', testAddon.add(5, 10));
+
+
+const classInstance = new testAddon.ClassExample(4.3);
+console.log('Testing class initial value : ',classInstance.getValue());
+console.log('After adding 3.3 : ',classInstance.add(3.3));
 module.exports = testAddon;

Make the above changes and run npm run build , followed by node index.js .

Notice that we have to both classexample.cpp and actualclass.cpp in the binding.gyp . The reason is that both classes are written by us. If you have a thrid party library c++ file. Then you would need to include the precompiled dynamic library in the libraries section of binding.gyp instead.

Output:

node index.js
addon { hello: [Function],
  add: [Function],
  ClassExample: [Function: ClassExample] }
hello  Hello World
add  15
Testing class initial value :  4.3
After adding 3.3 :  7.6

That was easy ! Isn’t it ?

This should be enough for most use cases. But if you need to know how to send class instances back/any complex object between JS and C++ read on.

Sending complex js objects to the C++ world

Lets say we have a use case like below:

const prevInstance = new testAddon.ClassExample(4.3);
console.log('Initial value : ', prevInstance.getValue());
console.log('After adding 3.3 : ', prevInstance.add(3.3));
const newFromExisting = new testAddon.ClassExample(prevInstance);
console.log('Testing class initial value for derived instance');
console.log(newFromExisting.getValue()); 

Here, we have an instance of ClassExample in prevInstance .

And we want a new instance newFromExisting which has same value of prevInstance. For that, we want to pass the existing instance prevInstance to the constructor of ClassExample . Since, prevInstance is not a primitive value like int, double etc. The expected output of the last console.log should be 7.6 .

Lets see how we can do that:

diff --git a/cppsrc/Samples/classexample.cpp b/cppsrc/Samples/classexample.cpp
index 8dfa3cc..834f7ea 100644
--- a/cppsrc/Samples/classexample.cpp
+++ b/cppsrc/Samples/classexample.cpp
@@ -22,8 +22,17 @@ ClassExample::ClassExample(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Cl
   Napi::HandleScope scope(env);
 
   int length = info.Length();
-  if (length != 1 || !info[0].IsNumber()) {
-    Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
+  
+  if (length != 1) {
+    Napi::TypeError::New(env, "Only one argument expected").ThrowAsJavaScriptException();
+  }
+
+  if(!info[0].IsNumber()){
+    Napi::Object object_parent = info[0].As<Napi::Object>();
+    ClassExample* example_parent = Napi::ObjectWrap<ClassExample>::Unwrap(object_parent);
+    ActualClass* parent_actual_class_instance = example_parent->GetInternalInstance();
+    this->actualClass_ = new ActualClass(parent_actual_class_instance->getValue());
+    return;
   }
 
   Napi::Number value = info[0].As<Napi::Number>();
@@ -51,4 +60,8 @@ Napi::Value ClassExample::Add(const Napi::CallbackInfo& info) {
   double answer = this->actualClass_->add(toAdd.DoubleValue());
 
   return Napi::Number::New(info.Env(), answer);
+}
+
+ActualClass* ClassExample::GetInternalInstance() {
+  return this->actualClass_;
 }




diff --git a/cppsrc/Samples/classexample.h b/cppsrc/Samples/classexample.h
index 1f0cf69..7f6237f 100644
--- a/cppsrc/Samples/classexample.h
+++ b/cppsrc/Samples/classexample.h
@@ -5,6 +5,7 @@ class ClassExample : public Napi::ObjectWrap<ClassExample> {
  public:
   static Napi::Object Init(Napi::Env env, Napi::Object exports);
   ClassExample(const Napi::CallbackInfo& info);
+  ActualClass* GetInternalInstance();
 
  private:
   static Napi::FunctionReference constructor;
   
   
   
diff --git a/index.js b/index.js
index d849e0e..efce991 100644
--- a/index.js
+++ b/index.js
@@ -3,8 +3,13 @@ console.log('addon',testAddon);
 console.log('hello ', testAddon.hello());
 console.log('add ', testAddon.add(5, 10));
 
+const prevInstance = new testAddon.ClassExample(4.3);
+console.log('Initial value : ', prevInstance.getValue());
+console.log('After adding 3.3 : ', prevInstance.add(3.3));
+
+const newFromExisting = new testAddon.ClassExample(prevInstance);
+
+console.log('Testing class initial value for derived instance');
+console.log(newFromExisting.getValue());
 
-const classInstance = new testAddon.ClassExample(4.3);
-console.log('Testing class initial value : ',classInstance.getValue());
-console.log('After adding 3.3 : ',classInstance.add(3.3));
 module.exports = testAddon;

In the above changes.

  1. First thing we did is change the implementation of ClassExample::ClassExample so that it can take an argument which is not a number.

  2. Now we assume that if the argument is not a number, it must be an instance of the ClassExample itself. So to get the class instance from the JS side we need to UnWrap the object.

Napi::Object object_parent = info[0].As<Napi::Object>();
ClassExample* example_parent = Napi::ObjectWrap<ClassExample>::Unwrap(object_parent);
ActualClass* parent_actual_class_instance = example_parent->GetInternalInstance();
this->actualClass_ = new ActualClass(parent_actual_class_instance->getValue());
return;

So we Unwrap the object using the unwrap method and then to get to the actualClass instance of in the ClassExample we defined an additional method called GetInternalInstance which simply returns the internal actualClass reference. Finally, we take the value from actualClass instance and create new actualClass instance for the new ClassExample instance.

Lets again run it! npm run build and then node index.js

Output:

node index.js
Initial value :  4.3
After adding 3.3 :  7.6
Testing class initial value for derived instance
7.6

!! We got the expected 7.6 Wohoo !!

The entire source code is available at github

I hope this helps someone trying to use N-API and create C++/C addons for NodeJS.

Thank for reading!