Skip to content

Commit

Permalink
feat: add support for javascript binding
Browse files Browse the repository at this point in the history
  • Loading branch information
cryptochassis committed Aug 11, 2023
1 parent 2258a6b commit cf32f73
Show file tree
Hide file tree
Showing 28 changed files with 583 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,11 @@ jobs:
if ("$ENV{GITHUB_EVENT_NAME}" STREQUAL "push")
set(ENV{CMAKE_BUILD_TYPE} "Release")
set(ENV{DOTNET_BUILD_CONFIGURATION} "Release")
set(ENV{NODE_GYP_BUILD_MODE} "release")
else()
set(ENV{CMAKE_BUILD_TYPE} "Debug")
set(ENV{DOTNET_BUILD_CONFIGURATION} "Debug")
set(ENV{NODE_GYP_BUILD_MODE} "debug")
endif()
execute_process(
Expand Down Expand Up @@ -233,11 +235,14 @@ jobs:
-DBUILD_PYTHON=ON
-DBUILD_JAVA=ON
-DBUILD_CSHARP=ON
-DBUILD_GO=ON
-DBUILD_JAVASCRIPT=ON
-DBUILD_TEST=ON
-S binding
-B binding/build
-D CMAKE_BUILD_TYPE=$ENV{CMAKE_BUILD_TYPE}
-D DOTNET_BUILD_CONFIGURATION=$ENV{DOTNET_BUILD_CONFIGURATION}
-D DNODE_GYP_BUILD_MODE=$ENV{NODE_GYP_BUILD_MODE}
-G Ninja
-D CMAKE_MAKE_PROGRAM=ninja
# -D CMAKE_C_COMPILER_LAUNCHER=ccache
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,5 @@ docs/_build/
.venv/
target/
obj/
node_modules/
package-lock.json
2 changes: 1 addition & 1 deletion binding/csharp/example/fix_simple/MainProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class MyEventHandler : ccapi.EventHandler {
param.Add(new ccapi.PairIntString(40, "2"));
param.Add(new ccapi.PairIntString(59, "1"));
request.AppendParamFix(param);
session.SendRequest(request);
session.SendRequestByFix(request);
}
} else if (event_.GetType_() == ccapi.Event.Type.FIX) {
System.Console.WriteLine(string.Format("Received an event of type FIX:\n{0}", event_.ToStringPretty(2, 2)));
Expand Down
2 changes: 1 addition & 1 deletion binding/go/example/fix_simple/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (*MyEventHandler) ProcessEvent(event ccapi.Event, session ccapi.Session) bo
param.Add(aParam)
}
request.AppendParamFix(param)
session.SendRequest(request)
session.SendRequestByFix(request)
}
} else if event.GetType() == ccapi.EventType_FIX {
fmt.Printf("Received an event of type FIX:\n%s\n", event.ToStringPretty(2, 2))
Expand Down
18 changes: 9 additions & 9 deletions binding/go/example/market_data_simple_subscription/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ func (*MyEventHandler) ProcessEvent(event ccapi.Event, session ccapi.Session) bo
elementList := message.GetElementList()
for j := 0; j < int(elementList.Size()); j++ {
element := elementList.Get(j)
nameValueMap := element.GetNameValueMap()
if nameValueMap.Has_key("BID_PRICE") {
fmt.Printf(" %s = %s\n", "BID_PRICE", nameValueMap.Get("BID_PRICE"))
elementNameValueMap := element.GetNameValueMap()
if elementNameValueMap.Has_key("BID_PRICE") {
fmt.Printf(" BID_PRICE = %s\n", elementNameValueMap.Get("BID_PRICE"))
}
if nameValueMap.Has_key("BID_SIZE") {
fmt.Printf(" %s = %s\n", "BID_SIZE", nameValueMap.Get("BID_SIZE"))
if elementNameValueMap.Has_key("BID_SIZE") {
fmt.Printf(" BID_SIZE = %s\n", elementNameValueMap.Get("BID_SIZE"))
}
if nameValueMap.Has_key("ASK_PRICE") {
fmt.Printf(" %s = %s\n", "ASK_PRICE", nameValueMap.Get("ASK_PRICE"))
if elementNameValueMap.Has_key("ASK_PRICE") {
fmt.Printf(" ASK_PRICE = %s\n", elementNameValueMap.Get("ASK_PRICE"))
}
if nameValueMap.Has_key("ASK_SIZE") {
fmt.Printf(" %s = %s\n", "ASK_SIZE", nameValueMap.Get("ASK_SIZE"))
if elementNameValueMap.Has_key("ASK_SIZE") {
fmt.Printf(" ASK_SIZE = %s\n", elementNameValueMap.Get("ASK_SIZE"))
}
}
}
Expand Down
7 changes: 0 additions & 7 deletions binding/go/test/go.mod

This file was deleted.

2 changes: 1 addition & 1 deletion binding/java/example/fix_simple/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public boolean processEvent(Event event, Session session) {
param.add(new PairIntString(40, "2"));
param.add(new PairIntString(59, "1"));
request.appendParamFix(param);
session.sendRequest(request);
session.sendRequestByFix(request);
}
} else if (event.getType() == Event.Type.FIX) {
System.out.println(String.format("Received an event of type FIX:\n%s", event.toStringPretty(2, 2)));
Expand Down
130 changes: 130 additions & 0 deletions binding/javascript/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
set(NAME binding_${LANG})
project(${NAME})
set(SWIG_TARGET_NAME ccapi_${NAME})

# Find javascript cli
find_program(NODE_EXECUTABLE NAMES node REQUIRED)
if(NOT NODE_EXECUTABLE)
message(FATAL_ERROR "Check for node Program: not found")
else()
message(STATUS "Found node Program: ${NODE_EXECUTABLE}")
endif()

execute_process(
COMMAND ${NODE_EXECUTABLE} -v
OUTPUT_VARIABLE NODE_EXECUTABLE_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
message(STATUS "node version: ${NODE_EXECUTABLE_VERSION}")

find_program(NODE_GYP_EXECUTABLE NAMES node-gyp REQUIRED)
if(NOT NODE_GYP_EXECUTABLE)
message(FATAL_ERROR "Check for node-gyp Program: not found")
else()
message(STATUS "Found node-gyp Program: ${NODE_EXECUTABLE}")
endif()

execute_process(
COMMAND ${NODE_GYP_EXECUTABLE} -v
OUTPUT_VARIABLE NODE_GYP_EXECUTABLE_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
message(STATUS "node-gyp version: ${NODE_GYP_EXECUTABLE_VERSION}")

file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${SWIG_TARGET_NAME})
set(BINDING_GYP_CFLAGS_CC_LIST "")
set(BINDING_GYP_LDFLAGS_LIST "")
set(BINDING_GYP_DEFINES_LIST "")
list(APPEND BINDING_GYP_CFLAGS_CC_LIST -std=c++17 -fPIC -Wno-deprecated-declarations)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
list(APPEND BINDING_GYP_CFLAGS_CC_LIST -g)
list(APPEND BINDING_GYP_LDFLAGS_LIST -g)
else()
list(APPEND BINDING_GYP_CFLAGS_CC_LIST -O3 -DNDEBUG)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
list(APPEND BINDING_GYP_CFLAGS_CC_LIST -pthread)
endif()
list(APPEND BINDING_GYP_DEFINES_LIST CCAPI_ENABLE_SERVICE_MARKET_DATA CCAPI_ENABLE_SERVICE_EXECUTION_MANAGEMENT CCAPI_ENABLE_SERVICE_FIX CCAPI_ENABLE_EXCHANGE_COINBASE CCAPI_ENABLE_EXCHANGE_GEMINI CCAPI_ENABLE_EXCHANGE_KRAKEN CCAPI_ENABLE_EXCHANGE_KRAKEN_FUTURES CCAPI_ENABLE_EXCHANGE_BITSTAMP CCAPI_ENABLE_EXCHANGE_BITFINEX CCAPI_ENABLE_EXCHANGE_BITMEX CCAPI_ENABLE_EXCHANGE_BINANCE_US CCAPI_ENABLE_EXCHANGE_BINANCE CCAPI_ENABLE_EXCHANGE_BINANCE_MARGIN CCAPI_ENABLE_EXCHANGE_BINANCE_USDS_FUTURES CCAPI_ENABLE_EXCHANGE_BINANCE_COIN_FUTURES CCAPI_ENABLE_EXCHANGE_HUOBI CCAPI_ENABLE_EXCHANGE_HUOBI_USDT_SWAP CCAPI_ENABLE_EXCHANGE_HUOBI_COIN_SWAP CCAPI_ENABLE_EXCHANGE_OKX CCAPI_ENABLE_EXCHANGE_ERISX CCAPI_ENABLE_EXCHANGE_KUCOIN CCAPI_ENABLE_EXCHANGE_KUCOIN_FUTURES CCAPI_ENABLE_EXCHANGE_DERIBIT CCAPI_ENABLE_EXCHANGE_GATEIO CCAPI_ENABLE_EXCHANGE_GATEIO_PERPETUAL_FUTURES CCAPI_ENABLE_EXCHANGE_CRYPTOCOM CCAPI_ENABLE_EXCHANGE_BYBIT CCAPI_ENABLE_EXCHANGE_BYBIT_DERIVATIVES CCAPI_ENABLE_EXCHANGE_ASCENDEX CCAPI_ENABLE_EXCHANGE_BITGET CCAPI_ENABLE_EXCHANGE_BITGET_FUTURES CCAPI_ENABLE_EXCHANGE_BITMART CCAPI_ENABLE_EXCHANGE_MEXC CCAPI_ENABLE_EXCHANGE_MEXC_FUTURES CCAPI_ENABLE_EXCHANGE_WHITEBIT)
if(CCAPI_ENABLE_LOG_ERROR)
list(APPEND BINDING_GYP_DEFINES_LIST CCAPI_ENABLE_LOG_ERROR)
endif()
if(CCAPI_ENABLE_LOG_WARN)
list(APPEND BINDING_GYP_DEFINES_LIST CCAPI_ENABLE_LOG_WARN)
endif()
if(CCAPI_ENABLE_LOG_INFO)
list(APPEND BINDING_GYP_DEFINES_LIST CCAPI_ENABLE_LOG_INFO)
endif()
if(CCAPI_ENABLE_LOG_DEBUG)
list(APPEND BINDING_GYP_DEFINES_LIST CCAPI_ENABLE_LOG_DEBUG)
endif()
if(CCAPI_ENABLE_LOG_TRACE)
list(APPEND BINDING_GYP_DEFINES_LIST CCAPI_ENABLE_LOG_TRACE)
endif()
list(JOIN BINDING_GYP_CFLAGS_CC_LIST "\",\"" BINDING_GYP_CFLAGS_CC)
message(STATUS "BINDING_GYP_CFLAGS_CC: ${BINDING_GYP_CFLAGS_CC}")
list(JOIN BINDING_GYP_LDFLAGS_LIST "\",\"" BINDING_GYP_LDFLAGS)
message(STATUS "BINDING_GYP_LDFLAGS: ${BINDING_GYP_LDFLAGS}")
list(JOIN BINDING_GYP_DEFINES_LIST "\",\"" BINDING_GYP_DEFINES)
message(STATUS "BINDING_GYP_DEFINES: ${BINDING_GYP_DEFINES}")

configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/binding.gyp.in
${CMAKE_CURRENT_BINARY_DIR}/${SWIG_TARGET_NAME}/binding.gyp
@ONLY)
if(NOT NODE_GYP_BUILD_MODE)
set(NODE_GYP_BUILD_MODE "release" CACHE STRING
"Choose the type of build, options are: debug, release."
FORCE)
endif()
if("${NODE_GYP_BUILD_MODE}" STREQUAL "release")
set(NODE_GYP_BUILD_DIR "build/Release")
else()
set(NODE_GYP_BUILD_DIR "build/Debug")
endif()
message(STATUS "NODE_GYP_BUILD_MODE: ${NODE_GYP_BUILD_MODE}")
add_custom_target(${SWIG_TARGET_NAME} ALL
COMMAND ${SWIG_EXECUTABLE} -outcurrentdir -c++ -javascript -node -I${CCAPI_PROJECT_DIR}/include ${SWIG_INTERFACE}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/ccapi_logger.cpp .
COMMAND ${NODE_GYP_EXECUTABLE} --${NODE_GYP_BUILD_MODE} clean configure build
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${SWIG_TARGET_NAME}
)
add_dependencies(${SWIG_TARGET_NAME} boost rapidjson hffix)

set(PACKAGING_DIR packaging)
set(PACKAGING_DIR_FULL ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGING_DIR}/${BUILD_VERSION})
file(MAKE_DIRECTORY ${PACKAGING_DIR_FULL})
set(JAVASCRIPT_PACKAGING_TARGET_NAME ${LANG}_${PACKAGING_DIR})
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/package.json.in
${PACKAGING_DIR_FULL}/package.json
@ONLY)
add_custom_target(${JAVASCRIPT_PACKAGING_TARGET_NAME} ALL
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${SWIG_TARGET_NAME}/${NODE_GYP_BUILD_DIR}/index.node ${PACKAGING_DIR_FULL}
WORKING_DIRECTORY ${PACKAGING_DIR_FULL}
)
add_dependencies(${JAVASCRIPT_PACKAGING_TARGET_NAME} ${SWIG_TARGET_NAME})

# Test
if(BUILD_TEST)
set(TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/test)
find_program(NPM_EXECUTABLE NAMES npm REQUIRED)
if(NOT NPM_EXECUTABLE)
message(FATAL_ERROR "Check for npm Program: not found")
else()
message(STATUS "Found npm Program: ${NPM_EXECUTABLE}")
endif()
file(COPY test DESTINATION ${TEST_DIR})
set(JAVASCRIPT_TEST_TARGET_NAME javascript_test_test)
set(JAVASCRIPT_TEST_BUILD_DIRECTORY ${TEST_DIR}/test)
file(MAKE_DIRECTORY ${JAVASCRIPT_TEST_BUILD_DIRECTORY})
add_custom_target(${JAVASCRIPT_TEST_TARGET_NAME} ALL
COMMAND ${CMAKE_COMMAND} -E rm -rf node_modules
COMMAND ${NPM_EXECUTABLE} install ${PACKAGING_DIR_FULL}
WORKING_DIRECTORY ${JAVASCRIPT_TEST_BUILD_DIRECTORY}
)
add_dependencies(${JAVASCRIPT_TEST_TARGET_NAME} ${JAVASCRIPT_PACKAGING_TARGET_NAME})
add_test(NAME javascript_test
COMMAND ${NODE_EXECUTABLE} index.js
WORKING_DIRECTORY ${JAVASCRIPT_TEST_BUILD_DIRECTORY})
endif()
65 changes: 65 additions & 0 deletions binding/javascript/binding.gyp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"targets": [
{
"target_name": "index",
"sources": [
"swig_interface_wrap.cxx",
"ccapi_logger.cpp"
],
"include_dirs": [
"@CCAPI_PROJECT_DIR@/include",
"@BOOST_INCLUDE_DIR@",
"@RAPIDJSON_INCLUDE_DIR@",
"@HFFIX_INCLUDE_DIR@",
"<(node_root_dir)/deps/openssl/openssl/include"
],
"cflags_cc!": [
"-fno-exceptions"
],
"conditions": [
[
"OS=='mac'",
{
"xcode_settings": {
"OTHER_CPLUSPLUSFLAGS" : [ "@BINDING_GYP_CFLAGS_CC@" ],
"GCC_ENABLE_CPP_EXCEPTIONS": "YES"
}
}
],
[
"target_arch=='ia32'",
{
"include_dirs": [
"<(node_root_dir)/deps/openssl/config/piii"
]
}
],
[
"target_arch=='x64'",
{
"include_dirs": [
"<(node_root_dir)/deps/openssl/config/k8"
]
}
],
[
"target_arch=='arm'",
{
"include_dirs": [
"<(node_root_dir)/deps/openssl/config/arm"
]
}
]
],
"cflags_cc": [
"@BINDING_GYP_CFLAGS_CC@"
],
"ldflags": [
"@BINDING_GYP_LDFLAGS@"
],
"defines": [
"@BINDING_GYP_DEFINES@"
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const ccapi = require('ccapi')
if (!process.env.OKX_API_KEY) {
console.error('Please set environment variable OKX_API_KEY')
process.exit(1)
}
if (!process.env.OKX_API_SECRET) {
console.error('Please set environment variable OKX_API_SECRET')
process.exit(1)
}
if (!process.env.OKX_API_PASSPHRASE) {
console.error('Please set environment variable OKX_API_PASSPHRASE')
process.exit(1)
}
const Session = ccapi.Session
const SessionConfigs = ccapi.SessionConfigs
const SessionOptions = ccapi.SessionOptions
const Request = ccapi.Request
const MapStringString = ccapi.MapStringString
const sessionConfigs = new SessionConfigs()
const sessionOptions = new SessionOptions()
const session = new Session(sessionOptions, sessionConfigs)
const request = new Request(Request.Operation_CREATE_ORDER, 'okx', 'BTC-USDT')
const param = new MapStringString()
param.set('SIDE', 'BUY')
param.set('QUANTITY', '0.0005')
param.set('LIMIT_PRICE', '20000')
request.appendParam(param)
session.sendRequest(request)
const intervalId = setInterval(() => {
const eventList = session.getEventQueue().purge()
for (let i = 0; i < eventList.size(); i++) {
const event = eventList.get(i)
console.log(`Received an event:\n${event.toStringPretty(2, 2)}`)
}
}, 1)
setTimeout(() => {
clearInterval(intervalId)
session.stop()
console.log('Bye')
}, 10000)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"ccapi": "file:../../../build/javascript/packaging/1.0.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const ccapi = require('ccapi')
if (!process.env.OKX_API_KEY) {
console.error('Please set environment variable OKX_API_KEY')
process.exit(1)
}
if (!process.env.OKX_API_SECRET) {
console.error('Please set environment variable OKX_API_SECRET')
process.exit(1)
}
if (!process.env.OKX_API_PASSPHRASE) {
console.error('Please set environment variable OKX_API_PASSPHRASE')
process.exit(1)
}
const Session = ccapi.Session
const SessionConfigs = ccapi.SessionConfigs
const SessionOptions = ccapi.SessionOptions
const Subscription = ccapi.Subscription
const Request = ccapi.Request
const MapStringString = ccapi.MapStringString
const Event = ccapi.Event
const Message = ccapi.Message
const sessionConfigs = new SessionConfigs()
const sessionOptions = new SessionOptions()
const session = new Session(sessionOptions, sessionConfigs)
const subscription = new Subscription('okx', 'BTC-USDT', 'ORDER_UPDATE')
session.subscribe(subscription)
const intervalId = setInterval(() => {
const eventList = session.getEventQueue().purge()
for (let i = 0; i < eventList.size(); i++) {
const event = eventList.get(i)
if (event.getType() == Event.Type_SUBSCRIPTION_STATUS) {
console.log(`Received an event of type SUBSCRIPTION_STATUS:\n${event.toStringPretty(2, 2)}`)
const message = event.getMessageList().get(0)
if (message.getType() == Message.Type_SUBSCRIPTION_STARTED) {
const request = new Request(Request.Operation_CREATE_ORDER, 'okx', 'BTC-USDT')
const param = new MapStringString()
param.set('SIDE', 'BUY')
param.set('QUANTITY', '0.0005')
param.set('LIMIT_PRICE', '20000')
request.appendParam(param)
session.sendRequest(request)
}
}
else if (event.getType() == ccapi.Event.Type_SUBSCRIPTION_DATA) {
console.log(`Received an event of type SUBSCRIPTION_DATA:\n${event.toStringPretty(2, 2)}`)
}
}
}, 1)
setTimeout(() => {
clearInterval(intervalId)
session.stop()
console.log('Bye')
}, 10000)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"ccapi": "file:../../../build/javascript/packaging/1.0.0"
}
}

0 comments on commit cf32f73

Please sign in to comment.