diff --git a/doc/api/wallet_owner_api.md b/doc/api/wallet_owner_api.md
index ab0d92b07..70562de08 100644
--- a/doc/api/wallet_owner_api.md
+++ b/doc/api/wallet_owner_api.md
@@ -12,6 +12,7 @@
1. [POST Finalize Tx](#post-finalize-tx)
1. [POST Cancel Tx](#post-cancel-tx)
1. [POST Post Tx](#post-post-tx)
+ 1. [POST Repost Tx](#post-repost-tx)
1. [POST Issue Burn Tx](#post-issue-burn-tx)
1. [Adding Foreign API Endpoints](#add-foreign-api-endpoints)
@@ -641,6 +642,50 @@ Push new transaction to the connected node transaction pool. Add `?fluff` at the
},
});
```
+### POST Repost Tx
+
+Repost a `sending` transaction to the connected node transaction pool with a given transaction id. Add `?fluff` at the end of the URL to bypass Dandelion relay . This could be used for retry posting when a `sending` transaction is created but somehow failed on posting.
+
+* **URL**
+
+ * /v1/wallet/owner/repost?id=x
+ * /v1/wallet/owner/repost?tx_id=x
+ * /v1/wallet/owner/repost?fluff&tx_id=x
+
+* **Method:**
+
+ `POST`
+
+* **URL Params**
+
+ **Required:**
+ * `id=[number]` the transaction id
+ * `tx_id=[string]`the transaction slate id
+
+* **Data Params**
+
+ None
+
+* **Success Response:**
+
+ * **Code:** 200
+
+* **Error Response:**
+
+ * **Code:** 400
+
+* **Sample Call:**
+
+ ```javascript
+ $.ajax({
+ url: "/v1/wallet/owner/repost?id=3",
+ dataType: "json",
+ type : "POST",
+ success : function(r) {
+ console.log(r);
+ }
+ });
+ ```
### POST Issue Burn Tx
diff --git a/wallet/src/controller.rs b/wallet/src/controller.rs
index 1bbf1a268..94cb82614 100644
--- a/wallet/src/controller.rs
+++ b/wallet/src/controller.rs
@@ -40,6 +40,7 @@ use std::marker::PhantomData;
use std::net::SocketAddr;
use std::sync::Arc;
use url::form_urlencoded;
+use uuid::Uuid;
/// Instantiate wallet Owner API for a single-use (command line) call
/// Return a function containing a loaded API context to call
@@ -467,6 +468,87 @@ where
))
}
+ pub fn repost(
+ &self,
+ req: Request
,
+ api: APIOwner,
+ ) -> Box + Send> {
+ let params = parse_params(&req);
+ let mut id_int: Option = None;
+ let mut tx_uuid: Option = None;
+
+ if let Some(id_string) = params.get("id") {
+ match id_string[0].parse() {
+ Ok(id) => id_int = Some(id),
+ Err(e) => {
+ error!("repost: could not parse id: {}", e);
+ return Box::new(err(ErrorKind::GenericError(
+ "repost: cannot repost transaction. Could not parse id in request."
+ .to_owned(),
+ )
+ .into()));
+ }
+ }
+ } else if let Some(tx_id_string) = params.get("tx_id") {
+ match tx_id_string[0].parse() {
+ Ok(tx_id) => tx_uuid = Some(tx_id),
+ Err(e) => {
+ error!("repost: could not parse tx_id: {}", e);
+ return Box::new(err(ErrorKind::GenericError(
+ "repost: cannot repost transaction. Could not parse tx_id in request."
+ .to_owned(),
+ )
+ .into()));
+ }
+ }
+ } else {
+ return Box::new(err(ErrorKind::GenericError(
+ "repost: Cannot repost transaction. Missing id or tx_id param in request."
+ .to_owned(),
+ )
+ .into()));
+ }
+
+ let res = api.retrieve_txs(true, id_int, tx_uuid);
+ if let Err(e) = res {
+ return Box::new(err(ErrorKind::GenericError(format!(
+ "repost: cannot repost transaction. retrieve_txs failed, err: {:?}",
+ e
+ ))
+ .into()));
+ }
+ let (_, txs) = res.unwrap();
+ let res = api.get_stored_tx(&txs[0]);
+ if let Err(e) = res {
+ return Box::new(err(ErrorKind::GenericError(format!(
+ "repost: cannot repost transaction. get_stored_tx failed, err: {:?}",
+ e
+ ))
+ .into()));
+ }
+ let stored_tx = res.unwrap();
+ if stored_tx.is_none() {
+ error!(
+ "Transaction with id {:?}/{:?} does not have transaction data. Not reposting.",
+ id_int, tx_uuid,
+ );
+ return Box::new(err(ErrorKind::GenericError(
+ "repost: Cannot repost transaction. Missing id or tx_id param in request."
+ .to_owned(),
+ )
+ .into()));
+ }
+
+ let fluff = params.get("fluff").is_some();
+ Box::new(match api.post_tx(&stored_tx.unwrap(), fluff) {
+ Ok(_) => ok(()),
+ Err(e) => {
+ error!("repost: failed with error: {}", e);
+ err(e)
+ }
+ })
+ }
+
fn handle_post_request(&self, req: Request) -> WalletResponseFuture {
let api = APIOwner::new(self.wallet.clone());
match req
@@ -493,6 +575,10 @@ where
self.post_tx(req, api)
.and_then(|_| ok(response(StatusCode::OK, "{}"))),
),
+ "repost" => Box::new(
+ self.repost(req, api)
+ .and_then(|_| ok(response(StatusCode::OK, ""))),
+ ),
_ => Box::new(err(ErrorKind::GenericError(
"Unknown error handling post request".to_owned(),
)