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) =>