fix terminology, better types
This commit is contained in:
parent
26467674ba
commit
29b107f937
138
node_modules/nyc/node_modules/yargs/package.json
generated
vendored
138
node_modules/nyc/node_modules/yargs/package.json
generated
vendored
File diff suppressed because one or more lines are too long
@ -54,7 +54,7 @@ test("amount subtraction (saturation)", (t) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test("contract validation", (t) => {
|
test("contract terms validation", (t) => {
|
||||||
const c = {
|
const c = {
|
||||||
H_wire: "123",
|
H_wire: "123",
|
||||||
amount: amt(1, 2, "EUR"),
|
amount: amt(1, 2, "EUR"),
|
||||||
@ -73,13 +73,13 @@ test("contract validation", (t) => {
|
|||||||
wire_method: "test",
|
wire_method: "test",
|
||||||
};
|
};
|
||||||
|
|
||||||
types.Contract.checked(c);
|
types.ContractTerms.checked(c);
|
||||||
|
|
||||||
const c1 = JSON.parse(JSON.stringify(c));
|
const c1 = JSON.parse(JSON.stringify(c));
|
||||||
c1.exchanges = [];
|
c1.exchanges = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
types.Contract.checked(c1);
|
types.ContractTerms.checked(c1);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
t.pass();
|
t.pass();
|
||||||
return;
|
return;
|
||||||
|
58
src/types.ts
58
src/types.ts
@ -903,10 +903,10 @@ export interface WalletBalanceEntry {
|
|||||||
* Contract terms from a merchant.
|
* Contract terms from a merchant.
|
||||||
*/
|
*/
|
||||||
@Checkable.Class({validate: true})
|
@Checkable.Class({validate: true})
|
||||||
export class Contract {
|
export class ContractTerms {
|
||||||
validate() {
|
validate() {
|
||||||
if (this.exchanges.length === 0) {
|
if (this.exchanges.length === 0) {
|
||||||
throw Error("no exchanges in contract");
|
throw Error("no exchanges in contract terms");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1042,7 +1042,7 @@ export class Contract {
|
|||||||
* Verify that a value matches the schema of this class and convert it into a
|
* Verify that a value matches the schema of this class and convert it into a
|
||||||
* member.
|
* member.
|
||||||
*/
|
*/
|
||||||
static checked: (obj: any) => Contract;
|
static checked: (obj: any) => ContractTerms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1054,8 +1054,8 @@ export class ProposalRecord {
|
|||||||
/**
|
/**
|
||||||
* The contract that was offered by the merchant.
|
* The contract that was offered by the merchant.
|
||||||
*/
|
*/
|
||||||
@Checkable.Value(Contract)
|
@Checkable.Value(ContractTerms)
|
||||||
contractTerms: Contract;
|
contractTerms: ContractTerms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signature by the merchant over the contract details.
|
* Signature by the merchant over the contract details.
|
||||||
@ -1398,3 +1398,51 @@ export interface HistoryRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment body sent to the merchant's /pay.
|
||||||
|
*/
|
||||||
|
export interface PayReq {
|
||||||
|
/**
|
||||||
|
* Coins with signature.
|
||||||
|
*/
|
||||||
|
coins: CoinPaySig[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The merchant public key, used to uniquely
|
||||||
|
* identify the merchant instance.
|
||||||
|
*/
|
||||||
|
merchant_pub: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Order ID that's being payed for.
|
||||||
|
*/
|
||||||
|
order_id: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exchange that the coins are from.
|
||||||
|
*/
|
||||||
|
exchange: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response to a query payment request. Tagged union over the 'found' field.
|
||||||
|
*/
|
||||||
|
export type QueryPaymentResult = QueryPaymentNotFound | QueryPaymentFound;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query payment response when the payment was found.
|
||||||
|
*/
|
||||||
|
export interface QueryPaymentNotFound {
|
||||||
|
found: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query payment response when the payment wasn't found.
|
||||||
|
*/
|
||||||
|
export interface QueryPaymentFound {
|
||||||
|
found: true;
|
||||||
|
contractTermsHash: string;
|
||||||
|
contractTerms: ContractTerms;
|
||||||
|
payReq: PayReq;
|
||||||
|
}
|
||||||
|
@ -47,11 +47,10 @@ import {
|
|||||||
Amounts,
|
Amounts,
|
||||||
Auditor,
|
Auditor,
|
||||||
CheckPayResult,
|
CheckPayResult,
|
||||||
CoinPaySig,
|
|
||||||
CoinRecord,
|
CoinRecord,
|
||||||
CoinStatus,
|
CoinStatus,
|
||||||
ConfirmPayResult,
|
ConfirmPayResult,
|
||||||
Contract,
|
ContractTerms,
|
||||||
CreateReserveResponse,
|
CreateReserveResponse,
|
||||||
CurrencyRecord,
|
CurrencyRecord,
|
||||||
Denomination,
|
Denomination,
|
||||||
@ -63,10 +62,12 @@ import {
|
|||||||
HistoryLevel,
|
HistoryLevel,
|
||||||
HistoryRecord,
|
HistoryRecord,
|
||||||
Notifier,
|
Notifier,
|
||||||
ProposalRecord,
|
|
||||||
PayCoinInfo,
|
PayCoinInfo,
|
||||||
|
PayReq,
|
||||||
PaybackConfirmation,
|
PaybackConfirmation,
|
||||||
PreCoinRecord,
|
PreCoinRecord,
|
||||||
|
ProposalRecord,
|
||||||
|
QueryPaymentResult,
|
||||||
RefreshSessionRecord,
|
RefreshSessionRecord,
|
||||||
ReserveCreationInfo,
|
ReserveCreationInfo,
|
||||||
ReserveRecord,
|
ReserveRecord,
|
||||||
@ -272,16 +273,9 @@ export class ConfirmReserveRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface PayReq {
|
|
||||||
coins: CoinPaySig[];
|
|
||||||
merchant_pub: string;
|
|
||||||
order_id: string;
|
|
||||||
exchange: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TransactionRecord {
|
interface TransactionRecord {
|
||||||
contractHash: string;
|
contractTermsHash: string;
|
||||||
contract: Contract;
|
contractTerms: ContractTerms;
|
||||||
payReq: PayReq;
|
payReq: PayReq;
|
||||||
merchantSig: string;
|
merchantSig: string;
|
||||||
|
|
||||||
@ -518,11 +512,11 @@ export namespace Stores {
|
|||||||
|
|
||||||
class TransactionsStore extends Store<TransactionRecord> {
|
class TransactionsStore extends Store<TransactionRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("transactions", {keyPath: "contractHash"});
|
super("transactions", {keyPath: "contractTermsHash"});
|
||||||
}
|
}
|
||||||
|
|
||||||
fulfillmentUrlIndex = new Index<string, TransactionRecord>(this, "fulfillment_url", "contract.fulfillment_url");
|
fulfillmentUrlIndex = new Index<string, TransactionRecord>(this, "fulfillment_url", "contractTerms.fulfillment_url");
|
||||||
orderIdIndex = new Index<string, TransactionRecord>(this, "order_id", "contract.order_id");
|
orderIdIndex = new Index<string, TransactionRecord>(this, "order_id", "contractTerms.order_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
class DenominationsStore extends Store<DenominationRecord> {
|
class DenominationsStore extends Store<DenominationRecord> {
|
||||||
@ -832,7 +826,7 @@ export class Wallet {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Record all information that is necessary to
|
* Record all information that is necessary to
|
||||||
* pay for a contract in the wallet's database.
|
* pay for a proposal in the wallet's database.
|
||||||
*/
|
*/
|
||||||
private async recordConfirmPay(proposal: ProposalRecord,
|
private async recordConfirmPay(proposal: ProposalRecord,
|
||||||
payCoinInfo: PayCoinInfo,
|
payCoinInfo: PayCoinInfo,
|
||||||
@ -844,8 +838,8 @@ export class Wallet {
|
|||||||
order_id: proposal.contractTerms.order_id,
|
order_id: proposal.contractTerms.order_id,
|
||||||
};
|
};
|
||||||
const t: TransactionRecord = {
|
const t: TransactionRecord = {
|
||||||
contract: proposal.contractTerms,
|
contractTerms: proposal.contractTerms,
|
||||||
contractHash: proposal.contractTermsHash,
|
contractTermsHash: proposal.contractTermsHash,
|
||||||
finished: false,
|
finished: false,
|
||||||
merchantSig: proposal.merchantSig,
|
merchantSig: proposal.merchantSig,
|
||||||
payReq,
|
payReq,
|
||||||
@ -854,7 +848,7 @@ export class Wallet {
|
|||||||
const historyEntry: HistoryRecord = {
|
const historyEntry: HistoryRecord = {
|
||||||
detail: {
|
detail: {
|
||||||
amount: proposal.contractTerms.amount,
|
amount: proposal.contractTerms.amount,
|
||||||
contractHash: proposal.contractTermsHash,
|
contractTermsHash: proposal.contractTermsHash,
|
||||||
fulfillmentUrl: proposal.contractTerms.fulfillment_url,
|
fulfillmentUrl: proposal.contractTerms.fulfillment_url,
|
||||||
merchantName: proposal.contractTerms.merchant.name,
|
merchantName: proposal.contractTerms.merchant.name,
|
||||||
},
|
},
|
||||||
@ -980,7 +974,7 @@ export class Wallet {
|
|||||||
* Retrieve information required to pay for a contract, where the
|
* Retrieve information required to pay for a contract, where the
|
||||||
* contract is identified via the fulfillment url.
|
* contract is identified via the fulfillment url.
|
||||||
*/
|
*/
|
||||||
async queryPayment(url: string): Promise<any> {
|
async queryPayment(url: string): Promise<QueryPaymentResult> {
|
||||||
console.log("query for payment", url);
|
console.log("query for payment", url);
|
||||||
|
|
||||||
const t = await this.q().getIndexed(Stores.transactions.fulfillmentUrlIndex, url);
|
const t = await this.q().getIndexed(Stores.transactions.fulfillmentUrlIndex, url);
|
||||||
@ -988,17 +982,16 @@ export class Wallet {
|
|||||||
if (!t) {
|
if (!t) {
|
||||||
console.log("query for payment failed");
|
console.log("query for payment failed");
|
||||||
return {
|
return {
|
||||||
success: false,
|
found: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
console.log("query for payment succeeded:", t);
|
console.log("query for payment succeeded:", t);
|
||||||
const resp = {
|
return {
|
||||||
H_contract: t.contractHash,
|
contractTermsHash: t.contractTermsHash,
|
||||||
contract: t.contract,
|
contractTerms: t.contractTerms,
|
||||||
payReq: t.payReq,
|
payReq: t.payReq,
|
||||||
success: true,
|
found: true,
|
||||||
};
|
};
|
||||||
return resp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1804,9 +1797,9 @@ export class Wallet {
|
|||||||
if (t.finished) {
|
if (t.finished) {
|
||||||
return balance;
|
return balance;
|
||||||
}
|
}
|
||||||
const entry = ensureEntry(balance, t.contract.amount.currency);
|
const entry = ensureEntry(balance, t.contractTerms.amount.currency);
|
||||||
entry.pendingPayment = Amounts.add(entry.pendingPayment,
|
entry.pendingPayment = Amounts.add(entry.pendingPayment,
|
||||||
t.contract.amount).amount;
|
t.contractTerms.amount).amount;
|
||||||
|
|
||||||
return balance;
|
return balance;
|
||||||
}
|
}
|
||||||
@ -2171,7 +2164,7 @@ export class Wallet {
|
|||||||
.toArray();
|
.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
async hashContract(contract: Contract): Promise<string> {
|
async hashContract(contract: ContractTerms): Promise<string> {
|
||||||
return this.cryptoApi.hashString(canonicalJson(contract));
|
return this.cryptoApi.hashString(canonicalJson(contract));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2193,16 +2186,16 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async paymentSucceeded(contractHash: string, merchantSig: string): Promise<any> {
|
async paymentSucceeded(contractTermsHash: string, merchantSig: string): Promise<any> {
|
||||||
const doPaymentSucceeded = async() => {
|
const doPaymentSucceeded = async() => {
|
||||||
const t = await this.q().get<TransactionRecord>(Stores.transactions,
|
const t = await this.q().get<TransactionRecord>(Stores.transactions,
|
||||||
contractHash);
|
contractTermsHash);
|
||||||
if (!t) {
|
if (!t) {
|
||||||
console.error("contract not found");
|
console.error("contract not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const merchantPub = t.contract.merchant_pub;
|
const merchantPub = t.contractTerms.merchant_pub;
|
||||||
const valid = this.cryptoApi.isValidPaymentSignature(merchantSig, contractHash, merchantPub);
|
const valid = this.cryptoApi.isValidPaymentSignature(merchantSig, contractTermsHash, merchantPub);
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
console.error("merchant payment signature invalid");
|
console.error("merchant payment signature invalid");
|
||||||
// FIXME: properly display error
|
// FIXME: properly display error
|
||||||
|
@ -28,6 +28,8 @@ import URI = require("urijs");
|
|||||||
|
|
||||||
import wxApi = require("./wxApi");
|
import wxApi = require("./wxApi");
|
||||||
|
|
||||||
|
import { QueryPaymentResult } from "../types";
|
||||||
|
|
||||||
declare var cloneInto: any;
|
declare var cloneInto: any;
|
||||||
|
|
||||||
let logVerbose: boolean = false;
|
let logVerbose: boolean = false;
|
||||||
@ -96,7 +98,12 @@ function setStyles(installed: boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handlePaymentResponse(walletResp: any) {
|
function handlePaymentResponse(maybeFoundResponse: QueryPaymentResult) {
|
||||||
|
if (!maybeFoundResponse.found) {
|
||||||
|
console.log("pay-failed", {hint: "payment not found in the wallet"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const walletResp = maybeFoundResponse;
|
||||||
/**
|
/**
|
||||||
* Handle a failed payment.
|
* Handle a failed payment.
|
||||||
*
|
*
|
||||||
@ -115,7 +122,7 @@ function handlePaymentResponse(walletResp: any) {
|
|||||||
}
|
}
|
||||||
timeoutHandle = window.setTimeout(onTimeout, 200);
|
timeoutHandle = window.setTimeout(onTimeout, 200);
|
||||||
|
|
||||||
await wxApi.paymentFailed(walletResp.H_contract);
|
await wxApi.paymentFailed(walletResp.contractTermsHash);
|
||||||
if (timeoutHandle !== null) {
|
if (timeoutHandle !== null) {
|
||||||
clearTimeout(timeoutHandle);
|
clearTimeout(timeoutHandle);
|
||||||
timeoutHandle = null;
|
timeoutHandle = null;
|
||||||
@ -131,7 +138,7 @@ function handlePaymentResponse(walletResp: any) {
|
|||||||
let timeoutHandle: number|null = null;
|
let timeoutHandle: number|null = null;
|
||||||
function sendPay() {
|
function sendPay() {
|
||||||
r = new XMLHttpRequest();
|
r = new XMLHttpRequest();
|
||||||
r.open("post", walletResp.contract.pay_url);
|
r.open("post", walletResp.contractTerms.pay_url);
|
||||||
r.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
r.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
||||||
r.send(JSON.stringify(walletResp.payReq));
|
r.send(JSON.stringify(walletResp.payReq));
|
||||||
r.onload = async () => {
|
r.onload = async () => {
|
||||||
@ -142,8 +149,8 @@ function handlePaymentResponse(walletResp: any) {
|
|||||||
case 200:
|
case 200:
|
||||||
const merchantResp = JSON.parse(r.responseText);
|
const merchantResp = JSON.parse(r.responseText);
|
||||||
logVerbose && console.log("got success from pay_url");
|
logVerbose && console.log("got success from pay_url");
|
||||||
await wxApi.paymentSucceeded(walletResp.H_contract, merchantResp.sig);
|
await wxApi.paymentSucceeded(walletResp.contractTermsHash, merchantResp.sig);
|
||||||
const nextUrl = walletResp.contract.fulfillment_url;
|
const nextUrl = walletResp.contractTerms.fulfillment_url;
|
||||||
logVerbose && console.log("taler-payment-succeeded done, going to", nextUrl);
|
logVerbose && console.log("taler-payment-succeeded done, going to", nextUrl);
|
||||||
window.location.href = nextUrl;
|
window.location.href = nextUrl;
|
||||||
window.location.reload(true);
|
window.location.reload(true);
|
||||||
@ -318,7 +325,7 @@ function talerPay(msg: any): Promise<any> {
|
|||||||
const url = new URI(document.location.href).fragment("").href();
|
const url = new URI(document.location.href).fragment("").href();
|
||||||
const res = await wxApi.queryPayment(url);
|
const res = await wxApi.queryPayment(url);
|
||||||
logVerbose && console.log("taler-pay: got response", res);
|
logVerbose && console.log("taler-pay: got response", res);
|
||||||
if (res && res.payReq) {
|
if (res && res.found && res.payReq) {
|
||||||
resolve(res);
|
resolve(res);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,12 @@
|
|||||||
*/
|
*/
|
||||||
import * as i18n from "../../i18n";
|
import * as i18n from "../../i18n";
|
||||||
import {
|
import {
|
||||||
Contract,
|
ContractTerms,
|
||||||
ExchangeRecord,
|
ExchangeRecord,
|
||||||
ProposalRecord,
|
ProposalRecord,
|
||||||
} from "../../types";
|
} from "../../types";
|
||||||
|
|
||||||
import { renderContract } from "../renderHtml";
|
import { renderContractTerms } from "../renderHtml";
|
||||||
import * as wxApi from "../wxApi";
|
import * as wxApi from "../wxApi";
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
@ -43,7 +43,7 @@ interface DetailState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface DetailProps {
|
interface DetailProps {
|
||||||
contract: Contract;
|
contractTerms: ContractTerms;
|
||||||
collapsed: boolean;
|
collapsed: boolean;
|
||||||
exchanges: null|ExchangeRecord[];
|
exchanges: null|ExchangeRecord[];
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ class Details extends React.Component<DetailProps, DetailState> {
|
|||||||
<div>
|
<div>
|
||||||
{i18n.str`Accepted exchanges:`}
|
{i18n.str`Accepted exchanges:`}
|
||||||
<ul>
|
<ul>
|
||||||
{this.props.contract.exchanges.map(
|
{this.props.contractTerms.exchanges.map(
|
||||||
(e) => <li>{`${e.url}: ${e.master_pub}`}</li>)}
|
(e) => <li>{`${e.url}: ${e.master_pub}`}</li>)}
|
||||||
</ul>
|
</ul>
|
||||||
{i18n.str`Exchanges in the wallet:`}
|
{i18n.str`Exchanges in the wallet:`}
|
||||||
@ -185,7 +185,7 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
{renderContract(c)}
|
{renderContractTerms(c)}
|
||||||
</div>
|
</div>
|
||||||
<button onClick={() => this.doPayment()}
|
<button onClick={() => this.doPayment()}
|
||||||
disabled={this.state.payDisabled}
|
disabled={this.state.payDisabled}
|
||||||
@ -195,7 +195,7 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
|
|||||||
<div>
|
<div>
|
||||||
{(this.state.error ? <p className="errorbox">{this.state.error}</p> : <p />)}
|
{(this.state.error ? <p className="errorbox">{this.state.error}</p> : <p />)}
|
||||||
</div>
|
</div>
|
||||||
<Details exchanges={this.state.exchanges} contract={c} collapsed={!this.state.error}/>
|
<Details exchanges={this.state.exchanges} contractTerms={c} collapsed={!this.state.error}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
import { amountToPretty } from "../helpers";
|
import { amountToPretty } from "../helpers";
|
||||||
import * as i18n from "../i18n";
|
import * as i18n from "../i18n";
|
||||||
import {
|
import {
|
||||||
Contract,
|
ContractTerms,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
@ -35,14 +35,14 @@ import * as React from "react";
|
|||||||
/**
|
/**
|
||||||
* Render contract terms for the end user to view.
|
* Render contract terms for the end user to view.
|
||||||
*/
|
*/
|
||||||
export function renderContract(contract: Contract): JSX.Element {
|
export function renderContractTerms(contractTerms: ContractTerms): JSX.Element {
|
||||||
let merchantName;
|
let merchantName;
|
||||||
if (contract.merchant && contract.merchant.name) {
|
if (contractTerms.merchant && contractTerms.merchant.name) {
|
||||||
merchantName = <strong>{contract.merchant.name}</strong>;
|
merchantName = <strong>{contractTerms.merchant.name}</strong>;
|
||||||
} else {
|
} else {
|
||||||
merchantName = <strong>(pub: {contract.merchant_pub})</strong>;
|
merchantName = <strong>(pub: {contractTerms.merchant_pub})</strong>;
|
||||||
}
|
}
|
||||||
const amount = <strong>{amountToPretty(contract.amount)}</strong>;
|
const amount = <strong>{amountToPretty(contractTerms.amount)}</strong>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -53,7 +53,7 @@ export function renderContract(contract: Contract): JSX.Element {
|
|||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
<p>{i18n.str`You are about to purchase:`}</p>
|
<p>{i18n.str`You are about to purchase:`}</p>
|
||||||
<ul>
|
<ul>
|
||||||
{contract.products.map(
|
{contractTerms.products.map(
|
||||||
(p: any, i: number) => (<li key={i}>{`${p.description}: ${amountToPretty(p.price)}`}</li>))
|
(p: any, i: number) => (<li key={i}>{`${p.description}: ${amountToPretty(p.price)}`}</li>))
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -33,6 +33,7 @@ import {
|
|||||||
PreCoinRecord,
|
PreCoinRecord,
|
||||||
ReserveCreationInfo,
|
ReserveCreationInfo,
|
||||||
ReserveRecord,
|
ReserveRecord,
|
||||||
|
QueryPaymentResult,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
|
|
||||||
import { MessageType, MessageMap } from "./messages";
|
import { MessageType, MessageMap } from "./messages";
|
||||||
@ -213,7 +214,7 @@ export function confirmReserve(reservePub: string): Promise<void> {
|
|||||||
/**
|
/**
|
||||||
* Query for a payment by fulfillment URL.
|
* Query for a payment by fulfillment URL.
|
||||||
*/
|
*/
|
||||||
export function queryPayment(url: string): Promise<any> {
|
export function queryPayment(url: string): Promise<QueryPaymentResult> {
|
||||||
return callBackend("query-payment", { url });
|
return callBackend("query-payment", { url });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user