Skip to content

Commit

Permalink
woofipro: new dex (#22196)
Browse files Browse the repository at this point in the history
* woofipro: initialize new dex

* woofipro: add fetchMarkets

* woofipro: add fetchCurrencies

* woofipro: add fetchTrades

* woofipro: update

* woofipro: add fetchTime

* woofipro: add fetchFundingRate

* woofipro: add fetchFundingRates

* woofipro: add fetchFundingRateHistory

* woofipro: update

* woofipro: update signature

* woofipro: add fetchOrderBook

* woofipro: add fetchOHLCV

* woofipro: add createOrder

* woofipro: update

* woofipro: add cancelOrder

* woofipro: update

* woofipro: add fetchOrders

* woofipro: add fetchOpenOrders

* woofipro: add fetchClosedOrders

* woofipro: add fetchOrder

* woofipro: update

* woofipro: add fetchOrderTrades

* woofipro: add fetchMyTrades

* woofipro: add cancelAllOrders

* woofipro: add cancelOrders

* woofipro: add editOrder

* woofipro: add fetchTradingFees

* woofipro: update

* woofipro: add fetchBalance

* woofipro: add fetchLeger functions

* woofipro: update

* woofipro: add setLeverage

* woofipro: add fetchLeverage

* woofipro: add fetchPosition

* woofipro: add fetchPositions

* woofipro: updatw

* woofipro: update

* woofipro: update

* woofipro: update

* woofipro: update

* woofipro: update crypto

* woofipro: update

* woofipro: update

* woofipro: update

* woofipro: update

* cs: update exchange

* woofipro: update doc

* woofipro: add withdraw

* woofipro: update

* woofipro: update

* woofipro: update skip tests

* woofipro: update static tests

* woofipro: update static tests

* woofipro: update

* woofipro: update

* woofipro: update

* woofipro: update

* woofipro: add ws

* woofipro: add watchTicker and watchTickers

* woofipro: add watchOHLCV

* woofipro: add watchTrades

* woofipro: add watchOrders

* woofipro: update

* woofipro: add watchPositions

* woofipro: update

* woofipro: add watchBalance

* fix ts syntax

* fix transpilation

* add brokerId

* update docs

* fix tests

* improve editOrder

* more static tests

* add symbol to editOrder

* more tests

* woofipro: update

* woofipro: replace uid with accountId

* fix delete request

* woofipro: add createOrders (need to remove keysort of params)

* woofipro: update createOrders

* woofipro: update createOrders

* fix ts syntax

* static tests setup

* fix static tests

* fix c# build

* fix python syntax

* add secret to response tests

* add woofipro id test

* fix idtest

* ws fixes

* add watchMyTrades

* fix args

* add more tests

* woofipro: update default id

* woofipro: update

* woofipro: use watchMultiple

* fixing linting

* fix handleUNtilOption

* add logo

* add referral

* woofipro: update

* woofipro: update doc

---------

Co-authored-by: carlosmiei <43336371+carlosmiei@users.noreply.github.com>
  • Loading branch information
sc0Vu and carlosmiei committed May 10, 2024
1 parent bb7983e commit 5d37694
Show file tree
Hide file tree
Showing 20 changed files with 6,091 additions and 49 deletions.
18 changes: 9 additions & 9 deletions cs/ccxt/base/Exchange.Crypto.cs
Expand Up @@ -73,7 +73,7 @@ public static string Hmac(object request2, object secret2, Delegate algorithm2 =
break;
}

return digest == "hex" ? binaryToHex(signature) : binaryToBase64(signature);
return digest == "hex" ? binaryToHex(signature) : Exchange.BinaryToBase64(signature);
}

public string hmac(object request2, object secret2, Delegate algorithm2 = null, string digest = "hex") => Hmac(request2, secret2, algorithm2, digest);
Expand Down Expand Up @@ -115,7 +115,7 @@ public static object Hash(object request2, Delegate hash = null, object digest2
{
return signature;
}
return digest == "hex" ? binaryToHex(signature) : binaryToBase64(signature);
return digest == "hex" ? binaryToHex(signature) : Exchange.BinaryToBase64(signature);
}

