Browse Source

Add balance and withdraw API methods for ETH/ERC20.

patch-3
Artem Pikulin 7 years ago
parent
commit
8bc79dbfb0
  1. 2
      iguana/exchanges/CMakeLists.txt
  2. 8
      iguana/exchanges/LP_commands.c
  3. 10
      iguana/exchanges/LP_etomic.c
  4. 52
      iguana/exchanges/LP_etomic.h
  5. 3
      iguana/exchanges/LP_include.h
  6. 5
      iguana/exchanges/LP_nativeDEX.c
  7. 5
      iguana/exchanges/LP_swap.c
  8. 29
      iguana/exchanges/LP_transaction.c
  9. 9
      iguana/exchanges/LP_utxo.c
  10. 19
      iguana/exchanges/etomicswap/etomiccurl.c
  11. 1
      iguana/exchanges/etomicswap/etomiccurl.h
  12. 44
      iguana/exchanges/etomicswap/etomiclib.cpp
  13. 4
      iguana/exchanges/etomicswap/etomiclib.h

2
iguana/exchanges/CMakeLists.txt

@ -1,5 +1,5 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
set(MM_SOURCES mm.c ../mini-gmp.c ../groestl.c ../segwit_addr.c ../keccak.c)
set(MM_SOURCES mm.c ../mini-gmp.c ../groestl.c ../segwit_addr.c ../keccak.c LP_etomic.c)
set(MM_LIBS ${NANOMSG_LIBRARY} curl pthread libcrypto777 libjpeg libsecp256k1)
add_executable(marketmaker-testnet ${MM_SOURCES})
add_executable(marketmaker-mainnet ${MM_SOURCES})

8
iguana/exchanges/LP_commands.c

@ -578,6 +578,14 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
}
return(clonestr("{\"error\":\"cant find coind\"}"));
}
#ifndef NOTETOMIC
else if ( strcmp(method,"eth_withdraw") == 0 )
{
if ( (ptr= LP_coinsearch(coin)) != 0 ) {
return LP_eth_withdraw(ptr, argjson);
}
}
#endif
else if ( strcmp(method,"setconfirms") == 0 )
{
int32_t n;

10
iguana/exchanges/LP_etomic.c

@ -21,9 +21,7 @@
//
// Created by artem on 24.01.18.
//
#include "etomicswap/etomiclib.h"
#include "etomicswap/etomiccurl.h"
#include <inttypes.h>
#include "LP_etomic.h"
int32_t LP_etomic_wait_for_confirmation(char *txId)
{
@ -36,9 +34,9 @@ char *LP_etomicalice_send_fee(struct basilisk_swap *swap)
satoshisToWei(amount, swap->myfee.I.amount);
uint8arrayToHex(secretKey, swap->persistent_privkey.bytes, 32);
if (strcmp(swap->I.alicestr,"ETH") == 0 ) {
return(sendEth(ETH_FEE_ACCEPTOR, amount, secretKey));
return(sendEth(ETH_FEE_ACCEPTOR, amount, secretKey, 1));
} else {
return(sendErc20(swap->I.alicetomic, ETH_FEE_ACCEPTOR, amount, secretKey));
return(sendErc20(swap->I.alicetomic, ETH_FEE_ACCEPTOR, amount, secretKey, 1));
}
}
@ -136,12 +134,10 @@ char *LP_etomicalice_send_payment(struct basilisk_swap *swap)
uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId)
{
/*
if (waitForConfirmation(txId) < 0) {
printf("Alice payment %s does not exist\n", txId);
return(0);
}
*/
EthTxData data = getEthTxData(txId);
if (strcmp(data.to, ETOMIC_ALICECONTRACT) != 0) {
printf("Alice payment %s was sent to wrong address %s\n", txId, data.to);

52
iguana/exchanges/LP_etomic.h

@ -0,0 +1,52 @@
//
// Created by artem on 13.03.18.
//
#ifndef SUPERNET_LP_ETOMIC_H
#define SUPERNET_LP_ETOMIC_H
#include "etomicswap/etomiclib.h"
#include "etomicswap/etomiccurl.h"
#include <inttypes.h>
#include "LP_include.h"
int32_t LP_etomic_wait_for_confirmation(char *txId);
char *LP_etomicalice_send_fee(struct basilisk_swap *swap);
uint8_t LP_etomic_verify_alice_fee(struct basilisk_swap *swap);
char *LP_etomicalice_send_payment(struct basilisk_swap *swap);
uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId);
char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap);
char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap);
char *LP_etomicbob_sends_deposit(struct basilisk_swap *swap);
uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId);
char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap);
char *LP_etomicbob_sends_payment(struct basilisk_swap *swap);
uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId);
char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap);
char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap);
char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap);
char *sendEthTx(struct basilisk_swap *swap, struct basilisk_rawtx *rawtx);
int32_t LP_etomic_priv2addr(char *coinaddr,bits256 privkey);
int32_t LP_etomic_priv2pub(uint8_t *pub64,bits256 privkey);
int32_t LP_etomic_pub2addr(char *coinaddr,uint8_t pub64[64]);
uint8_t LP_etomic_is_empty_tx_id(char *txId);
#endif //SUPERNET_LP_ETOMIC_H

