diff --git a/app/actions/VSPActions.js b/app/actions/VSPActions.js
index 120fc29df7..12d50c637a 100644
--- a/app/actions/VSPActions.js
+++ b/app/actions/VSPActions.js
@@ -5,7 +5,7 @@ import { importScriptAttempt, rescanAttempt } from "./ControlActions";
import * as sel from "../selectors";
import * as wallet from "wallet";
import { TESTNET, MAINNET, VSP_FEE_PROCESS_ERRORED } from "constants";
-import { reverseRawHash } from "../helpers/byteActions";
+import { reverseRawHash, strHashToRaw } from "helpers";
export const GETVSP_ATTEMPT = "GETVSP_ATTEMPT";
export const GETVSP_FAILED = "GETVSP_FAILED";
@@ -64,6 +64,7 @@ export const SYNCVSPTICKETS_ATTEMPT = "SYNCVSPTICKETS_ATTEMPT";
export const SYNCVSPTICKETS_FAILED = "SYNCVSPTICKETS_FAILED";
export const SYNCVSPTICKETS_SUCCESS = "SYNCVSPTICKETS_SUCCESS";
+// syncVSPTicketsRequest syncs vsp tickets which are failed to be processed.
export const syncVSPTicketsRequest = ({ passphrase, vspHost, vspPubkey, account }) => (dispatch, getState) => {
dispatch({ type: SYNCVSPTICKETS_ATTEMPT });
wallet.syncVSPTickets(getState().grpc.walletService, passphrase, vspHost, vspPubkey, account)
@@ -76,6 +77,35 @@ export const syncVSPTicketsRequest = ({ passphrase, vspHost, vspPubkey, account
});
};
+export const SYNCVSPTICKETBYHASH_ATTEMPT = "SYNCVSPTICKETBYHASH_ATTEMPT";
+export const SYNCVSPTICKETBYHASH_FAILED = "SYNCVSPTICKETBYHASH_FAILED";
+export const SYNCVSPTICKETBYHASH_SUCCESS = "SYNCVSPTICKETBYHASH_SUCCESS";
+
+// syncVSPTicketByHash syncs vsp ticket by hash.
+export const syncVSPTicketByHash = ({
+ passphrase,
+ vspHost,
+ vspPubkey,
+ account,
+ ticketHash
+}) => (dispatch, getState) => {
+ dispatch({ type: SYNCVSPTICKETBYHASH_ATTEMPT });
+ wallet.syncVSPTickets(
+ getState().grpc.walletService,
+ passphrase,
+ vspHost,
+ vspPubkey,
+ account,
+ strHashToRaw(ticketHash)
+ )
+ .then(() => {
+ dispatch({ type: SYNCVSPTICKETBYHASH_SUCCESS });
+ dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_ERRORED));
+ })
+ .catch(error => {
+ dispatch({ type: SYNCVSPTICKETBYHASH_FAILED, error });
+ });
+};
// getTicketSignature receives the tickethash and request and sign it using the
// ticket sstxcommitment address.
diff --git a/app/components/views/TransactionPage/Page.js b/app/components/views/TransactionPage/Page.js
index 117a23790d..abd53a725a 100644
--- a/app/components/views/TransactionPage/Page.js
+++ b/app/components/views/TransactionPage/Page.js
@@ -4,8 +4,11 @@ import { KeyBlueButton } from "buttons";
import { addSpacingAroundText } from "helpers";
import { FormattedMessage as T } from "react-intl";
import { DecodedTransaction } from "middleware/walletrpc/api_pb";
+import { PassphraseModalButton } from "buttons";
+import { SyncVSPFailedTickets } from "modals";
import {
VOTE,
+ TICKET,
TRANSACTION_DIR_RECEIVED,
TRANSACTION_DIR_SENT
} from "constants/Decrediton";
@@ -37,7 +40,13 @@ const Page = ({
decodedTransaction,
abandonTransaction,
publishUnminedTransactions,
- currentBlockHeight
+ currentBlockHeight,
+ onSyncVSPTicketByHash,
+ setVSP,
+ account,
+ setAccount,
+ isValid,
+ hasVSPTicketsError
}) => {
const {
txHash,
@@ -158,6 +167,26 @@ const Page = ({
)}
+ { txType === TICKET && (
+
+ }
+ modalComponent={SyncVSPFailedTickets}
+ buttonLabel={
+
+ }
+ />
+ )
+ }
diff --git a/app/components/views/TransactionPage/TransactionPage.jsx b/app/components/views/TransactionPage/TransactionPage.jsx
index 59f0d64fb2..1d3400fbf0 100644
--- a/app/components/views/TransactionPage/TransactionPage.jsx
+++ b/app/components/views/TransactionPage/TransactionPage.jsx
@@ -4,6 +4,7 @@ import { useParams } from "react-router-dom";
import { DecredLoading } from "indicators";
import { StandalonePage } from "layout";
import { useTransactionPage } from "./hooks";
+import { useState } from "react";
function Transaction() {
const { txHash } = useParams();
@@ -13,9 +14,25 @@ function Transaction() {
currentBlockHeight,
state,
viewedTransaction,
- decodedTx
+ decodedTx,
+ syncVSPTicketByHash,
+ defaultSpendingAccount,
+ hasVSPTicketsError
} = useTransactionPage(txHash);
+ const [account, setAccount] = useState(defaultSpendingAccount);
+ const [vsp, setVSP] = useState(null);
+
+ const onSyncVSPTicketByHash = (passphrase) => {
+ syncVSPTicketByHash({
+ passphrase,
+ account: account.value,
+ vspHost: vsp.host,
+ vspPubkey: vsp.pubkey,
+ ticketHash: txHash
+ });
+ };
+
if (!viewedTransaction) return null;
switch (state.value) {
case "idle":
@@ -39,7 +56,12 @@ function Transaction() {
decodedTransaction: decodedTx,
abandonTransaction,
publishUnminedTransactions,
- currentBlockHeight
+ currentBlockHeight,
+ onSyncVSPTicketByHash,
+ setVSP,
+ account,
+ setAccount,
+ hasVSPTicketsError
}}
/>
diff --git a/app/components/views/TransactionPage/hooks.js b/app/components/views/TransactionPage/hooks.js
index 567933c6c2..1d303f1264 100644
--- a/app/components/views/TransactionPage/hooks.js
+++ b/app/components/views/TransactionPage/hooks.js
@@ -6,8 +6,10 @@ import * as sel from "selectors";
import * as ca from "actions/ControlActions";
import * as ta from "actions/TransactionActions";
import * as clia from "actions/ClientActions";
+import * as vspa from "actions/VSPActions";
export function useTransactionPage(txHash) {
+ // selectors
const regularTxs = useSelector(sel.regularTransactions);
const stakeTxs = useSelector(sel.stakeTransactions);
const decodedTransactions = useSelector(sel.decodedTransactions);
@@ -16,7 +18,10 @@ export function useTransactionPage(txHash) {
decodedTransactions[txHash]
);
const currentBlockHeight = useSelector(sel.currentBlockHeight);
+ const defaultSpendingAccount = useSelector(sel.defaultSpendingAccount);
+ const hasVSPTicketsError = useSelector(sel.getHasVSPTicketsError);
+ // actions
const dispatch = useDispatch();
const abandonTransaction = useCallback((txHash) => {
dispatch(clia.abandonTransactionAttempt(txHash));
@@ -35,6 +40,11 @@ export function useTransactionPage(txHash) {
dispatch(ca.publishUnminedTransactionsAttempt()),
[dispatch]
);
+
+ const syncVSPTicketByHash = ({ passphrase, vspHost, vspPubkey, account, ticketHash }) =>
+ dispatch(vspa.syncVSPTicketByHash({ passphrase, vspHost, vspPubkey, account, ticketHash }));
+
+ // state machine actions
const [state, send] = useMachine(fetchMachine, {
actions: {
initial: () => {
@@ -78,6 +88,9 @@ export function useTransactionPage(txHash) {
currentBlockHeight,
state,
viewedTransaction,
- decodedTx
+ decodedTx,
+ syncVSPTicketByHash,
+ defaultSpendingAccount,
+ hasVSPTicketsError
};
}
diff --git a/app/middleware/api.proto b/app/middleware/api.proto
index 2cbb9298eb..f101597b01 100644
--- a/app/middleware/api.proto
+++ b/app/middleware/api.proto
@@ -79,6 +79,7 @@ service WalletService {
rpc LockWallet (LockWalletRequest) returns (LockWalletResponse);
rpc SyncVSPFailedTickets(SyncVSPTicketsRequest) returns (SyncVSPTicketsResponse);
rpc GetVSPTicketsByFeeStatus (GetVSPTicketsByFeeStatusRequest) returns (GetVSPTicketsByFeeStatusResponse);
+ rpc SyncVSPTicketByHash (SyncVSPTicketByHashRequest) returns (SyncVSPTicketByHashResponse);
}
service WalletLoaderService {
@@ -1272,3 +1273,12 @@ message GetVSPTicketsByFeeStatusRequest {
message GetVSPTicketsByFeeStatusResponse {
repeated bytes tickets_hashes = 1;
}
+
+message SyncVSPTicketByHashRequest {
+ string vsp_host = 1;
+ string vsp_pubkey = 2;
+ uint32 account = 3;
+ bytes ticket_hash = 4;
+}
+
+message SyncVSPTicketByHashResponse {}
diff --git a/app/middleware/walletrpc/api_grpc_pb.js b/app/middleware/walletrpc/api_grpc_pb.js
index 73f94e1138..6238e0161d 100644
--- a/app/middleware/walletrpc/api_grpc_pb.js
+++ b/app/middleware/walletrpc/api_grpc_pb.js
@@ -1621,6 +1621,28 @@ function deserialize_walletrpc_SweepAccountResponse(buffer_arg) {
return api_pb.SweepAccountResponse.deserializeBinary(new Uint8Array(buffer_arg));
}
+function serialize_walletrpc_SyncVSPTicketByHashRequest(arg) {
+ if (!(arg instanceof api_pb.SyncVSPTicketByHashRequest)) {
+ throw new Error('Expected argument of type walletrpc.SyncVSPTicketByHashRequest');
+ }
+ return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_walletrpc_SyncVSPTicketByHashRequest(buffer_arg) {
+ return api_pb.SyncVSPTicketByHashRequest.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_walletrpc_SyncVSPTicketByHashResponse(arg) {
+ if (!(arg instanceof api_pb.SyncVSPTicketByHashResponse)) {
+ throw new Error('Expected argument of type walletrpc.SyncVSPTicketByHashResponse');
+ }
+ return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_walletrpc_SyncVSPTicketByHashResponse(buffer_arg) {
+ return api_pb.SyncVSPTicketByHashResponse.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
function serialize_walletrpc_SyncVSPTicketsRequest(arg) {
if (!(arg instanceof api_pb.SyncVSPTicketsRequest)) {
throw new Error('Expected argument of type walletrpc.SyncVSPTicketsRequest');
@@ -2510,6 +2532,17 @@ changePassphrase: {
responseSerialize: serialize_walletrpc_GetVSPTicketsByFeeStatusResponse,
responseDeserialize: deserialize_walletrpc_GetVSPTicketsByFeeStatusResponse,
},
+ syncVSPTicketByHash: {
+ path: '/walletrpc.WalletService/SyncVSPTicketByHash',
+ requestStream: false,
+ responseStream: false,
+ requestType: api_pb.SyncVSPTicketByHashRequest,
+ responseType: api_pb.SyncVSPTicketByHashResponse,
+ requestSerialize: serialize_walletrpc_SyncVSPTicketByHashRequest,
+ requestDeserialize: deserialize_walletrpc_SyncVSPTicketByHashRequest,
+ responseSerialize: serialize_walletrpc_SyncVSPTicketByHashResponse,
+ responseDeserialize: deserialize_walletrpc_SyncVSPTicketByHashResponse,
+ },
};
exports.WalletServiceClient = grpc.makeGenericClientConstructor(WalletServiceService);
diff --git a/app/middleware/walletrpc/api_pb.js b/app/middleware/walletrpc/api_pb.js
index ea856df377..e28f089a51 100644
--- a/app/middleware/walletrpc/api_pb.js
+++ b/app/middleware/walletrpc/api_pb.js
@@ -206,6 +206,8 @@ goog.exportSymbol('proto.walletrpc.SubscribeToBlockNotificationsResponse', null,
goog.exportSymbol('proto.walletrpc.SweepAccountRequest', null, global);
goog.exportSymbol('proto.walletrpc.SweepAccountResponse', null, global);
goog.exportSymbol('proto.walletrpc.SyncNotificationType', null, global);
+goog.exportSymbol('proto.walletrpc.SyncVSPTicketByHashRequest', null, global);
+goog.exportSymbol('proto.walletrpc.SyncVSPTicketByHashResponse', null, global);
goog.exportSymbol('proto.walletrpc.SyncVSPTicketsRequest', null, global);
goog.exportSymbol('proto.walletrpc.SyncVSPTicketsResponse', null, global);
goog.exportSymbol('proto.walletrpc.TicketBuyerConfigRequest', null, global);
@@ -42839,6 +42841,369 @@ proto.walletrpc.GetVSPTicketsByFeeStatusResponse.prototype.clearTicketsHashesLis
};
+
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest = function(opt_data) {
+ jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.walletrpc.SyncVSPTicketByHashRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+ proto.walletrpc.SyncVSPTicketByHashRequest.displayName = 'proto.walletrpc.SyncVSPTicketByHashRequest';
+}
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto suitable for use in Soy templates.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * To access a reserved field use, foo.pb_, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
+ * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
+ * for transitional soy proto support: http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest.prototype.toObject = function(opt_includeInstance) {
+ return proto.walletrpc.SyncVSPTicketByHashRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Whether to include the JSPB
+ * instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @param {!proto.walletrpc.SyncVSPTicketByHashRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest.toObject = function(includeInstance, msg) {
+ var f, obj = {
+ vspHost: jspb.Message.getFieldWithDefault(msg, 1, ""),
+ vspPubkey: jspb.Message.getFieldWithDefault(msg, 2, ""),
+ account: jspb.Message.getFieldWithDefault(msg, 3, 0),
+ ticketHash: msg.getTicketHash_asB64()
+ };
+
+ if (includeInstance) {
+ obj.$jspbMessageInstance = msg;
+ }
+ return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.walletrpc.SyncVSPTicketByHashRequest}
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest.deserializeBinary = function(bytes) {
+ var reader = new jspb.BinaryReader(bytes);
+ var msg = new proto.walletrpc.SyncVSPTicketByHashRequest;
+ return proto.walletrpc.SyncVSPTicketByHashRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.walletrpc.SyncVSPTicketByHashRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.walletrpc.SyncVSPTicketByHashRequest}
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest.deserializeBinaryFromReader = function(msg, reader) {
+ while (reader.nextField()) {
+ if (reader.isEndGroup()) {
+ break;
+ }
+ var field = reader.getFieldNumber();
+ switch (field) {
+ case 1:
+ var value = /** @type {string} */ (reader.readString());
+ msg.setVspHost(value);
+ break;
+ case 2:
+ var value = /** @type {string} */ (reader.readString());
+ msg.setVspPubkey(value);
+ break;
+ case 3:
+ var value = /** @type {number} */ (reader.readUint32());
+ msg.setAccount(value);
+ break;
+ case 4:
+ var value = /** @type {!Uint8Array} */ (reader.readBytes());
+ msg.setTicketHash(value);
+ break;
+ default:
+ reader.skipField();
+ break;
+ }
+ }
+ return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest.prototype.serializeBinary = function() {
+ var writer = new jspb.BinaryWriter();
+ proto.walletrpc.SyncVSPTicketByHashRequest.serializeBinaryToWriter(this, writer);
+ return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.walletrpc.SyncVSPTicketByHashRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest.serializeBinaryToWriter = function(message, writer) {
+ var f = undefined;
+ f = message.getVspHost();
+ if (f.length > 0) {
+ writer.writeString(
+ 1,
+ f
+ );
+ }
+ f = message.getVspPubkey();
+ if (f.length > 0) {
+ writer.writeString(
+ 2,
+ f
+ );
+ }
+ f = message.getAccount();
+ if (f !== 0) {
+ writer.writeUint32(
+ 3,
+ f
+ );
+ }
+ f = message.getTicketHash_asU8();
+ if (f.length > 0) {
+ writer.writeBytes(
+ 4,
+ f
+ );
+ }
+};
+
+
+/**
+ * optional string vsp_host = 1;
+ * @return {string}
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest.prototype.getVspHost = function() {
+ return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/** @param {string} value */
+proto.walletrpc.SyncVSPTicketByHashRequest.prototype.setVspHost = function(value) {
+ jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string vsp_pubkey = 2;
+ * @return {string}
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest.prototype.getVspPubkey = function() {
+ return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/** @param {string} value */
+proto.walletrpc.SyncVSPTicketByHashRequest.prototype.setVspPubkey = function(value) {
+ jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional uint32 account = 3;
+ * @return {number}
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest.prototype.getAccount = function() {
+ return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/** @param {number} value */
+proto.walletrpc.SyncVSPTicketByHashRequest.prototype.setAccount = function(value) {
+ jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional bytes ticket_hash = 4;
+ * @return {!(string|Uint8Array)}
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest.prototype.getTicketHash = function() {
+ return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * optional bytes ticket_hash = 4;
+ * This is a type-conversion wrapper around `getTicketHash()`
+ * @return {string}
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest.prototype.getTicketHash_asB64 = function() {
+ return /** @type {string} */ (jspb.Message.bytesAsB64(
+ this.getTicketHash()));
+};
+
+
+/**
+ * optional bytes ticket_hash = 4;
+ * Note that Uint8Array is not supported on all browsers.
+ * @see http://caniuse.com/Uint8Array
+ * This is a type-conversion wrapper around `getTicketHash()`
+ * @return {!Uint8Array}
+ */
+proto.walletrpc.SyncVSPTicketByHashRequest.prototype.getTicketHash_asU8 = function() {
+ return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
+ this.getTicketHash()));
+};
+
+
+/** @param {!(string|Uint8Array)} value */
+proto.walletrpc.SyncVSPTicketByHashRequest.prototype.setTicketHash = function(value) {
+ jspb.Message.setProto3BytesField(this, 4, value);
+};
+
+
+
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.walletrpc.SyncVSPTicketByHashResponse = function(opt_data) {
+ jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.walletrpc.SyncVSPTicketByHashResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+ proto.walletrpc.SyncVSPTicketByHashResponse.displayName = 'proto.walletrpc.SyncVSPTicketByHashResponse';
+}
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto suitable for use in Soy templates.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * To access a reserved field use, foo.pb_, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
+ * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
+ * for transitional soy proto support: http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.walletrpc.SyncVSPTicketByHashResponse.prototype.toObject = function(opt_includeInstance) {
+ return proto.walletrpc.SyncVSPTicketByHashResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Whether to include the JSPB
+ * instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @param {!proto.walletrpc.SyncVSPTicketByHashResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.walletrpc.SyncVSPTicketByHashResponse.toObject = function(includeInstance, msg) {
+ var f, obj = {
+
+ };
+
+ if (includeInstance) {
+ obj.$jspbMessageInstance = msg;
+ }
+ return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.walletrpc.SyncVSPTicketByHashResponse}
+ */
+proto.walletrpc.SyncVSPTicketByHashResponse.deserializeBinary = function(bytes) {
+ var reader = new jspb.BinaryReader(bytes);
+ var msg = new proto.walletrpc.SyncVSPTicketByHashResponse;
+ return proto.walletrpc.SyncVSPTicketByHashResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.walletrpc.SyncVSPTicketByHashResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.walletrpc.SyncVSPTicketByHashResponse}
+ */
+proto.walletrpc.SyncVSPTicketByHashResponse.deserializeBinaryFromReader = function(msg, reader) {
+ while (reader.nextField()) {
+ if (reader.isEndGroup()) {
+ break;
+ }
+ var field = reader.getFieldNumber();
+ switch (field) {
+ default:
+ reader.skipField();
+ break;
+ }
+ }
+ return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.walletrpc.SyncVSPTicketByHashResponse.prototype.serializeBinary = function() {
+ var writer = new jspb.BinaryWriter();
+ proto.walletrpc.SyncVSPTicketByHashResponse.serializeBinaryToWriter(this, writer);
+ return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.walletrpc.SyncVSPTicketByHashResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.walletrpc.SyncVSPTicketByHashResponse.serializeBinaryToWriter = function(message, writer) {
+ var f = undefined;
+};
+
+
/**
* @enum {number}
*/
diff --git a/app/wallet/control.js b/app/wallet/control.js
index c08df5ac9e..82568a5e45 100644
--- a/app/wallet/control.js
+++ b/app/wallet/control.js
@@ -190,7 +190,7 @@ export const purchaseTickets = (
request.setDontSignTx(!signTx);
const { pubkey, host } = vsp;
request.setVspPubkey(pubkey);
- request.setVspHost("https://" + host);
+ request.setVspHost("http://" + host);
walletService.purchaseTickets(request, (error, response) => {
if (error) {
reject(error);
@@ -306,11 +306,7 @@ export const syncVSPTickets = (walletService, passphrase, vspHost, vspPubkey, ac
reject(error);
}
const request = new api.SyncVSPTicketsRequest();
- console.log(vspHost);
- console.log(vspPubkey);
- console.log(account);
- console.log(walletService);
request.setAccount(account);
request.setVspPubkey(vspPubkey);
request.setVspHost("https://" + vspHost);
@@ -333,6 +329,42 @@ export const syncVSPTickets = (walletService, passphrase, vspHost, vspPubkey, ac
});
});
+export const syncVSPTicketByHash = (walletService, passphrase, vspHost, vspPubkey, account, ticketHash) =>
+ new Promise((resolve, reject) => {
+ // console.log(walletService)
+ const unlockReq = new api.UnlockWalletRequest();
+ // console.log(unlockReq)
+ unlockReq.setPassphrase(new Uint8Array(Buffer.from(passphrase)));
+ // Unlock wallet so we can call the request.
+ walletService.unlockWallet(unlockReq, (error) => {
+ if (error) {
+ reject(error);
+ }
+ const request = new api.SyncVSPTicketsRequest();
+
+ request.setAccount(account);
+ request.setVspPubkey(vspPubkey);
+ request.setVspHost("https://" + vspHost);
+ request.setTicketHash(ticketHash);
+
+ // Call the request
+ walletService.syncVSPTicketByHash(request, (error, response) => {
+ if (error) {
+ reject(error);
+ }
+ const lockReq = new api.LockWalletRequest();
+
+ // Lock wallet and return response from the request.
+ walletService.lockWallet(lockReq, (error) => {
+ if (error) {
+ reject(error);
+ }
+ resolve(response);
+ });
+ });
+ });
+ });
+
export const getPeerInfo = (walletService) => new Promise((ok, fail) => {
const request = new api.GetPeerInfoRequest();
walletService.getPeerInfo(request, (err, res) =>