private static byte[] HashBytes(object request2, Delegate hash = null)
Expand Down Expand Up @@ -167,25 +167,25 @@ public static string Jwt(object data, object secret, Delegate hash = null, bool
header.Remove("iat");
}
var stringHeader = Exchange.Json(header);
var encodedHeader = Exchange.Base64urlEncode(Exchange.StringToBase64(stringHeader));
var encodedData = Exchange.Base64urlEncode(Exchange.StringToBase64(Exchange.Json(data)));
var encodedHeader = Exchange.Base64urlEncode(stringHeader);
var encodedData = Exchange.Base64urlEncode(Exchange.Json(data));
var token = encodedHeader + "." + encodedData;
string signature = null;
var algoType = alg.Substring(0, 2);
if (isRsa)
{
signature = Exchange.Base64urlEncode(Exchange.Rsa(token, secret, hash));
signature = Exchange.Base64urlEncode(Exchange.Base64ToBinary(Exchange.Rsa(token, secret, hash) as object));
}
else if (algoType == "ES")
{
var ec = Ecdsa(token, secret, p256, hash) as Dictionary<string, object>;
var r = ec["r"] as string;
var s = ec["s"] as string;
signature = Exchange.Base64urlEncode(Exchange.binaryToBase64(Exchange.ConvertHexStringToByteArray(r + s)));
signature = Exchange.Base64urlEncode(Exchange.ConvertHexStringToByteArray(r + s));
}
else
{
signature = Exchange.Base64urlEncode(Exchange.Hmac(token, secret, hash, "binary"));
signature = Exchange.Base64urlEncode(Exchange.Base64ToBinary(Exchange.Hmac(token, secret, hash, "binary") as object));
}
var res = token + "." + signature;
return res;
Expand Down Expand Up @@ -461,9 +461,9 @@ public object signMessageString(object str, object privateKey = null)
public object eddsa(object request, object secret, object alg = null)
{
alg ??= "ed25519";
var msg = Hex.HexToBytes((string)request);
var msg = Encoding.UTF8.GetBytes((string)request);
var signer = new Ed25519Signer();
var privateKey = ReadEDDSAPrivateKeyFromPem(secret as string);
var privateKey = (secret is string) ? ReadEDDSAPrivateKeyFromPem(secret as string) : new Ed25519PrivateKeyParameters(secret as byte[]);
signer.Init(true, privateKey);
signer.BlockUpdate(msg, 0, msg.Length);
byte[] signature = signer.GenerateSignature();
Expand Down
27 changes: 16 additions & 11 deletions cs/ccxt/base/Exchange.Encode.cs
@@ -1,6 +1,7 @@
namespace ccxt;
using System.Security.Cryptography;
using System.Text;
using Cryptography.ECDSA;

using MiniMessagePack;

Expand Down Expand Up @@ -61,9 +62,11 @@ public static byte[] Base64ToBinary(object pt)
return base64EncodedBytes;
}

public string base58ToBinary(object str)
public byte[] base58ToBinary(object pt) => Base58ToBinary(pt);

public static byte[] Base58ToBinary(object pt)
{
return (string)str; // stub
return Base58.Decode(pt as string);
}

public object binaryConcat(object a, object b)
Expand Down Expand Up @@ -125,12 +128,13 @@ public string binaryToBase58(object buff2)
return binaryToHex(buff);
}

public static string binaryToBase64(byte[] buff)
{
return Convert.ToBase64String(buff);
}
public string binaryToBase64(byte[] buff) => BinaryToBase64(buff);

public byte[] stringToBinary(string buff)
public static string BinaryToBase64(byte[] buff) => Convert.ToBase64String(buff);

public byte[] stringToBinary(string buff) => StringToBinary(buff);

public static byte[] StringToBinary(string buff)
{
return Encoding.UTF8.GetBytes(buff);
}
Expand Down Expand Up @@ -268,12 +272,13 @@ public string encodeURIComponent(object str2)
return result.ToString();
}

public static string Base64urlEncode(string s)
public string urlencodeBase64(object s) => Base64urlEncode(s);

public static string Base64urlEncode(object s)
{
char[] padding = { '=' };
// var toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(s);
// string returnValue = System.Convert.ToBase64String(toEncodeAsBytes)
string returnValue = s.TrimEnd(padding).Replace('+', '-').Replace('/', '_');
string str = (s is string) ? Exchange.StringToBase64(s as string) : Exchange.BinaryToBase64(s as byte[]);
string returnValue = str.TrimEnd(padding).Replace('+', '-').Replace('/', '_');
return returnValue;
}

Expand Down
3 changes: 3 additions & 0 deletions cs/ccxt/base/Exchange.Options.cs
Expand Up @@ -79,6 +79,7 @@ public partial class Exchange
public string apiKey { get; set; }
public string password { get; set; }
public string uid { get; set; }
public string accountId { get; set; }