3
iguana/exchanges/LP_include.h

@ -266,7 +266,7 @@ struct basilisk_swapinfo
#define BASILISK_ALICERECLAIM 9
#define BASILISK_ALICECLAIM 10
//0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0
char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" };
static char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" };
struct LP_swap_remember
{
@ -577,5 +577,6 @@ int bech32_convert_bits(uint8_t *out,int32_t *outlen,int outbits,const uint8_t *
int bech32_decode(char *hrp,uint8_t *data,int32_t *data_len,const char *input);
int bech32_encode(char *output,const char *hrp,const uint8_t *data,int32_t data_len);
void HashGroestl(void * buf, const void * pbegin, int len);
bits256 LP_privkey(char *symbol,char *coinaddr,uint8_t taddr);
#endif

5
iguana/exchanges/LP_nativeDEX.c

@ -85,6 +85,11 @@ void LP_millistats_update(struct LP_millistats *mp)
}
#include "LP_include.h"
#ifndef NOTETOMIC
#include "LP_etomic.h"
#endif
portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex,LP_tradesmutex,LP_commandQmutex,LP_blockinit_mutex,LP_pendswap_mutex,LP_listmutex;
int32_t LP_canbind;
char *Broadcaststr,*Reserved_msgs[2][1000];

5
iguana/exchanges/LP_swap.c

@ -107,8 +107,7 @@
depositspent.(f34e04ad74e290f63f3d0bccb7d0d50abfa54eea58de38816fdc596a19767add) alice.1 bob.0
*/
#define TX_WAIT_TIMEOUT 180
#define TX_WAIT_TIMEOUT 1800
uint32_t LP_atomic_locktime(char *base,char *rel)
{
@ -735,7 +734,7 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3
sendbuf[sendlen++] = rawtx->I.datalen & 0xff;
sendbuf[sendlen++] = (rawtx->I.datalen >> 8) & 0xff;
sendbuf[sendlen++] = rawtx->I.redeemlen;
if ( rawtx->I.ethTxid[0] != 0 && strlen(rawtx->I.ethTxid) == 66 )
if ( rawtx->I.ethTxid[0] != 0 && strlen(rawtx->I.ethTxid) == 66 )
{
uint8_t ethTxidBytes[32];
// ETH txid always starts with 0x

29
iguana/exchanges/LP_transaction.c

@ -1515,6 +1515,31 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
return(jprint(retjson,1));
}
#ifndef NOTETOMIC
char *LP_eth_withdraw(struct iguana_info *coin,cJSON *argjson)
{
cJSON *retjson = cJSON_CreateObject();
char *dest_addr, *tx_id, privkey_str[70], amount_str[100];
int64_t amount;
bits256 privkey;
dest_addr = jstr(argjson, "to");
amount = get_cJSON_int(argjson, "amount");
privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr);
uint8arrayToHex(privkey_str, privkey.bytes, 32);
satoshisToWei(amount_str, amount);
if (strcmp(coin->symbol, "ETH") == 0) {
tx_id = sendEth(dest_addr, amount_str, privkey_str, 0);
} else {
tx_id = sendErc20(coin->etomic, dest_addr, amount_str, privkey_str, 0);
}
jaddstr(retjson, "tx_id", tx_id);
return(jprint(retjson,1));
}
#endif
int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pubkey33,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf,int32_t delay,bits256 privkey,uint8_t *changermd160,char *vinaddr)
{
struct iguana_info *coin; int32_t len,retval=-1; char *retstr,*hexstr; cJSON *argjson,*outputs,*item,*retjson,*obj;
@ -2054,10 +2079,6 @@ void basilisk_alicepayment(struct basilisk_swap *swap,struct iguana_info *coin,s
basilisk_rawtx_gen(swap->ctx,"alicepayment",swap->I.started,swap->persistent_pubkey33,0,1,alicepayment,alicepayment->I.locktime,alicepayment->spendscript,alicepayment->I.spendlen,swap->I.Atxfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr);
}
#ifndef NOTETOMIC
#include "LP_etomic.c"
#endif
int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)
{
char coinaddr[64],alicestr[65],alicetomic[128]; int32_t retval = -1; struct iguana_info *coin;

9
iguana/exchanges/LP_utxo.c

@ -620,6 +620,15 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
{
cJSON *array,*retjson,*item; bits256 zero; int32_t i,n; uint64_t balance = 0;
memset(zero.bytes,0,sizeof(zero));
#ifndef NOTETOMIC
if (coin->etomic[0] != 0) {
if (strcmp(coin->symbol, "ETH") == 0) {
balance = getEthBalance(coinaddr);
} else {
balance = getErc20BalanceSatoshi(coinaddr, coin->etomic);
}
} else
#endif
if ( coin->electrum == 0 )
{
if ( (array= LP_listunspent(coin->symbol,coinaddr,zero,zero)) != 0 )

19
iguana/exchanges/etomicswap/etomiccurl.c

@ -106,7 +106,7 @@ cJSON *sendRpcRequest(char *method, cJSON *params)
return result;
}
char* sendRawTx(char* rawTx)
char* sendRawTxWaitConfirm(char* rawTx)
{
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToArray(params, cJSON_CreateString(rawTx));
@ -125,6 +125,23 @@ char* sendRawTx(char* rawTx)
return txId;
}
char* sendRawTx(char* rawTx)
{
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToArray(params, cJSON_CreateString(rawTx));
cJSON *resultJson = sendRpcRequest("eth_sendRawTransaction", params);
cJSON_Delete(params);
char *txId = NULL;
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
char* tmp = resultJson->valuestring;
txId = (char *) malloc(strlen(tmp) + 1);
strcpy(txId, tmp);
}
cJSON_Delete(resultJson);
pthread_mutex_unlock(&sendTxMutex);
return txId;
}
int64_t getNonce(char* address)
{
// we should lock this mutex and unlock it only when transaction was already sent.

1
iguana/exchanges/etomicswap/etomiccurl.h

@ -37,6 +37,7 @@ typedef struct
} EthTxData;
char* sendRawTx(char* rawTx);
char* sendRawTxWaitConfirm(char* rawTx);
char* ethCall(char* to, const char* data);
int64_t getNonce(char* address);
char* getEthBalanceRequest(char* address);

44
iguana/exchanges/etomicswap/etomiclib.cpp

@ -59,7 +59,7 @@ char *approveErc20(ApproveErc20Input input)
<< toHex(toBigEndian(jsToU256(input.amount)));
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, input.secret);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -84,7 +84,7 @@ char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData)
std::stringstream ss = aliceSendsEthPaymentData(input);
tx.data = jsToBytes(ss.str());
char *rawTx = signTx(tx, txData.secretKey);
char *result = sendRawTx(rawTx);
char *result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -127,7 +127,7 @@ char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txDa
std::stringstream ss = aliceSendsErc20PaymentData(input);
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -168,7 +168,7 @@ char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxDat
<< toHex(jsToBytes(input.bobSecret));
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -199,7 +199,7 @@ char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData
<< toHex(jsToBytes(input.aliceSecret));
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -263,7 +263,7 @@ char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData)
std::stringstream ss = bobSendsErc20DepositData(input);
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -303,7 +303,7 @@ char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData)
<< toHex(jsToBytes(input.bobSecret));
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -332,7 +332,7 @@ char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData
<< "000000000000000000000000";
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -355,7 +355,7 @@ char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData)
std::stringstream ss = bobSendsEthPaymentData(input);
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -396,7 +396,7 @@ char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData)
std::stringstream ss = bobSendsErc20PaymentData(input);
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -435,7 +435,7 @@ char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData
<< "000000000000000000000000";
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -465,7 +465,7 @@ char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData
<< toHex(jsToBytes(input.aliceSecret));
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -582,10 +582,10 @@ uint64_t weiToSatoshi(char *wei)
return static_cast<uint64_t>(satoshi);
}
char *sendEth(char *to, char *amount, char *privKey)
char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm)
{
TransactionSkeleton tx;
char *from = privKey2Addr(privKey);
char *from = privKey2Addr(privKey), *result;
tx.from = jsToAddress(from);
tx.to = jsToAddress(to);
tx.value = jsToU256(amount);
@ -595,7 +595,11 @@ char *sendEth(char *to, char *amount, char *privKey)
free(from);
char *rawTx = signTx(tx, privKey);
char *result = sendRawTx(rawTx);
if (waitConfirm == 0) {
result = sendRawTx(rawTx);
} else {
result = sendRawTxWaitConfirm(rawTx);
}
free(rawTx);
return result;
}
@ -616,10 +620,10 @@ std::stringstream getErc20TransferData(char *tokenAddress, char *to, char *amoun
return ss;
}
char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey)
char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8_t waitConfirm)
{
TransactionSkeleton tx;
char *from = privKey2Addr(privKey);
char *from = privKey2Addr(privKey), *result;
tx.from = jsToAddress(from);
tx.to = jsToAddress(tokenAddress);
tx.value = 0;
@ -632,7 +636,11 @@ char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey)
tx.data = jsToBytes(ss.str());
char *rawTx = signTx(tx, privKey);
char *result = sendRawTx(rawTx);
if (waitConfirm == 0) {
result = sendRawTx(rawTx);
} else {
result = sendRawTxWaitConfirm(rawTx);
}
free(rawTx);
return result;
}

4
iguana/exchanges/etomicswap/etomiclib.h

@ -178,8 +178,8 @@ void uint8arrayToHex(char *dest, uint8_t *input, int len);
void satoshisToWei(char *dest, uint64_t input);
uint64_t weiToSatoshi(char *wei);
char *sendEth(char *to, char *amount, char *privKey);
char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey);
char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm);
char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8_t waitConfirm);
uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data);
// Your prototype or Definition

Loading…
Cancel
Save