mirror of
https://github.com/Qortal/qortal.git
synced 2025-03-15 11:52:32 +00:00
Added API call POST /crosschain/btc/send for sending Bitcoin
This commit is contained in:
parent
99d09a9877
commit
9007dfe779
25
src/main/java/org/qortal/api/model/BitcoinSendRequest.java
Normal file
25
src/main/java/org/qortal/api/model/BitcoinSendRequest.java
Normal file
@ -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() {
|
||||
}
|
||||
|
||||
}
|
@ -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() {
|
||||
|
@ -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…
x
Reference in New Issue
Block a user