public dict userAgents { get; set; } = new dict(){
{"chrome", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"},
Expand Down Expand Up @@ -325,6 +326,7 @@ public virtual object describe()
{ "apiKey", true },
{ "secret", true },
{ "uid", false },
{ "accountId", false },
{ "login", false },
{ "password", false },
{ "twofa", false },
Expand Down Expand Up @@ -429,6 +431,7 @@ void initializeProperties(dict userConfig = null)
this.walletAddress = SafeString(extendedProperties, "walletAddress", "");
this.token = SafeString(extendedProperties, "token", "");
this.uid = SafeString(extendedProperties, "uid", "");
this.accountId = SafeString(extendedProperties, "accountId", "");

this.userAgents = SafeValue(extendedProperties, "userAgents", userAgents) as dict;
this.userAgent = SafeString(extendedProperties, "userAgent");
Expand Down
22 changes: 14 additions & 8 deletions php/Exchange.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions php/test/test_async.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions python/ccxt/base/exchange.py
Expand Up @@ -38,7 +38,7 @@
# rsa jwt signing
from cryptography.hazmat import backends
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric import padding, ed25519
# from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
from cryptography.hazmat.primitives.serialization import load_pem_private_key

Expand Down Expand Up @@ -199,6 +199,7 @@ class Exchange(object):
secret = ''
password = ''
uid = ''
accountId = None
privateKey = '' # a "0x"-prefixed hexstring private key for a wallet
walletAddress = '' # the wallet address "0x"-prefixed hexstring
token = '' # reserved for HTTP auth in some cases
Expand Down Expand Up @@ -273,6 +274,7 @@ class Exchange(object):
'apiKey': True,
'secret': True,
'uid': False,
'accountId': False,
'login': False,
'password': False,
'twofa': False, # 2-factor authentication (one-time password key)
Expand Down Expand Up @@ -1307,7 +1309,7 @@ def binary_concat_array(array):
return result

@staticmethod
def base64urlencode(s):
def urlencode_base64(s):
return Exchange.decode(base64.urlsafe_b64encode(s)).replace('=', '')

@staticmethod
Expand Down Expand Up @@ -1345,8 +1347,8 @@ def jwt(request, secret, algorithm='sha256', is_rsa=False, opts={}):
if 'nonce' in opts and opts['nonce'] is not None:
header_opts['nonce'] = opts['nonce']
header = Exchange.encode(Exchange.json(header_opts))
encoded_header = Exchange.base64urlencode(header)
encoded_data = Exchange.base64urlencode(Exchange.encode(Exchange.json(request)))
encoded_header = Exchange.urlencode_base64(header)
encoded_data = Exchange.urlencode_base64(Exchange.encode(Exchange.json(request)))
token = encoded_header + '.' + encoded_data
algoType = alg[0:2]
if is_rsa or algoType == 'RS':
Expand All @@ -1356,7 +1358,7 @@ def jwt(request, secret, algorithm='sha256', is_rsa=False, opts={}):
signature = Exchange.base16_to_binary(rawSignature['r'].rjust(64, "0") + rawSignature['s'].rjust(64, "0"))
else:
signature = Exchange.hmac(Exchange.encode(token), secret, algos[algorithm], 'binary')
return token + '.' + Exchange.base64urlencode(signature)
return token + '.' + Exchange.urlencode_base64(signature)

@staticmethod
def rsa(request, secret, alg='sha256'):
Expand Down Expand Up @@ -1438,7 +1440,9 @@ def ecdsa(request, secret, algorithm='p256', hash=None, fixed_length=False):

@staticmethod
def eddsa(request, secret, curve='ed25519'):
private_key = load_pem_private_key(Exchange.encode(secret), None)
if isinstance(secret, str):
Exchange.encode(secret)
private_key = ed25519.Ed25519PrivateKey.from_private_bytes(secret) if len(secret) == 32 else load_pem_private_key(secret, None)
return Exchange.binary_to_base64(private_key.sign(request))

@staticmethod
Expand Down
14 changes: 14 additions & 0 deletions python/ccxt/test/test_async.py
Expand Up @@ -889,6 +889,13 @@ def load_currencies_from_file(self, id):
content = io_file_read(filename)
return content

def load_credentials_from_file(self, id):
filename = self.root_dir + './ts/src/test/static/credentials/' + id + '.json'
if not io_file_exists(filename):
return None
content = io_file_read(filename)
return content

def load_static_data(self, folder, target_exchange=None):
result = {}
if target_exchange:
Expand Down Expand Up @@ -1104,6 +1111,7 @@ async def test_response_statically(self, exchange, method, skip_keys, data):
def init_offline_exchange(self, exchange_name):
markets = self.load_markets_from_file(exchange_name)
currencies = self.load_currencies_from_file(exchange_name)
credentials = self.load_credentials_from_file(exchange_name)
exchange = init_exchange(exchange_name, {
'markets': markets,
'currencies': currencies,
Expand Down Expand Up @@ -1134,6 +1142,12 @@ def init_offline_exchange(self, exchange_name):
},
})
exchange.currencies = currencies # not working in python if assigned in the config dict
if credentials is not None:
objkeys = list(credentials.keys())
for i in range(0, len(objkeys)):
credential = objkeys[i]
credential_value = credentials[credential]
set_exchange_prop(exchange, credential, credential_value)
return exchange

async def test_exchange_request_statically(self, exchange_name, exchange_data, test_name=None):
Expand Down
12 changes: 12 additions & 0 deletions skip-tests.json
Expand Up @@ -1526,6 +1526,18 @@
}
}
},
"woofipro": {
"skipMethods":{
"loadMarkets":{
"active": "undefined",
"currencyIdAndCode": "messed"
},
"fetchCurrencies":{
"withdraw": "undefined",
"deposit": "undefined"
}
}
},
"yobit": {
"skipMethods": {
"loadMarkets":{
Expand Down

0 comments on commit 5d37694

Please sign in to comment.