Browse Source

Added API call POST /crosschain/btc/send for sending Bitcoin

split-DB
catbref 4 years ago
parent
commit
9007dfe779
  1. 25
      src/main/java/org/qortal/api/model/BitcoinSendRequest.java
  2. 2
      src/main/java/org/qortal/api/model/TradeBotCreateRequest.java
  3. 52
      src/main/java/org/qortal/api/resource/CrossChainResource.java

25
src/main/java/org/qortal/api/model/BitcoinSendRequest.java

@ -0,0 +1,25 @@
package org.qortal.api.model;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import io.swagger.v3.oas.annotations.media.Schema;
@XmlAccessorType(XmlAccessType.FIELD)
public class BitcoinSendRequest {
@Schema(description = "Bitcoin BIP32 extended private key", example = "tprv8ZgxMBicQKsPdahhFSrCdvC1bsWyzHHZfTneTVqUXN6s1wEtZLwAkZXzFP6TbTVGajEB55L1HYLg2aQMecZLXLre5YJcawpdFG66STVAWPJ")
public String xprv58;
@Schema(description = "Recipient's Bitcoin address ('legacy' P2PKH only)", example = "1BitcoinEaterAddressDontSendf59kuE")
public String receivingAddress;
@Schema(description = "Amount of BTC to send")
@XmlJavaTypeAdapter(value = org.qortal.api.AmountTypeAdapter.class)
public long bitcoinAmount;
public BitcoinSendRequest() {
}
}

2
src/main/java/org/qortal/api/model/TradeBotCreateRequest.java

@ -27,7 +27,7 @@ public class TradeBotCreateRequest {
@Schema(description = "Suggested trade timeout (minutes)", example = "10080")
public int tradeTimeout;
@Schema(description = "Bitcoin address for receiving", example = "1NCTG9oLk41bU6pcehLNo9DVJup77EHAVx")
@Schema(description = "Bitcoin address for receiving", example = "1BitcoinEaterAddressDontSendf59kuE")
public String receivingAddress;
public TradeBotCreateRequest() {

52
src/main/java/org/qortal/api/resource/CrossChainResource.java

@ -46,6 +46,7 @@ import org.qortal.api.model.CrossChainTradeRequest;
import org.qortal.api.model.CrossChainTradeSummary;
import org.qortal.api.model.TradeBotCreateRequest;
import org.qortal.api.model.TradeBotRespondRequest;
import org.qortal.api.model.BitcoinSendRequest;
import org.qortal.api.model.CrossChainBitcoinP2SHStatus;
import org.qortal.api.model.CrossChainBitcoinRedeemRequest;
import org.qortal.api.model.CrossChainBitcoinRefundRequest;
@ -947,6 +948,57 @@ public class CrossChainResource {
return balance.toString();
}
@POST
@Path("/btc/send")
@Operation(
summary = "Sends BTC from BIP32 wallet to specific address",
description = "Currently only supports 'legacy' P2PKH Bitcoin addresses. Supply BIP32 'm' private key in base58, starting with 'xprv' for mainnet, 'tprv' for testnet",
requestBody = @RequestBody(
required = true,
content = @Content(
mediaType = MediaType.APPLICATION_JSON,
schema = @Schema(
implementation = BitcoinSendRequest.class
)
)
),
responses = {
@ApiResponse(
content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string"))
)
}
)
@ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.INVALID_CRITERIA, ApiError.INVALID_ADDRESS, ApiError.BTC_BALANCE_ISSUE, ApiError.BTC_NETWORK_ISSUE})
public String sendBitcoin(BitcoinSendRequest bitcoinSendRequest) {
Security.checkApiCallAllowed(request);
if (bitcoinSendRequest.bitcoinAmount <= 0)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA);
Address receivingAddress;
try {
receivingAddress = Address.fromString(BTC.getInstance().getNetworkParameters(), bitcoinSendRequest.receivingAddress);
} catch (AddressFormatException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ADDRESS);
}
// We only support P2PKH addresses at this time
if (receivingAddress.getOutputScriptType() != ScriptType.P2PKH)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ADDRESS);
if (!BTC.getInstance().isValidXprv(bitcoinSendRequest.xprv58))
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_PRIVATE_KEY);
org.bitcoinj.core.Transaction spendTransaction = BTC.getInstance().buildSpend(bitcoinSendRequest.xprv58, bitcoinSendRequest.receivingAddress, bitcoinSendRequest.bitcoinAmount);
if (spendTransaction == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BTC_BALANCE_ISSUE);
if (!BTC.getInstance().broadcastTransaction(spendTransaction))
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BTC_NETWORK_ISSUE);
return "true";
}
@GET
@Path("/tradebot")
@Operation(

Loading…
Cancel
Save