/****************************************************************************** * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * * holder information and the developer policies on copyright and licensing. * * * * Unless otherwise agreed in a custom licensing agreement, no part of the * * SuperNET software, including this file may be copied, modified, propagated * * or distributed except according to the terms contained in the LICENSE file * * * * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ // // LP_etomic.c // marketmaker // // // Created by artem on 24.01.18. // #include "LP_etomic.h" int32_t LP_etomic_wait_for_confirmation(char *txId) { return(waitForConfirmation(txId)); } void LP_etomic_pubkeystr_to_addr(char *pubkey, char *output) { char *address = pubKey2Addr(pubkey); strcpy(output, address); free(address); } char *LP_etomicalice_send_fee(struct basilisk_swap *swap) { char amount[100], secretKey[70], dexaddr[50]; satoshisToWei(amount, swap->myfee.I.amount); uint8arrayToHex(secretKey, swap->persistent_privkey.bytes, 32); LP_etomic_pubkeystr_to_addr(INSTANTDEX_PUBKEY, dexaddr); if (strcmp(swap->I.alicestr,"ETH") == 0 ) { return(sendEth(dexaddr, amount, secretKey, 1)); } else { return(sendErc20(swap->I.alicetomic, dexaddr, amount, secretKey, 1)); } } uint8_t LP_etomic_verify_alice_fee(struct basilisk_swap *swap) { if (waitForConfirmation(swap->otherfee.I.ethTxid) < 0) { printf("Alice fee tx %s does not exist", swap->otherfee.I.ethTxid); return(0); } EthTxData data = getEthTxData(swap->otherfee.I.ethTxid); if (strcmp(data.from, swap->I.etomicdest) != 0) { printf("Alice fee tx %s was sent from wrong address %s\n", swap->otherfee.I.ethTxid, data.from); return(0); } char dexaddr[50]; LP_etomic_pubkeystr_to_addr(INSTANTDEX_PUBKEY, dexaddr); if ( strcmp(swap->I.alicestr,"ETH") == 0 ) { if (strcmp(data.to, dexaddr) != 0) { printf("Alice fee %s was sent to wrong address %s\n", swap->otherfee.I.ethTxid, data.to); return(0); } uint64_t txValue = weiToSatoshi(data.valueHex); if (txValue != swap->otherfee.I.amount) { printf("Alice fee %s amount %" PRIu64 " is not equal to expected %" PRIu64 "\n", swap->otherfee.I.ethTxid, txValue, swap->otherfee.I.amount); return(0); } return(1); } else { if (strcmp(data.to, swap->I.alicetomic) != 0) { printf("Alice ERC20 fee %s token address %s is not equal to expected %s\n", swap->otherfee.I.ethTxid, data.to, swap->I.alicetomic); return(0); } char weiAmount[70]; satoshisToWei(weiAmount, swap->otherfee.I.amount); return(verifyAliceErc20FeeData(swap->I.alicetomic, dexaddr, weiAmount, data.input)); } } char *LP_etomicalice_send_payment(struct basilisk_swap *swap) { AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20; BasicTxData txData; // set input and txData fields from the swap data structure memset(&txData,0,sizeof(txData)); if ( strcmp(swap->I.alicestr,"ETH") == 0 ) { memset(&input,0,sizeof(input)); strcpy(input.bobAddress, swap->I.etomicsrc); uint8arrayToHex(input.bobHash, swap->I.secretBn, 20); uint8arrayToHex(input.aliceHash, swap->I.secretAm, 20); uint8arrayToHex(input.dealId, swap->alicepayment.I.actualtxid.bytes, 32); strcpy(txData.from, swap->I.etomicdest); strcpy(txData.to, ETOMIC_ALICECONTRACT); satoshisToWei(txData.amount, swap->I.alicesatoshis); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); return(aliceSendsEthPayment(input,txData)); } else { memset(&input20,0,sizeof(input20)); strcpy(input20.bobAddress, swap->I.etomicsrc); uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20); uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20); uint8arrayToHex(input20.dealId, swap->alicepayment.I.actualtxid.bytes, 32); strcpy(input20.tokenAddress, swap->I.alicetomic); satoshisToWei(input20.amount, swap->I.alicesatoshis); strcpy(txData.from, swap->I.etomicdest); strcpy(txData.to, ETOMIC_ALICECONTRACT); strcpy(txData.amount, "0"); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); uint64_t allowance = getErc20Allowance(swap->I.etomicdest, ETOMIC_ALICECONTRACT, swap->I.alicetomic); if (allowance < swap->I.alicesatoshis) { printf("Alice token allowance is too low, setting new allowance\n"); ApproveErc20Input approveErc20Input; strcpy(approveErc20Input.tokenAddress, swap->I.alicetomic); strcpy(approveErc20Input.owner, swap->I.etomicdest); strcpy(approveErc20Input.spender, ETOMIC_ALICECONTRACT); char *tokenBalance = getErc20BalanceHexWei(swap->I.etomicdest, swap->I.alicetomic); strcpy(approveErc20Input.amount, tokenBalance); free(tokenBalance); strcpy(approveErc20Input.secret, txData.secretKey); char *allowTxId = approveErc20(approveErc20Input); LP_etomic_wait_for_confirmation(allowTxId); free(allowTxId); } return(aliceSendsErc20Payment(input20,txData)); } } 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); return(0); } if (strcmp(data.from, swap->I.etomicdest) != 0) { printf("Alice payment %s was done from wrong address %s\n", txId, data.from); return(0); } AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20; if ( strcmp(swap->I.alicestr,"ETH") == 0 ) { uint64_t paymentAmount = weiToSatoshi(data.valueHex); if (paymentAmount != swap->I.alicesatoshis) { printf("Alice payment amount %" PRIu64 " does not match expected %" PRIu64 "\n", paymentAmount, swap->I.alicesatoshis); return(0); } memset(&input,0,sizeof(input)); strcpy(input.bobAddress, swap->I.etomicsrc); uint8arrayToHex(input.bobHash, swap->I.secretBn, 20); uint8arrayToHex(input.aliceHash, swap->I.secretAm, 20); uint8arrayToHex(input.dealId, swap->alicepayment.I.actualtxid.bytes, 32); return(verifyAliceEthPaymentData(input, data.input)); } else { memset(&input20,0,sizeof(input20)); strcpy(input20.bobAddress, swap->I.etomicsrc); uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20); uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20); uint8arrayToHex(input20.dealId, swap->alicepayment.I.actualtxid.bytes, 32); strcpy(input20.tokenAddress, swap->I.alicetomic); satoshisToWei(input20.amount, swap->I.alicesatoshis); return(verifyAliceErc20PaymentData(input20, data.input)); } } char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap) { if (waitForConfirmation(swap->alicePaymentEthTx) < 0) { printf("Alice ETH payment %s is not found, can't reclaim\n", swap->alicePaymentEthTx); return NULL; } EthTxReceipt receipt = getEthTxReceipt(swap->alicePaymentEthTx); if (strcmp(receipt.status, "0x1") != 0) { printf("Alice payment receipt status failed, can't reclaim\n"); return NULL; } AliceReclaimsAlicePaymentInput input; BasicTxData txData; memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); struct iguana_info *ecoin; bits256 privkey; ecoin = LP_coinfind("ETOMIC"); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); uint8arrayToHex(input.dealId, swap->txids[BASILISK_ALICEPAYMENT].bytes, 32); satoshisToWei(input.amount, swap->destamount); if (swap->alicetomic[0] != 0) { strcpy(input.tokenAddress, swap->alicetomic); } else { strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); } strcpy(input.bobAddress, swap->etomicsrc); uint8arrayToHex(input.aliceHash, swap->secretAm, 20); bits256 invertedSecret; int32_t i; for (i=0; i<32; i++) { invertedSecret.bytes[i] = swap->privBn.bytes[31 - i]; } uint8arrayToHex(input.bobSecret, invertedSecret.bytes, 32); strcpy(txData.from, swap->etomicdest); strcpy(txData.to, ETOMIC_ALICECONTRACT); strcpy(txData.amount, "0"); uint8arrayToHex(txData.secretKey, privkey.bytes, 32); return aliceReclaimsAlicePayment(input, txData); } char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap) { if (waitForConfirmation(swap->alicePaymentEthTx) < 0) { printf("Alice ETH payment %s is not found, can't spend\n", swap->alicePaymentEthTx); return NULL; } EthTxReceipt receipt = getEthTxReceipt(swap->alicePaymentEthTx); if (strcmp(receipt.status, "0x1") != 0) { printf("Alice payment receipt status failed, can't spend\n"); return NULL; } BobSpendsAlicePaymentInput input; BasicTxData txData; memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); struct iguana_info *ecoin; bits256 privkey; ecoin = LP_coinfind("ETOMIC"); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); uint8arrayToHex(input.dealId, swap->txids[BASILISK_ALICEPAYMENT].bytes, 32); satoshisToWei(input.amount, swap->destamount); if (swap->alicetomic[0] != 0) { strcpy(input.tokenAddress, swap->alicetomic); } else { strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); } strcpy(input.aliceAddress, swap->etomicdest); bits256 invertedSecret; int32_t i; for (i=0; i<32; i++) { invertedSecret.bytes[i] = swap->privAm.bytes[31 - i]; } uint8arrayToHex(input.aliceSecret, invertedSecret.bytes, 32); uint8arrayToHex(input.bobHash, swap->secretBn, 20); strcpy(txData.from, swap->etomicsrc); strcpy(txData.to, ETOMIC_ALICECONTRACT); strcpy(txData.amount, "0"); uint8arrayToHex(txData.secretKey, privkey.bytes, 32); return bobSpendsAlicePayment(input, txData); } char *LP_etomicbob_sends_deposit(struct basilisk_swap *swap) { BobSendsEthDepositInput input; BobSendsErc20DepositInput input20; BasicTxData txData; memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); memset(&input20,0,sizeof(input20)); if ( strcmp(swap->I.bobstr,"ETH") == 0 ) { uint8arrayToHex(input.depositId, swap->bobdeposit.I.actualtxid.bytes, 32); strcpy(input.aliceAddress, swap->I.etomicdest); uint8arrayToHex(input.bobHash, swap->I.secretBn, 20); input.lockTime = swap->bobdeposit.I.locktime; strcpy(txData.from, swap->I.etomicsrc); strcpy(txData.to, ETOMIC_BOBCONTRACT); satoshisToWei(txData.amount, swap->bobdeposit.I.amount); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); return bobSendsEthDeposit(input, txData); } else { uint8arrayToHex(input20.depositId, swap->bobdeposit.I.actualtxid.bytes, 32); strcpy(input20.aliceAddress, swap->I.etomicdest); uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20); satoshisToWei(input20.amount, swap->bobdeposit.I.amount); strcpy(input20.tokenAddress, swap->I.bobtomic); input20.lockTime = swap->bobdeposit.I.locktime; strcpy(txData.from, swap->I.etomicsrc); strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.amount, "0"); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic); if (allowance < swap->bobdeposit.I.amount) { printf("Bob token allowance is too low, setting new allowance\n"); ApproveErc20Input approveErc20Input; strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic); strcpy(approveErc20Input.owner, swap->I.etomicsrc); strcpy(approveErc20Input.spender, ETOMIC_BOBCONTRACT); char *tokenBalance = getErc20BalanceHexWei(swap->I.etomicsrc, swap->I.bobtomic); strcpy(approveErc20Input.amount, tokenBalance); free(tokenBalance); strcpy(approveErc20Input.secret, txData.secretKey); char *allowTxId = approveErc20(approveErc20Input); LP_etomic_wait_for_confirmation(allowTxId); free(allowTxId); } return bobSendsErc20Deposit(input20, txData); } } uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId) { if (waitForConfirmation(txId) < 0) { printf("Bob deposit txid %s does not exist\n", txId); return(0); } EthTxData data = getEthTxData(txId); if (strcmp(data.to, ETOMIC_BOBCONTRACT) != 0) { printf("Bob deposit txid %s was sent to wrong address %s\n", txId, data.to); return(0); } if (strcmp(data.from, swap->I.etomicsrc) != 0) { printf("Bob deposit txid %s was sent from wrong address %s\n", txId, data.from); return(0); } BobSendsEthDepositInput input; BobSendsErc20DepositInput input20; memset(&input,0,sizeof(input)); memset(&input20,0,sizeof(input20)); if ( strcmp(swap->I.bobstr,"ETH") == 0 ) { uint64_t depositAmount = weiToSatoshi(data.valueHex); if (depositAmount != swap->bobdeposit.I.amount) { printf("Bob deposit %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, depositAmount, swap->bobdeposit.I.amount); return(0); } uint8arrayToHex(input.depositId, swap->bobdeposit.I.actualtxid.bytes, 32); strcpy(input.aliceAddress, swap->I.etomicdest); uint8arrayToHex(input.bobHash, swap->I.secretBn, 20); input.lockTime = swap->bobdeposit.I.locktime; return verifyBobEthDepositData(input, data.input); } else { uint8arrayToHex(input20.depositId, swap->bobdeposit.I.actualtxid.bytes, 32); strcpy(input20.aliceAddress, swap->I.etomicdest); uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20); satoshisToWei(input20.amount, swap->bobdeposit.I.amount); strcpy(input20.tokenAddress, swap->I.bobtomic); input20.lockTime = swap->bobdeposit.I.locktime; return verifyBobErc20DepositData(input20, data.input); } } char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap) { if (waitForConfirmation(swap->bobDepositEthTx) < 0) { printf("Bob deposit %s is not found, can't refund\n", swap->bobDepositEthTx); return NULL; } BobRefundsDepositInput input; BasicTxData txData; memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); struct iguana_info *ecoin; bits256 privkey; ecoin = LP_coinfind("ETOMIC"); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); EthTxReceipt receipt = getEthTxReceipt(swap->bobDepositEthTx); if (strcmp(receipt.status, "0x1") != 0) { printf("Bob deposit %s receipt status failed, can't refund\n", swap->bobDepositEthTx); return NULL; } uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32); strcpy(input.aliceAddress, swap->etomicdest); bits256 invertedSecret; int32_t i; for (i=0; i<32; i++) { invertedSecret.bytes[i] = swap->privBn.bytes[31 - i]; } uint8arrayToHex(input.bobSecret, invertedSecret.bytes, 32); if (swap->bobtomic[0] != 0) { strcpy(input.tokenAddress, swap->bobtomic); } else { strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); } satoshisToWei(input.amount, swap->values[BASILISK_BOBDEPOSIT]); strcpy(txData.from, swap->etomicsrc); strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.amount, "0"); uint8arrayToHex(txData.secretKey, privkey.bytes, 32); return bobRefundsDeposit(input, txData); } char *LP_etomicbob_sends_payment(struct basilisk_swap *swap) { BobSendsEthPaymentInput input; BobSendsErc20PaymentInput input20; BasicTxData txData; memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); memset(&input20,0,sizeof(input20)); if ( strcmp(swap->I.bobstr,"ETH") == 0 ) { uint8arrayToHex(input.paymentId, swap->bobpayment.I.actualtxid.bytes, 32); strcpy(input.aliceAddress, swap->I.etomicdest); uint8arrayToHex(input.aliceHash, swap->I.secretAm, 20); input.lockTime = swap->bobpayment.I.locktime; strcpy(txData.from, swap->I.etomicsrc); strcpy(txData.to, ETOMIC_BOBCONTRACT); satoshisToWei(txData.amount, swap->bobpayment.I.amount); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); return bobSendsEthPayment(input, txData); } else { uint8arrayToHex(input20.paymentId, swap->bobpayment.I.actualtxid.bytes, 32); strcpy(input20.aliceAddress, swap->I.etomicdest); uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20); satoshisToWei(input20.amount, swap->bobpayment.I.amount); strcpy(input20.tokenAddress, swap->I.bobtomic); input20.lockTime = swap->bobpayment.I.locktime; strcpy(txData.from, swap->I.etomicsrc); strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.amount, "0"); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic); if (allowance < swap->bobpayment.I.amount) { printf("Bob token allowance is too low, setting new allowance\n"); ApproveErc20Input approveErc20Input; strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic); strcpy(approveErc20Input.owner, swap->I.etomicsrc); strcpy(approveErc20Input.spender, ETOMIC_BOBCONTRACT); char *tokenBalance = getErc20BalanceHexWei(swap->I.etomicsrc, swap->I.bobtomic); strcpy(approveErc20Input.amount, tokenBalance); free(tokenBalance); strcpy(approveErc20Input.secret, txData.secretKey); char *allowTxId = approveErc20(approveErc20Input); LP_etomic_wait_for_confirmation(allowTxId); free(allowTxId); } return bobSendsErc20Payment(input20, txData); } } uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId) { if (waitForConfirmation(txId) < 0) { printf("Bob payment %s is not found\n", txId); return 0; } EthTxData data = getEthTxData(txId); if (strcmp(data.to, ETOMIC_BOBCONTRACT) != 0) { printf("Bob payment %s was sent to wrong address %s\n", txId, data.to); } if (strcmp(data.from, swap->I.etomicsrc) != 0) { printf("Bob payment %s was sent from wrong address %s\n", txId, data.from); } BobSendsEthPaymentInput input; BobSendsErc20PaymentInput input20; memset(&input,0,sizeof(input)); memset(&input20,0,sizeof(input20)); if ( strcmp(swap->I.bobstr,"ETH") == 0 ) { uint64_t paymentAmount = weiToSatoshi(data.valueHex); if (paymentAmount != swap->bobpayment.I.amount) { printf("Bob payment %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, paymentAmount, swap->bobpayment.I.amount); return(0); } uint8arrayToHex(input.paymentId, swap->bobpayment.I.actualtxid.bytes, 32); strcpy(input.aliceAddress, swap->I.etomicdest); uint8arrayToHex(input.aliceHash, swap->I.secretAm, 20); input.lockTime = swap->bobpayment.I.locktime; return verifyBobEthPaymentData(input, data.input); } else { uint8arrayToHex(input20.paymentId, swap->bobpayment.I.actualtxid.bytes, 32); strcpy(input20.aliceAddress, swap->I.etomicdest); uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20); satoshisToWei(input20.amount, swap->bobpayment.I.amount); strcpy(input20.tokenAddress, swap->I.bobtomic); input20.lockTime = swap->bobpayment.I.locktime; return verifyBobErc20PaymentData(input20, data.input); } } char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap) { if (waitForConfirmation(swap->bobPaymentEthTx) < 0) { printf("Bob payment %s is not found, can't reclaim\n", swap->bobPaymentEthTx); return NULL; } BobReclaimsBobPaymentInput input; BasicTxData txData; memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); struct iguana_info *ecoin; bits256 privkey; ecoin = LP_coinfind("ETOMIC"); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); EthTxReceipt receipt = getEthTxReceipt(swap->bobPaymentEthTx); if (strcmp(receipt.status, "0x1") != 0) { printf("Bob payment receipt status failed, can't reclaim\n"); return NULL; } uint8arrayToHex(input.paymentId, swap->txids[BASILISK_BOBPAYMENT].bytes, 32); strcpy(input.aliceAddress, swap->etomicdest); uint8arrayToHex(input.aliceHash, swap->secretAm, 20); if (swap->bobtomic[0] != 0) { strcpy(input.tokenAddress, swap->bobtomic); } else { strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); } satoshisToWei(input.amount, swap->values[BASILISK_BOBPAYMENT]); strcpy(txData.from, swap->etomicsrc); strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.amount, "0"); uint8arrayToHex(txData.secretKey, privkey.bytes, 32); return bobReclaimsBobPayment(input, txData); } char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap) { if (waitForConfirmation(swap->bobPaymentEthTx) < 0) { printf("Bob payment %s is not found, can't spend\n", swap->bobPaymentEthTx); return NULL; } AliceSpendsBobPaymentInput input; BasicTxData txData; memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); EthTxReceipt receipt = getEthTxReceipt(swap->bobPaymentEthTx); if (strcmp(receipt.status, "0x1") != 0) { printf("Bob payment %s receipt status failed, can't spend\n", swap->bobPaymentEthTx); return NULL; } struct iguana_info *ecoin; bits256 privkey; ecoin = LP_coinfind("ETOMIC"); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); uint8arrayToHex(input.paymentId, swap->txids[BASILISK_BOBPAYMENT].bytes, 32); satoshisToWei(input.amount, swap->values[BASILISK_BOBPAYMENT]); if (swap->bobtomic[0] != 0) { strcpy(input.tokenAddress, swap->bobtomic); } else { strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); } strcpy(input.bobAddress, swap->etomicsrc); bits256 invertedSecret; int32_t i; for (i=0; i<32; i++) { invertedSecret.bytes[i] = swap->privAm.bytes[31 - i]; } uint8arrayToHex(input.aliceSecret, invertedSecret.bytes, 32); strcpy(txData.from, swap->etomicdest); strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.amount, "0"); uint8arrayToHex(txData.secretKey, privkey.bytes, 32); return aliceSpendsBobPayment(input, txData); } char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap) { if (waitForConfirmation(swap->bobDepositEthTx) < 0) { printf("Bob deposit %s is not found, can't claim\n", swap->bobDepositEthTx); return NULL; } AliceClaimsBobDepositInput input; BasicTxData txData; memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); EthTxReceipt receipt = getEthTxReceipt(swap->bobDepositEthTx); if (strcmp(receipt.status, "0x1") != 0) { printf("Bob deposit receipt status failed, can't claim\n"); return NULL; } struct iguana_info *ecoin; bits256 privkey; ecoin = LP_coinfind("ETOMIC"); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32); satoshisToWei(input.amount, swap->values[BASILISK_BOBDEPOSIT]); if (swap->bobtomic[0] != 0) { strcpy(input.tokenAddress, swap->bobtomic); } else { strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); } strcpy(input.bobAddress, swap->etomicsrc); uint8arrayToHex(input.bobHash, swap->secretBn, 20); strcpy(txData.from, swap->etomicdest); strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.amount, "0"); uint8arrayToHex(txData.secretKey, privkey.bytes, 32); return aliceClaimsBobDeposit(input, txData); } char *sendEthTx(struct basilisk_swap *swap, struct basilisk_rawtx *rawtx) { if (rawtx == &swap->alicepayment && swap->I.alicetomic[0] != 0) { return LP_etomicalice_send_payment(swap); } else if (rawtx == &swap->bobdeposit && swap->I.bobtomic[0] != 0) { return LP_etomicbob_sends_deposit(swap); } else if (rawtx == &swap->bobpayment && swap->I.bobtomic[0] != 0) { return LP_etomicbob_sends_payment(swap); } else if (swap->I.iambob == 0 && rawtx == &swap->myfee && swap->I.alicetomic[0] != 0) { return LP_etomicalice_send_fee(swap); } else { char *result = malloc(67); strcpy(result, EMPTY_ETH_TX_ID); return result; } } int32_t LP_etomic_priv2addr(char *coinaddr,bits256 privkey) { char str[65],*addrstr; bits256_str(str,privkey); if ( (addrstr= privKey2Addr(str)) != 0 ) { strcpy(coinaddr,addrstr); free(addrstr); return(0); } return(-1); } int32_t LP_etomic_priv2pub(uint8_t *pub64,bits256 privkey) { char *pubstr,str[72]; int32_t retval = -1; bits256_str(str,privkey); if ( (pubstr= getPubKeyFromPriv(str)) != 0 ) { if ( strlen(pubstr) == 130 && pubstr[0] == '0' && pubstr[1] == 'x' ) { decode_hex(pub64,64,pubstr+2); retval = 0; } free(pubstr); } return(retval); } int32_t LP_etomic_pub2addr(char *coinaddr,uint8_t pub64[64]) { char pubkeystr[131],*addrstr; strcpy(pubkeystr,"0x"); init_hexbytes_noT(pubkeystr+2,pub64,64); if ( (addrstr= pubKey2Addr(pubkeystr)) != 0 ) { strcpy(coinaddr,addrstr); free(addrstr); return(0); } return(-1); } uint8_t LP_etomic_is_empty_tx_id(char *txId) { if (strcmp(txId, EMPTY_ETH_TX_ID) == 0) { return 1; } return 0; } uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr) { if (coin->etomic[0] == 0) { printf("Trying to get etomic balance for non-etomic coin %s!", coin->symbol); return 0; } if (strcmp(coin->symbol, "ETH") == 0) { return getEthBalance(coinaddr); } else { return getErc20BalanceSatoshi(coinaddr, coin->etomic); } }