fix messaging, small issues and safer types
This commit is contained in:
parent
7e5ddf3a45
commit
613a14c14f
@ -27,7 +27,7 @@ import {
|
|||||||
AmountJson,
|
AmountJson,
|
||||||
CoinRecord,
|
CoinRecord,
|
||||||
DenominationRecord,
|
DenominationRecord,
|
||||||
OfferRecord,
|
ProposalRecord,
|
||||||
PayCoinInfo,
|
PayCoinInfo,
|
||||||
PaybackRequest,
|
PaybackRequest,
|
||||||
PreCoinRecord,
|
PreCoinRecord,
|
||||||
@ -277,9 +277,9 @@ export class CryptoApi {
|
|||||||
return this.doRpc<PayCoinInfo>("isValidPaymentSignature", 1, sig, contractHash, merchantPub);
|
return this.doRpc<PayCoinInfo>("isValidPaymentSignature", 1, sig, contractHash, merchantPub);
|
||||||
}
|
}
|
||||||
|
|
||||||
signDeposit(offer: OfferRecord,
|
signDeposit(proposal: ProposalRecord,
|
||||||
cds: CoinWithDenom[]): Promise<PayCoinInfo> {
|
cds: CoinWithDenom[]): Promise<PayCoinInfo> {
|
||||||
return this.doRpc<PayCoinInfo>("signDeposit", 3, offer, cds);
|
return this.doRpc<PayCoinInfo>("signDeposit", 3, proposal, cds);
|
||||||
}
|
}
|
||||||
|
|
||||||
createEddsaKeypair(): Promise<{priv: string, pub: string}> {
|
createEddsaKeypair(): Promise<{priv: string, pub: string}> {
|
||||||
|
@ -29,7 +29,7 @@ import {
|
|||||||
CoinRecord,
|
CoinRecord,
|
||||||
CoinStatus,
|
CoinStatus,
|
||||||
DenominationRecord,
|
DenominationRecord,
|
||||||
OfferRecord,
|
ProposalRecord,
|
||||||
PayCoinInfo,
|
PayCoinInfo,
|
||||||
PaybackRequest,
|
PaybackRequest,
|
||||||
PreCoinRecord,
|
PreCoinRecord,
|
||||||
@ -227,7 +227,7 @@ namespace RpcFunctions {
|
|||||||
* Generate updated coins (to store in the database)
|
* Generate updated coins (to store in the database)
|
||||||
* and deposit permissions for each given coin.
|
* and deposit permissions for each given coin.
|
||||||
*/
|
*/
|
||||||
export function signDeposit(offer: OfferRecord,
|
export function signDeposit(proposal: ProposalRecord,
|
||||||
cds: CoinWithDenom[]): PayCoinInfo {
|
cds: CoinWithDenom[]): PayCoinInfo {
|
||||||
const ret: PayCoinInfo = [];
|
const ret: PayCoinInfo = [];
|
||||||
|
|
||||||
@ -235,8 +235,8 @@ namespace RpcFunctions {
|
|||||||
const feeList: AmountJson[] = cds.map((x) => x.denom.feeDeposit);
|
const feeList: AmountJson[] = cds.map((x) => x.denom.feeDeposit);
|
||||||
let fees = Amounts.add(Amounts.getZero(feeList[0].currency), ...feeList).amount;
|
let fees = Amounts.add(Amounts.getZero(feeList[0].currency), ...feeList).amount;
|
||||||
// okay if saturates
|
// okay if saturates
|
||||||
fees = Amounts.sub(fees, offer.contract.max_fee).amount;
|
fees = Amounts.sub(fees, proposal.contractTerms.max_fee).amount;
|
||||||
const total = Amounts.add(fees, offer.contract.amount).amount;
|
const total = Amounts.add(fees, proposal.contractTerms.amount).amount;
|
||||||
|
|
||||||
const amountSpent = native.Amount.getZero(cds[0].coin.currentAmount.currency);
|
const amountSpent = native.Amount.getZero(cds[0].coin.currentAmount.currency);
|
||||||
const amountRemaining = new native.Amount(total);
|
const amountRemaining = new native.Amount(total);
|
||||||
@ -273,11 +273,11 @@ namespace RpcFunctions {
|
|||||||
amount_with_fee: coinSpend.toNbo(),
|
amount_with_fee: coinSpend.toNbo(),
|
||||||
coin_pub: native.EddsaPublicKey.fromCrock(cd.coin.coinPub),
|
coin_pub: native.EddsaPublicKey.fromCrock(cd.coin.coinPub),
|
||||||
deposit_fee: new native.Amount(cd.denom.feeDeposit).toNbo(),
|
deposit_fee: new native.Amount(cd.denom.feeDeposit).toNbo(),
|
||||||
h_contract: native.HashCode.fromCrock(offer.H_contract),
|
h_contract: native.HashCode.fromCrock(proposal.contractTermsHash),
|
||||||
h_wire: native.HashCode.fromCrock(offer.contract.H_wire),
|
h_wire: native.HashCode.fromCrock(proposal.contractTerms.H_wire),
|
||||||
merchant: native.EddsaPublicKey.fromCrock(offer.contract.merchant_pub),
|
merchant: native.EddsaPublicKey.fromCrock(proposal.contractTerms.merchant_pub),
|
||||||
refund_deadline: native.AbsoluteTimeNbo.fromTalerString(offer.contract.refund_deadline),
|
refund_deadline: native.AbsoluteTimeNbo.fromTalerString(proposal.contractTerms.refund_deadline),
|
||||||
timestamp: native.AbsoluteTimeNbo.fromTalerString(offer.contract.timestamp),
|
timestamp: native.AbsoluteTimeNbo.fromTalerString(proposal.contractTerms.timestamp),
|
||||||
});
|
});
|
||||||
|
|
||||||
const coinSig = native.eddsaSign(d.toPurpose(),
|
const coinSig = native.eddsaSign(d.toPurpose(),
|
||||||
|
@ -42,13 +42,13 @@ msgstr ""
|
|||||||
msgid "Exchanges in the wallet:"
|
msgid "Exchanges in the wallet:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/confirm-contract.tsx:146
|
#: src/webex/pages/confirm-contract.tsx:141
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "You have insufficient funds of the requested currency in your wallet."
|
msgid "You have insufficient funds of the requested currency in your wallet."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. tslint:disable-next-line:max-line-length
|
#. tslint:disable-next-line:max-line-length
|
||||||
#: src/webex/pages/confirm-contract.tsx:148
|
#: src/webex/pages/confirm-contract.tsx:143
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You do not have any funds from an exchange that is accepted by this "
|
"You do not have any funds from an exchange that is accepted by this "
|
||||||
@ -193,90 +193,90 @@ msgstr ""
|
|||||||
msgid "Fatal error: \"%1$s\"."
|
msgid "Fatal error: \"%1$s\"."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:163
|
#: src/webex/pages/popup.tsx:161
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Balance"
|
msgid "Balance"
|
||||||
msgstr "Saldo"
|
msgstr "Saldo"
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:166
|
#: src/webex/pages/popup.tsx:164
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "History"
|
msgid "History"
|
||||||
msgstr "Verlauf"
|
msgstr "Verlauf"
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:169
|
#: src/webex/pages/popup.tsx:167
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Debug"
|
msgid "Debug"
|
||||||
msgstr "Debug"
|
msgstr "Debug"
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:245
|
#: src/webex/pages/popup.tsx:243
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "help"
|
msgid "help"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:250
|
#: src/webex/pages/popup.tsx:248
|
||||||
#, fuzzy, c-format
|
#, fuzzy, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You have no balance to show. Need some\n"
|
"You have no balance to show. Need some\n"
|
||||||
" %1$s getting started?\n"
|
" %1$s getting started?\n"
|
||||||
msgstr "Sie haben kein Digitalgeld. Wollen Sie %1$s? abheben?"
|
msgstr "Sie haben kein Digitalgeld. Wollen Sie %1$s? abheben?"
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:267
|
#: src/webex/pages/popup.tsx:265
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s incoming\n"
|
msgid "%1$s incoming\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:280
|
#: src/webex/pages/popup.tsx:278
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s being spent\n"
|
msgid "%1$s being spent\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:306
|
#: src/webex/pages/popup.tsx:304
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error: could not retrieve balance information."
|
msgid "Error: could not retrieve balance information."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:345
|
#: src/webex/pages/popup.tsx:343
|
||||||
#, fuzzy, c-format
|
#, fuzzy, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Bank requested reserve (%1$s) for\n"
|
"Bank requested reserve (%1$s) for\n"
|
||||||
" %2$s.\n"
|
" %2$s.\n"
|
||||||
msgstr "Bank bestätig anlegen der Reserve (%1$s) bei %2$s"
|
msgstr "Bank bestätig anlegen der Reserve (%1$s) bei %2$s"
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:356
|
#: src/webex/pages/popup.tsx:354
|
||||||
#, fuzzy, c-format
|
#, fuzzy, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Started to withdraw\n"
|
"Started to withdraw\n"
|
||||||
" %1$s from%2$s(%3$s).\n"
|
" %1$s from%2$s(%3$s).\n"
|
||||||
msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
|
msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:366
|
#: src/webex/pages/popup.tsx:364
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Merchant%1$soffered contract%2$s;\n"
|
msgid "Merchant%1$soffered contract%2$s;\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:376
|
#: src/webex/pages/popup.tsx:374
|
||||||
#, fuzzy, c-format
|
#, fuzzy, c-format
|
||||||
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
|
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
|
||||||
msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
|
msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:386
|
#: src/webex/pages/popup.tsx:384
|
||||||
#, fuzzy, c-format
|
#, fuzzy, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Paid%1$sto merchant%2$s.\n"
|
"Paid%1$sto merchant%2$s.\n"
|
||||||
" (%3$s)\n"
|
" (%3$s)\n"
|
||||||
msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
|
msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:395
|
#: src/webex/pages/popup.tsx:393
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Unknown event (%1$s)"
|
msgid "Unknown event (%1$s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:438
|
#: src/webex/pages/popup.tsx:436
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error: could not retrieve event history"
|
msgid "Error: could not retrieve event history"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:472
|
#: src/webex/pages/popup.tsx:470
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Your wallet has no events recorded."
|
msgid "Your wallet has no events recorded."
|
||||||
msgstr "Ihre Geldbörse verzeichnet keine Vorkommnisse."
|
msgstr "Ihre Geldbörse verzeichnet keine Vorkommnisse."
|
||||||
|
@ -42,13 +42,13 @@ msgstr ""
|
|||||||
msgid "Exchanges in the wallet:"
|
msgid "Exchanges in the wallet:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/confirm-contract.tsx:146
|
#: src/webex/pages/confirm-contract.tsx:141
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "You have insufficient funds of the requested currency in your wallet."
|
msgid "You have insufficient funds of the requested currency in your wallet."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. tslint:disable-next-line:max-line-length
|
#. tslint:disable-next-line:max-line-length
|
||||||
#: src/webex/pages/confirm-contract.tsx:148
|
#: src/webex/pages/confirm-contract.tsx:143
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You do not have any funds from an exchange that is accepted by this "
|
"You do not have any funds from an exchange that is accepted by this "
|
||||||
@ -193,90 +193,90 @@ msgstr ""
|
|||||||
msgid "Fatal error: \"%1$s\"."
|
msgid "Fatal error: \"%1$s\"."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:163
|
#: src/webex/pages/popup.tsx:161
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Balance"
|
msgid "Balance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:166
|
#: src/webex/pages/popup.tsx:164
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "History"
|
msgid "History"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:169
|
#: src/webex/pages/popup.tsx:167
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Debug"
|
msgid "Debug"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:245
|
#: src/webex/pages/popup.tsx:243
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "help"
|
msgid "help"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:250
|
#: src/webex/pages/popup.tsx:248
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You have no balance to show. Need some\n"
|
"You have no balance to show. Need some\n"
|
||||||
" %1$s getting started?\n"
|
" %1$s getting started?\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:267
|
#: src/webex/pages/popup.tsx:265
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s incoming\n"
|
msgid "%1$s incoming\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:280
|
#: src/webex/pages/popup.tsx:278
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s being spent\n"
|
msgid "%1$s being spent\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:306
|
#: src/webex/pages/popup.tsx:304
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error: could not retrieve balance information."
|
msgid "Error: could not retrieve balance information."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:345
|
#: src/webex/pages/popup.tsx:343
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Bank requested reserve (%1$s) for\n"
|
"Bank requested reserve (%1$s) for\n"
|
||||||
" %2$s.\n"
|
" %2$s.\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:356
|
#: src/webex/pages/popup.tsx:354
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Started to withdraw\n"
|
"Started to withdraw\n"
|
||||||
" %1$s from%2$s(%3$s).\n"
|
" %1$s from%2$s(%3$s).\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:366
|
#: src/webex/pages/popup.tsx:364
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Merchant%1$soffered contract%2$s;\n"
|
msgid "Merchant%1$soffered contract%2$s;\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:376
|
#: src/webex/pages/popup.tsx:374
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
|
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:386
|
#: src/webex/pages/popup.tsx:384
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Paid%1$sto merchant%2$s.\n"
|
"Paid%1$sto merchant%2$s.\n"
|
||||||
" (%3$s)\n"
|
" (%3$s)\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:395
|
#: src/webex/pages/popup.tsx:393
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Unknown event (%1$s)"
|
msgid "Unknown event (%1$s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:438
|
#: src/webex/pages/popup.tsx:436
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error: could not retrieve event history"
|
msgid "Error: could not retrieve event history"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:472
|
#: src/webex/pages/popup.tsx:470
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Your wallet has no events recorded."
|
msgid "Your wallet has no events recorded."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -42,13 +42,13 @@ msgstr ""
|
|||||||
msgid "Exchanges in the wallet:"
|
msgid "Exchanges in the wallet:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/confirm-contract.tsx:146
|
#: src/webex/pages/confirm-contract.tsx:141
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "You have insufficient funds of the requested currency in your wallet."
|
msgid "You have insufficient funds of the requested currency in your wallet."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. tslint:disable-next-line:max-line-length
|
#. tslint:disable-next-line:max-line-length
|
||||||
#: src/webex/pages/confirm-contract.tsx:148
|
#: src/webex/pages/confirm-contract.tsx:143
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You do not have any funds from an exchange that is accepted by this "
|
"You do not have any funds from an exchange that is accepted by this "
|
||||||
@ -193,90 +193,90 @@ msgstr ""
|
|||||||
msgid "Fatal error: \"%1$s\"."
|
msgid "Fatal error: \"%1$s\"."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:163
|
#: src/webex/pages/popup.tsx:161
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Balance"
|
msgid "Balance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:166
|
#: src/webex/pages/popup.tsx:164
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "History"
|
msgid "History"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:169
|
#: src/webex/pages/popup.tsx:167
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Debug"
|
msgid "Debug"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:245
|
#: src/webex/pages/popup.tsx:243
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "help"
|
msgid "help"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:250
|
#: src/webex/pages/popup.tsx:248
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You have no balance to show. Need some\n"
|
"You have no balance to show. Need some\n"
|
||||||
" %1$s getting started?\n"
|
" %1$s getting started?\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:267
|
#: src/webex/pages/popup.tsx:265
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s incoming\n"
|
msgid "%1$s incoming\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:280
|
#: src/webex/pages/popup.tsx:278
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s being spent\n"
|
msgid "%1$s being spent\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:306
|
#: src/webex/pages/popup.tsx:304
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error: could not retrieve balance information."
|
msgid "Error: could not retrieve balance information."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:345
|
#: src/webex/pages/popup.tsx:343
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Bank requested reserve (%1$s) for\n"
|
"Bank requested reserve (%1$s) for\n"
|
||||||
" %2$s.\n"
|
" %2$s.\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:356
|
#: src/webex/pages/popup.tsx:354
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Started to withdraw\n"
|
"Started to withdraw\n"
|
||||||
" %1$s from%2$s(%3$s).\n"
|
" %1$s from%2$s(%3$s).\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:366
|
#: src/webex/pages/popup.tsx:364
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Merchant%1$soffered contract%2$s;\n"
|
msgid "Merchant%1$soffered contract%2$s;\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:376
|
#: src/webex/pages/popup.tsx:374
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
|
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:386
|
#: src/webex/pages/popup.tsx:384
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Paid%1$sto merchant%2$s.\n"
|
"Paid%1$sto merchant%2$s.\n"
|
||||||
" (%3$s)\n"
|
" (%3$s)\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:395
|
#: src/webex/pages/popup.tsx:393
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Unknown event (%1$s)"
|
msgid "Unknown event (%1$s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:438
|
#: src/webex/pages/popup.tsx:436
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error: could not retrieve event history"
|
msgid "Error: could not retrieve event history"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:472
|
#: src/webex/pages/popup.tsx:470
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Your wallet has no events recorded."
|
msgid "Your wallet has no events recorded."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -42,13 +42,13 @@ msgstr ""
|
|||||||
msgid "Exchanges in the wallet:"
|
msgid "Exchanges in the wallet:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/confirm-contract.tsx:146
|
#: src/webex/pages/confirm-contract.tsx:141
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "You have insufficient funds of the requested currency in your wallet."
|
msgid "You have insufficient funds of the requested currency in your wallet."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. tslint:disable-next-line:max-line-length
|
#. tslint:disable-next-line:max-line-length
|
||||||
#: src/webex/pages/confirm-contract.tsx:148
|
#: src/webex/pages/confirm-contract.tsx:143
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You do not have any funds from an exchange that is accepted by this "
|
"You do not have any funds from an exchange that is accepted by this "
|
||||||
@ -193,90 +193,90 @@ msgstr ""
|
|||||||
msgid "Fatal error: \"%1$s\"."
|
msgid "Fatal error: \"%1$s\"."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:163
|
#: src/webex/pages/popup.tsx:161
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Balance"
|
msgid "Balance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:166
|
#: src/webex/pages/popup.tsx:164
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "History"
|
msgid "History"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:169
|
#: src/webex/pages/popup.tsx:167
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Debug"
|
msgid "Debug"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:245
|
#: src/webex/pages/popup.tsx:243
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "help"
|
msgid "help"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:250
|
#: src/webex/pages/popup.tsx:248
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You have no balance to show. Need some\n"
|
"You have no balance to show. Need some\n"
|
||||||
" %1$s getting started?\n"
|
" %1$s getting started?\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:267
|
#: src/webex/pages/popup.tsx:265
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s incoming\n"
|
msgid "%1$s incoming\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:280
|
#: src/webex/pages/popup.tsx:278
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s being spent\n"
|
msgid "%1$s being spent\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:306
|
#: src/webex/pages/popup.tsx:304
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error: could not retrieve balance information."
|
msgid "Error: could not retrieve balance information."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:345
|
#: src/webex/pages/popup.tsx:343
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Bank requested reserve (%1$s) for\n"
|
"Bank requested reserve (%1$s) for\n"
|
||||||
" %2$s.\n"
|
" %2$s.\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:356
|
#: src/webex/pages/popup.tsx:354
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Started to withdraw\n"
|
"Started to withdraw\n"
|
||||||
" %1$s from%2$s(%3$s).\n"
|
" %1$s from%2$s(%3$s).\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:366
|
#: src/webex/pages/popup.tsx:364
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Merchant%1$soffered contract%2$s;\n"
|
msgid "Merchant%1$soffered contract%2$s;\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:376
|
#: src/webex/pages/popup.tsx:374
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
|
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:386
|
#: src/webex/pages/popup.tsx:384
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Paid%1$sto merchant%2$s.\n"
|
"Paid%1$sto merchant%2$s.\n"
|
||||||
" (%3$s)\n"
|
" (%3$s)\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:395
|
#: src/webex/pages/popup.tsx:393
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Unknown event (%1$s)"
|
msgid "Unknown event (%1$s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:438
|
#: src/webex/pages/popup.tsx:436
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error: could not retrieve event history"
|
msgid "Error: could not retrieve event history"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:472
|
#: src/webex/pages/popup.tsx:470
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Your wallet has no events recorded."
|
msgid "Your wallet has no events recorded."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -42,13 +42,13 @@ msgstr ""
|
|||||||
msgid "Exchanges in the wallet:"
|
msgid "Exchanges in the wallet:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/confirm-contract.tsx:146
|
#: src/webex/pages/confirm-contract.tsx:141
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "You have insufficient funds of the requested currency in your wallet."
|
msgid "You have insufficient funds of the requested currency in your wallet."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. tslint:disable-next-line:max-line-length
|
#. tslint:disable-next-line:max-line-length
|
||||||
#: src/webex/pages/confirm-contract.tsx:148
|
#: src/webex/pages/confirm-contract.tsx:143
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You do not have any funds from an exchange that is accepted by this "
|
"You do not have any funds from an exchange that is accepted by this "
|
||||||
@ -193,90 +193,90 @@ msgstr ""
|
|||||||
msgid "Fatal error: \"%1$s\"."
|
msgid "Fatal error: \"%1$s\"."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:163
|
#: src/webex/pages/popup.tsx:161
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Balance"
|
msgid "Balance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:166
|
#: src/webex/pages/popup.tsx:164
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "History"
|
msgid "History"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:169
|
#: src/webex/pages/popup.tsx:167
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Debug"
|
msgid "Debug"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:245
|
#: src/webex/pages/popup.tsx:243
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "help"
|
msgid "help"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:250
|
#: src/webex/pages/popup.tsx:248
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You have no balance to show. Need some\n"
|
"You have no balance to show. Need some\n"
|
||||||
" %1$s getting started?\n"
|
" %1$s getting started?\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:267
|
#: src/webex/pages/popup.tsx:265
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s incoming\n"
|
msgid "%1$s incoming\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:280
|
#: src/webex/pages/popup.tsx:278
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s being spent\n"
|
msgid "%1$s being spent\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:306
|
#: src/webex/pages/popup.tsx:304
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error: could not retrieve balance information."
|
msgid "Error: could not retrieve balance information."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:345
|
#: src/webex/pages/popup.tsx:343
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Bank requested reserve (%1$s) for\n"
|
"Bank requested reserve (%1$s) for\n"
|
||||||
" %2$s.\n"
|
" %2$s.\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:356
|
#: src/webex/pages/popup.tsx:354
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Started to withdraw\n"
|
"Started to withdraw\n"
|
||||||
" %1$s from%2$s(%3$s).\n"
|
" %1$s from%2$s(%3$s).\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:366
|
#: src/webex/pages/popup.tsx:364
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Merchant%1$soffered contract%2$s;\n"
|
msgid "Merchant%1$soffered contract%2$s;\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:376
|
#: src/webex/pages/popup.tsx:374
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
|
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:386
|
#: src/webex/pages/popup.tsx:384
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Paid%1$sto merchant%2$s.\n"
|
"Paid%1$sto merchant%2$s.\n"
|
||||||
" (%3$s)\n"
|
" (%3$s)\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:395
|
#: src/webex/pages/popup.tsx:393
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Unknown event (%1$s)"
|
msgid "Unknown event (%1$s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:438
|
#: src/webex/pages/popup.tsx:436
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error: could not retrieve event history"
|
msgid "Error: could not retrieve event history"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/webex/pages/popup.tsx:472
|
#: src/webex/pages/popup.tsx:470
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Your wallet has no events recorded."
|
msgid "Your wallet has no events recorded."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
18
src/types.ts
18
src/types.ts
@ -1047,33 +1047,27 @@ export class Contract {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Offer record, stored in the wallet's database.
|
* Proposal record, stored in the wallet's database.
|
||||||
*/
|
*/
|
||||||
@Checkable.Class()
|
@Checkable.Class()
|
||||||
export class OfferRecord {
|
export class ProposalRecord {
|
||||||
/**
|
/**
|
||||||
* The contract that was offered by the merchant.
|
* The contract that was offered by the merchant.
|
||||||
*/
|
*/
|
||||||
@Checkable.Value(Contract)
|
@Checkable.Value(Contract)
|
||||||
contract: Contract;
|
contractTerms: Contract;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signature by the merchant over the contract details.
|
* Signature by the merchant over the contract details.
|
||||||
*/
|
*/
|
||||||
@Checkable.String
|
@Checkable.String
|
||||||
merchant_sig: string;
|
merchantSig: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash of the contract terms.
|
* Hash of the contract terms.
|
||||||
*/
|
*/
|
||||||
@Checkable.String
|
@Checkable.String
|
||||||
H_contract: string;
|
contractTermsHash: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Time when the offer was made.
|
|
||||||
*/
|
|
||||||
@Checkable.Number
|
|
||||||
offer_time: number;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serial ID when the offer is stored in the wallet DB.
|
* Serial ID when the offer is stored in the wallet DB.
|
||||||
@ -1085,7 +1079,7 @@ export class OfferRecord {
|
|||||||
* 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) => OfferRecord;
|
static checked: (obj: any) => ProposalRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
123
src/wallet.ts
123
src/wallet.ts
@ -63,7 +63,7 @@ import {
|
|||||||
HistoryLevel,
|
HistoryLevel,
|
||||||
HistoryRecord,
|
HistoryRecord,
|
||||||
Notifier,
|
Notifier,
|
||||||
OfferRecord,
|
ProposalRecord,
|
||||||
PayCoinInfo,
|
PayCoinInfo,
|
||||||
PaybackConfirmation,
|
PaybackConfirmation,
|
||||||
PreCoinRecord,
|
PreCoinRecord,
|
||||||
@ -507,9 +507,9 @@ export namespace Stores {
|
|||||||
timestampIndex = new Index<number, HistoryRecord>(this, "timestamp", "timestamp");
|
timestampIndex = new Index<number, HistoryRecord>(this, "timestamp", "timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
class OffersStore extends Store<OfferRecord> {
|
class ProposalsStore extends Store<ProposalRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("offers", {
|
super("proposals", {
|
||||||
autoIncrement: true,
|
autoIncrement: true,
|
||||||
keyPath: "id",
|
keyPath: "id",
|
||||||
});
|
});
|
||||||
@ -555,19 +555,19 @@ export namespace Stores {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const exchanges = new ExchangeStore();
|
|
||||||
export const exchangeWireFees = new ExchangeWireFeesStore();
|
|
||||||
export const nonces = new NonceStore();
|
|
||||||
export const transactions = new TransactionsStore();
|
|
||||||
export const reserves = new Store<ReserveRecord>("reserves", {keyPath: "reserve_pub"});
|
|
||||||
export const coins = new CoinsStore();
|
export const coins = new CoinsStore();
|
||||||
export const refresh = new Store<RefreshSessionRecord>("refresh", {keyPath: "meltCoinPub"});
|
|
||||||
export const history = new HistoryStore();
|
|
||||||
export const offers = new OffersStore();
|
|
||||||
export const precoins = new Store<PreCoinRecord>("precoins", {keyPath: "coinPub"});
|
|
||||||
export const denominations = new DenominationsStore();
|
|
||||||
export const currencies = new CurrenciesStore();
|
|
||||||
export const config = new ConfigStore();
|
export const config = new ConfigStore();
|
||||||
|
export const currencies = new CurrenciesStore();
|
||||||
|
export const denominations = new DenominationsStore();
|
||||||
|
export const exchangeWireFees = new ExchangeWireFeesStore();
|
||||||
|
export const exchanges = new ExchangeStore();
|
||||||
|
export const history = new HistoryStore();
|
||||||
|
export const nonces = new NonceStore();
|
||||||
|
export const precoins = new Store<PreCoinRecord>("precoins", {keyPath: "coinPub"});
|
||||||
|
export const proposals = new ProposalsStore();
|
||||||
|
export const refresh = new Store<RefreshSessionRecord>("refresh", {keyPath: "meltCoinPub"});
|
||||||
|
export const reserves = new Store<ReserveRecord>("reserves", {keyPath: "reserve_pub"});
|
||||||
|
export const transactions = new TransactionsStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tslint:enable:completed-docs */
|
/* tslint:enable:completed-docs */
|
||||||
@ -834,32 +834,32 @@ 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 contract in the wallet's database.
|
||||||
*/
|
*/
|
||||||
private async recordConfirmPay(offer: OfferRecord,
|
private async recordConfirmPay(proposal: ProposalRecord,
|
||||||
payCoinInfo: PayCoinInfo,
|
payCoinInfo: PayCoinInfo,
|
||||||
chosenExchange: string): Promise<void> {
|
chosenExchange: string): Promise<void> {
|
||||||
const payReq: PayReq = {
|
const payReq: PayReq = {
|
||||||
coins: payCoinInfo.map((x) => x.sig),
|
coins: payCoinInfo.map((x) => x.sig),
|
||||||
exchange: chosenExchange,
|
exchange: chosenExchange,
|
||||||
merchant_pub: offer.contract.merchant_pub,
|
merchant_pub: proposal.contractTerms.merchant_pub,
|
||||||
order_id: offer.contract.order_id,
|
order_id: proposal.contractTerms.order_id,
|
||||||
};
|
};
|
||||||
const t: TransactionRecord = {
|
const t: TransactionRecord = {
|
||||||
contract: offer.contract,
|
contract: proposal.contractTerms,
|
||||||
contractHash: offer.H_contract,
|
contractHash: proposal.contractTermsHash,
|
||||||
finished: false,
|
finished: false,
|
||||||
merchantSig: offer.merchant_sig,
|
merchantSig: proposal.merchantSig,
|
||||||
payReq,
|
payReq,
|
||||||
};
|
};
|
||||||
|
|
||||||
const historyEntry: HistoryRecord = {
|
const historyEntry: HistoryRecord = {
|
||||||
detail: {
|
detail: {
|
||||||
amount: offer.contract.amount,
|
amount: proposal.contractTerms.amount,
|
||||||
contractHash: offer.H_contract,
|
contractHash: proposal.contractTermsHash,
|
||||||
fulfillmentUrl: offer.contract.fulfillment_url,
|
fulfillmentUrl: proposal.contractTerms.fulfillment_url,
|
||||||
merchantName: offer.contract.merchant.name,
|
merchantName: proposal.contractTerms.merchant.name,
|
||||||
},
|
},
|
||||||
level: HistoryLevel.User,
|
level: HistoryLevel.User,
|
||||||
subjectId: `contract-${offer.H_contract}`,
|
subjectId: `contract-${proposal.contractTermsHash}`,
|
||||||
timestamp: (new Date()).getTime(),
|
timestamp: (new Date()).getTime(),
|
||||||
type: "pay",
|
type: "pay",
|
||||||
};
|
};
|
||||||
@ -880,11 +880,13 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async saveOffer(offer: OfferRecord): Promise<number> {
|
/**
|
||||||
console.log(`saving offer in wallet.ts`);
|
* Save a proposal in the database and return an id for it to
|
||||||
const id = await this.q().putWithResult(Stores.offers, offer);
|
* retrieve it later.
|
||||||
|
*/
|
||||||
|
async saveProposal(proposal: ProposalRecord): Promise<number> {
|
||||||
|
const id = await this.q().putWithResult(Stores.proposals, proposal);
|
||||||
this.notifier.notify();
|
this.notifier.notify();
|
||||||
console.log(`saved offer with id ${id}`);
|
|
||||||
if (typeof id !== "number") {
|
if (typeof id !== "number") {
|
||||||
throw Error("db schema wrong");
|
throw Error("db schema wrong");
|
||||||
}
|
}
|
||||||
@ -896,10 +898,15 @@ export class Wallet {
|
|||||||
* Add a contract to the wallet and sign coins,
|
* Add a contract to the wallet and sign coins,
|
||||||
* but do not send them yet.
|
* but do not send them yet.
|
||||||
*/
|
*/
|
||||||
async confirmPay(offer: OfferRecord): Promise<ConfirmPayResult> {
|
async confirmPay(proposalId: number): Promise<ConfirmPayResult> {
|
||||||
console.log("executing confirmPay");
|
console.log("executing confirmPay");
|
||||||
|
const proposal = await this.q().get(Stores.proposals, proposalId);
|
||||||
|
|
||||||
const transaction = await this.q().get(Stores.transactions, offer.H_contract);
|
if (!proposal) {
|
||||||
|
throw Error(`proposal with id ${proposalId} not found`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const transaction = await this.q().get(Stores.transactions, proposal.contractTermsHash);
|
||||||
|
|
||||||
if (transaction) {
|
if (transaction) {
|
||||||
// Already payed ...
|
// Already payed ...
|
||||||
@ -907,17 +914,17 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const res = await this.getCoinsForPayment({
|
const res = await this.getCoinsForPayment({
|
||||||
allowedAuditors: offer.contract.auditors,
|
allowedAuditors: proposal.contractTerms.auditors,
|
||||||
allowedExchanges: offer.contract.exchanges,
|
allowedExchanges: proposal.contractTerms.exchanges,
|
||||||
depositFeeLimit: offer.contract.max_fee,
|
depositFeeLimit: proposal.contractTerms.max_fee,
|
||||||
paymentAmount: offer.contract.amount,
|
paymentAmount: proposal.contractTerms.amount,
|
||||||
wireFeeAmortization: offer.contract.wire_fee_amortization || 1,
|
wireFeeAmortization: proposal.contractTerms.wire_fee_amortization || 1,
|
||||||
wireFeeLimit: offer.contract.max_wire_fee || Amounts.getZero(offer.contract.amount.currency),
|
wireFeeLimit: proposal.contractTerms.max_wire_fee || Amounts.getZero(proposal.contractTerms.amount.currency),
|
||||||
wireFeeTime: getTalerStampSec(offer.contract.timestamp) || 0,
|
wireFeeTime: getTalerStampSec(proposal.contractTerms.timestamp) || 0,
|
||||||
wireMethod: offer.contract.wire_method,
|
wireMethod: proposal.contractTerms.wire_method,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("max_fee", offer.contract.max_fee);
|
console.log("max_fee", proposal.contractTerms.max_fee);
|
||||||
console.log("coin selection result", res);
|
console.log("coin selection result", res);
|
||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
@ -926,8 +933,8 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
const {exchangeUrl, cds} = res;
|
const {exchangeUrl, cds} = res;
|
||||||
|
|
||||||
const ds = await this.cryptoApi.signDeposit(offer, cds);
|
const ds = await this.cryptoApi.signDeposit(proposal, cds);
|
||||||
await this.recordConfirmPay(offer, ds, exchangeUrl);
|
await this.recordConfirmPay(proposal, ds, exchangeUrl);
|
||||||
return "paid";
|
return "paid";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -936,23 +943,29 @@ export class Wallet {
|
|||||||
* Check if payment for an offer is possible, or if the offer has already
|
* Check if payment for an offer is possible, or if the offer has already
|
||||||
* been payed for.
|
* been payed for.
|
||||||
*/
|
*/
|
||||||
async checkPay(offer: OfferRecord): Promise<CheckPayResult> {
|
async checkPay(proposalId: number): Promise<CheckPayResult> {
|
||||||
|
const proposal = await this.q().get(Stores.proposals, proposalId);
|
||||||
|
|
||||||
|
if (!proposal) {
|
||||||
|
throw Error(`proposal with id ${proposalId} not found`);
|
||||||
|
}
|
||||||
|
|
||||||
// First check if we already payed for it.
|
// First check if we already payed for it.
|
||||||
const transaction = await this.q().get(Stores.transactions, offer.H_contract);
|
const transaction = await this.q().get(Stores.transactions, proposal.contractTermsHash);
|
||||||
if (transaction) {
|
if (transaction) {
|
||||||
return "insufficient-balance";
|
return "insufficient-balance";
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not already payed, check if we could pay for it.
|
// If not already payed, check if we could pay for it.
|
||||||
const res = await this.getCoinsForPayment({
|
const res = await this.getCoinsForPayment({
|
||||||
allowedAuditors: offer.contract.auditors,
|
allowedAuditors: proposal.contractTerms.auditors,
|
||||||
allowedExchanges: offer.contract.exchanges,
|
allowedExchanges: proposal.contractTerms.exchanges,
|
||||||
depositFeeLimit: offer.contract.max_fee,
|
depositFeeLimit: proposal.contractTerms.max_fee,
|
||||||
paymentAmount: offer.contract.amount,
|
paymentAmount: proposal.contractTerms.amount,
|
||||||
wireFeeAmortization: offer.contract.wire_fee_amortization || 1,
|
wireFeeAmortization: proposal.contractTerms.wire_fee_amortization || 1,
|
||||||
wireFeeLimit: offer.contract.max_wire_fee || Amounts.getZero(offer.contract.amount.currency),
|
wireFeeLimit: proposal.contractTerms.max_wire_fee || Amounts.getZero(proposal.contractTerms.amount.currency),
|
||||||
wireFeeTime: getTalerStampSec(offer.contract.timestamp) || 0,
|
wireFeeTime: getTalerStampSec(proposal.contractTerms.timestamp) || 0,
|
||||||
wireMethod: offer.contract.wire_method,
|
wireMethod: proposal.contractTerms.wire_method,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
@ -2110,9 +2123,9 @@ export class Wallet {
|
|||||||
return denoms;
|
return denoms;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOffer(offerId: number): Promise<any> {
|
async getProposal(proposalId: number): Promise<ProposalRecord|undefined> {
|
||||||
const offer = await this.q() .get(Stores.offers, offerId);
|
const proposal = await this.q().get(Stores.proposals, proposalId);
|
||||||
return offer;
|
return proposal;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getExchanges(): Promise<ExchangeRecord[]> {
|
async getExchanges(): Promise<ExchangeRecord[]> {
|
||||||
|
@ -69,11 +69,11 @@ export interface MessageMap {
|
|||||||
response: string;
|
response: string;
|
||||||
};
|
};
|
||||||
"confirm-pay": {
|
"confirm-pay": {
|
||||||
request: { offer: types.OfferRecord; };
|
request: { proposalId: number; };
|
||||||
response: types.ConfirmPayResult;
|
response: types.ConfirmPayResult;
|
||||||
};
|
};
|
||||||
"check-pay": {
|
"check-pay": {
|
||||||
request: { offer: types.OfferRecord; };
|
request: { proposalId: number; };
|
||||||
response: types.CheckPayResult;
|
response: types.CheckPayResult;
|
||||||
};
|
};
|
||||||
"query-payment": {
|
"query-payment": {
|
||||||
@ -96,21 +96,29 @@ export interface MessageMap {
|
|||||||
request: { historyEntry: types.HistoryRecord };
|
request: { historyEntry: types.HistoryRecord };
|
||||||
response: void;
|
response: void;
|
||||||
};
|
};
|
||||||
"safe-offer": {
|
"save-proposal": {
|
||||||
request: { offer: types.OfferRecord };
|
request: { proposal: types.ProposalRecord };
|
||||||
response: void;
|
response: void;
|
||||||
};
|
};
|
||||||
"reserve-creation-info": {
|
"reserve-creation-info": {
|
||||||
request: { baseUrl: string };
|
request: { baseUrl: string, amount: types.AmountJson };
|
||||||
response: types.ReserveCreationInfo;
|
response: types.ReserveCreationInfo;
|
||||||
}
|
}
|
||||||
"get-history": {
|
"get-history": {
|
||||||
request: { };
|
request: { };
|
||||||
response: types.HistoryRecord[];
|
response: types.HistoryRecord[];
|
||||||
};
|
};
|
||||||
"get-offer": {
|
"get-proposal": {
|
||||||
request: { offerId: number };
|
request: { proposalId: number };
|
||||||
response: types.OfferRecord | undefined;
|
response: types.ProposalRecord | undefined;
|
||||||
|
};
|
||||||
|
"get-coins": {
|
||||||
|
request: { exchangeBaseUrl: string };
|
||||||
|
response: any;
|
||||||
|
};
|
||||||
|
"refresh-coin": {
|
||||||
|
request: { coinPub: string };
|
||||||
|
response: any;
|
||||||
};
|
};
|
||||||
"get-currencies": {
|
"get-currencies": {
|
||||||
request: { };
|
request: { };
|
||||||
@ -120,6 +128,10 @@ export interface MessageMap {
|
|||||||
request: { currencyRecord: types.CurrencyRecord };
|
request: { currencyRecord: types.CurrencyRecord };
|
||||||
response: void;
|
response: void;
|
||||||
};
|
};
|
||||||
|
"get-exchanges": {
|
||||||
|
request: { };
|
||||||
|
response: types.ExchangeRecord[];
|
||||||
|
};
|
||||||
"get-reserves": {
|
"get-reserves": {
|
||||||
request: { exchangeBaseUrl: string };
|
request: { exchangeBaseUrl: string };
|
||||||
response: types.ReserveRecord[];
|
response: types.ReserveRecord[];
|
||||||
|
@ -280,7 +280,8 @@ async function processProposal(proposal: any) {
|
|||||||
const contractHash = await wxApi.hashContract(proposal.data);
|
const contractHash = await wxApi.hashContract(proposal.data);
|
||||||
|
|
||||||
if (contractHash !== proposal.hash) {
|
if (contractHash !== proposal.hash) {
|
||||||
console.error("merchant-supplied contract hash is wrong");
|
console.error(`merchant-supplied contract hash is wrong (us: ${contractHash}, merchant: ${proposal.hash})`);
|
||||||
|
console.dir(proposal.data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,12 +302,11 @@ async function processProposal(proposal: any) {
|
|||||||
type: "offer-contract",
|
type: "offer-contract",
|
||||||
};
|
};
|
||||||
await wxApi.putHistory(historyEntry);
|
await wxApi.putHistory(historyEntry);
|
||||||
const offerId = await wxApi.saveOffer(proposal);
|
let proposalId = await wxApi.saveProposal(proposal);
|
||||||
|
|
||||||
const uri = new URI(chrome.extension.getURL(
|
const uri = new URI(chrome.extension.getURL("/src/webex/pages/confirm-contract.html"));
|
||||||
"/src/webex/pages/confirm-contract.html"));
|
|
||||||
const params = {
|
const params = {
|
||||||
offerId: offerId.toString(),
|
proposalId: proposalId.toString(),
|
||||||
};
|
};
|
||||||
const target = uri.query(params).href();
|
const target = uri.query(params).href();
|
||||||
document.location.replace(target);
|
document.location.replace(target);
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Taler Wallet: Confirm Reserve Creation</title>
|
<title>Taler Wallet: Confirm Reserve Creation</title>
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="/src/style/wallet.css">
|
<link rel="stylesheet" type="text/css" href="../style/wallet.css">
|
||||||
|
|
||||||
<link rel="icon" href="/img/icon.png">
|
<link rel="icon" href="/img/icon.png">
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ import * as i18n from "../../i18n";
|
|||||||
import {
|
import {
|
||||||
Contract,
|
Contract,
|
||||||
ExchangeRecord,
|
ExchangeRecord,
|
||||||
OfferRecord,
|
ProposalRecord,
|
||||||
} from "../../types";
|
} from "../../types";
|
||||||
|
|
||||||
import { renderContract } from "../renderHtml";
|
import { renderContract } from "../renderHtml";
|
||||||
@ -98,11 +98,11 @@ class Details extends React.Component<DetailProps, DetailState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ContractPromptProps {
|
interface ContractPromptProps {
|
||||||
offerId: number;
|
proposalId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ContractPromptState {
|
interface ContractPromptState {
|
||||||
offer: OfferRecord|null;
|
proposal: ProposalRecord|null;
|
||||||
error: string|null;
|
error: string|null;
|
||||||
payDisabled: boolean;
|
payDisabled: boolean;
|
||||||
exchanges: null|ExchangeRecord[];
|
exchanges: null|ExchangeRecord[];
|
||||||
@ -114,7 +114,7 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
|
|||||||
this.state = {
|
this.state = {
|
||||||
error: null,
|
error: null,
|
||||||
exchanges: null,
|
exchanges: null,
|
||||||
offer: null,
|
proposal: null,
|
||||||
payDisabled: true,
|
payDisabled: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -128,26 +128,21 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
|
|||||||
}
|
}
|
||||||
|
|
||||||
async update() {
|
async update() {
|
||||||
const offer = await wxApi.getOffer(this.props.offerId);
|
const proposal = await wxApi.getProposal(this.props.proposalId);
|
||||||
this.setState({offer} as any);
|
this.setState({proposal} as any);
|
||||||
this.checkPayment();
|
this.checkPayment();
|
||||||
const exchanges = await wxApi.getExchanges();
|
const exchanges = await wxApi.getExchanges();
|
||||||
this.setState({exchanges} as any);
|
this.setState({exchanges} as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkPayment() {
|
async checkPayment() {
|
||||||
const offer = this.state.offer;
|
const payStatus = await wxApi.checkPay(this.props.proposalId);
|
||||||
if (!offer) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const payStatus = await wxApi.checkPay(offer);
|
|
||||||
|
|
||||||
if (payStatus === "insufficient-balance") {
|
if (payStatus === "insufficient-balance") {
|
||||||
const msgInsufficient = i18n.str`You have insufficient funds of the requested currency in your wallet.`;
|
const msgInsufficient = i18n.str`You have insufficient funds of the requested currency in your wallet.`;
|
||||||
// tslint:disable-next-line:max-line-length
|
// tslint:disable-next-line:max-line-length
|
||||||
const msgNoMatch = i18n.str`You do not have any funds from an exchange that is accepted by this merchant. None of the exchanges accepted by the merchant is known to your wallet.`;
|
const msgNoMatch = i18n.str`You do not have any funds from an exchange that is accepted by this merchant. None of the exchanges accepted by the merchant is known to your wallet.`;
|
||||||
if (this.state.exchanges && this.state.offer) {
|
if (this.state.exchanges && this.state.proposal) {
|
||||||
const acceptedExchangePubs = this.state.offer.contract.exchanges.map((e) => e.master_pub);
|
const acceptedExchangePubs = this.state.proposal.contractTerms.exchanges.map((e) => e.master_pub);
|
||||||
const ex = this.state.exchanges.find((e) => acceptedExchangePubs.indexOf(e.masterPublicKey) >= 0);
|
const ex = this.state.exchanges.find((e) => acceptedExchangePubs.indexOf(e.masterPublicKey) >= 0);
|
||||||
if (ex) {
|
if (ex) {
|
||||||
this.setState({error: msgInsufficient});
|
this.setState({error: msgInsufficient});
|
||||||
@ -165,28 +160,28 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
|
|||||||
}
|
}
|
||||||
|
|
||||||
async doPayment() {
|
async doPayment() {
|
||||||
const offer = this.state.offer;
|
const proposal = this.state.proposal;
|
||||||
if (!offer) {
|
if (!proposal) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const payStatus = await wxApi.confirmPay(offer);
|
const payStatus = await wxApi.confirmPay(this.props.proposalId);
|
||||||
switch (payStatus) {
|
switch (payStatus) {
|
||||||
case "insufficient-balance":
|
case "insufficient-balance":
|
||||||
this.checkPayment();
|
this.checkPayment();
|
||||||
return;
|
return;
|
||||||
case "paid":
|
case "paid":
|
||||||
console.log("contract", offer.contract);
|
console.log("contract", proposal.contractTerms);
|
||||||
document.location.href = offer.contract.fulfillment_url;
|
document.location.href = proposal.contractTerms.fulfillment_url;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.state.offer) {
|
if (!this.state.proposal) {
|
||||||
return <span>...</span>;
|
return <span>...</span>;
|
||||||
}
|
}
|
||||||
const c = this.state.offer.contract;
|
const c = this.state.proposal.contractTerms;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
@ -210,8 +205,8 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
|
|||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
const url = new URI(document.location.href);
|
const url = new URI(document.location.href);
|
||||||
const query: any = URI.parseQuery(url.query());
|
const query: any = URI.parseQuery(url.query());
|
||||||
const offerId = JSON.parse(query.offerId);
|
const proposalId = JSON.parse(query.proposalId);
|
||||||
|
|
||||||
ReactDOM.render(<ContractPrompt offerId={offerId}/>, document.getElementById(
|
ReactDOM.render(<ContractPrompt proposalId={proposalId}/>, document.getElementById(
|
||||||
"contract")!);
|
"contract")!);
|
||||||
});
|
});
|
||||||
|
@ -30,15 +30,16 @@ import {
|
|||||||
CurrencyRecord,
|
CurrencyRecord,
|
||||||
DenominationRecord,
|
DenominationRecord,
|
||||||
ExchangeRecord,
|
ExchangeRecord,
|
||||||
OfferRecord,
|
|
||||||
PreCoinRecord,
|
PreCoinRecord,
|
||||||
ReserveCreationInfo,
|
ReserveCreationInfo,
|
||||||
ReserveRecord,
|
ReserveRecord,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
|
|
||||||
|
import { MessageType, MessageMap } from "./messages";
|
||||||
|
|
||||||
|
|
||||||
async function callBackend(type: string, detail?: any): Promise<any> {
|
|
||||||
|
async function callBackend<T extends MessageType>(type: T, detail: MessageMap[T]["request"]): Promise<any> {
|
||||||
return new Promise<any>((resolve, reject) => {
|
return new Promise<any>((resolve, reject) => {
|
||||||
chrome.runtime.sendMessage({ type, detail }, (resp) => {
|
chrome.runtime.sendMessage({ type, detail }, (resp) => {
|
||||||
if (resp && resp.error) {
|
if (resp && resp.error) {
|
||||||
@ -65,7 +66,7 @@ export function getReserveCreationInfo(baseUrl: string,
|
|||||||
* Get all exchanges the wallet knows about.
|
* Get all exchanges the wallet knows about.
|
||||||
*/
|
*/
|
||||||
export function getExchanges(): Promise<ExchangeRecord[]> {
|
export function getExchanges(): Promise<ExchangeRecord[]> {
|
||||||
return callBackend("get-exchanges");
|
return callBackend("get-exchanges", { });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ export function getExchanges(): Promise<ExchangeRecord[]> {
|
|||||||
* Get all currencies the exchange knows about.
|
* Get all currencies the exchange knows about.
|
||||||
*/
|
*/
|
||||||
export function getCurrencies(): Promise<CurrencyRecord[]> {
|
export function getCurrencies(): Promise<CurrencyRecord[]> {
|
||||||
return callBackend("get-currencies");
|
return callBackend("get-currencies", { });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -114,7 +115,7 @@ export function getReserves(exchangeBaseUrl: string): Promise<ReserveRecord[]> {
|
|||||||
* Get all reserves for which a payback is available.
|
* Get all reserves for which a payback is available.
|
||||||
*/
|
*/
|
||||||
export function getPaybackReserves(): Promise<ReserveRecord[]> {
|
export function getPaybackReserves(): Promise<ReserveRecord[]> {
|
||||||
return callBackend("get-payback-reserves");
|
return callBackend("get-payback-reserves", { });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -166,41 +167,40 @@ export function payback(coinPub: string): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an offer stored in the wallet by its offer id.
|
* Get a proposal stored in the wallet by its proposal id.
|
||||||
* Note that the numeric offer id is not to be confused with
|
|
||||||
* the string order_id from the contract terms.
|
|
||||||
*/
|
*/
|
||||||
export function getOffer(offerId: number) {
|
export function getProposal(proposalId: number) {
|
||||||
return callBackend("get-offer", { offerId });
|
return callBackend("get-proposal", { proposalId });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if payment is possible or already done.
|
* Check if payment is possible or already done.
|
||||||
*/
|
*/
|
||||||
export function checkPay(offer: OfferRecord): Promise<CheckPayResult> {
|
export function checkPay(proposalId: number): Promise<CheckPayResult> {
|
||||||
return callBackend("check-pay", { offer });
|
return callBackend("check-pay", { proposalId });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pay for an offer.
|
* Pay for a proposal.
|
||||||
*/
|
*/
|
||||||
export function confirmPay(offer: OfferRecord): Promise<ConfirmPayResult> {
|
export function confirmPay(proposalId: number): Promise<ConfirmPayResult> {
|
||||||
return callBackend("confirm-pay", { offer });
|
return callBackend("confirm-pay", { proposalId });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash a contract. Throws if its not a valid contract.
|
* Hash a contract. Throws if its not a valid contract.
|
||||||
*/
|
*/
|
||||||
export function hashContract(contract: object): Promise<string> {
|
export function hashContract(contract: object): Promise<string> {
|
||||||
return callBackend("confirm-pay", { contract });
|
return callBackend("hash-contract", { contract });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save an offer in the wallet. Returns the offer id that
|
* Save a proposal in the wallet. Returns the proposal id that
|
||||||
* the offer is stored under.
|
* the proposal is stored under.
|
||||||
*/
|
*/
|
||||||
export function saveOffer(offer: object): Promise<number> {
|
export function saveProposal(proposal: any): Promise<number> {
|
||||||
return callBackend("save-offer", { offer });
|
return callBackend("save-proposal", proposal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -243,7 +243,7 @@ export function paymentFailed(contractTermsHash: string): Promise<void> {
|
|||||||
* cookie was set.
|
* cookie was set.
|
||||||
*/
|
*/
|
||||||
export function getTabCookie(contractTermsHash: string, merchantSig: string): Promise<any> {
|
export function getTabCookie(contractTermsHash: string, merchantSig: string): Promise<any> {
|
||||||
return callBackend("get-tab-cookie");
|
return callBackend("get-tab-cookie", { });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -251,5 +251,5 @@ export function getTabCookie(contractTermsHash: string, merchantSig: string): Pr
|
|||||||
* database and return the public key.
|
* database and return the public key.
|
||||||
*/
|
*/
|
||||||
export function generateNonce(): Promise<string> {
|
export function generateNonce(): Promise<string> {
|
||||||
return callBackend("generate-nonce");
|
return callBackend("generate-nonce", { });
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { Checkable } from "../checkable";
|
|
||||||
import { BrowserHttpLib } from "../http";
|
import { BrowserHttpLib } from "../http";
|
||||||
import * as logging from "../logging";
|
import * as logging from "../logging";
|
||||||
import {
|
import {
|
||||||
@ -34,7 +33,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
AmountJson,
|
AmountJson,
|
||||||
Notifier,
|
Notifier,
|
||||||
OfferRecord,
|
ProposalRecord,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
import {
|
import {
|
||||||
ConfirmReserveRequest,
|
ConfirmReserveRequest,
|
||||||
@ -44,6 +43,7 @@ import {
|
|||||||
} from "../wallet";
|
} from "../wallet";
|
||||||
|
|
||||||
import { ChromeBadge } from "./chromeBadge";
|
import { ChromeBadge } from "./chromeBadge";
|
||||||
|
import { MessageType } from "./messages";
|
||||||
|
|
||||||
import URI = require("urijs");
|
import URI = require("urijs");
|
||||||
import Port = chrome.runtime.Port;
|
import Port = chrome.runtime.Port;
|
||||||
@ -60,21 +60,23 @@ const DB_NAME = "taler";
|
|||||||
*/
|
*/
|
||||||
const DB_VERSION = 17;
|
const DB_VERSION = 17;
|
||||||
|
|
||||||
type Handler = (detail: any, sender: MessageSender) => Promise<any>;
|
function handleMessage(db: IDBDatabase,
|
||||||
|
wallet: Wallet,
|
||||||
function makeHandlers(db: IDBDatabase,
|
sender: MessageSender,
|
||||||
wallet: Wallet): { [msg: string]: Handler } {
|
type: MessageType, detail: any): any {
|
||||||
return {
|
function assertNotFound(t: never): never {
|
||||||
["balances"]: (detail, sender) => {
|
console.error(`Request type ${t as string} unknown`);
|
||||||
|
console.error(`Request detail was ${detail}`);
|
||||||
|
return { error: "request unknown", requestType: type } as never;
|
||||||
|
}
|
||||||
|
switch (type) {
|
||||||
|
case "balances":
|
||||||
return wallet.getBalances();
|
return wallet.getBalances();
|
||||||
},
|
case "dump-db":
|
||||||
["dump-db"]: (detail, sender) => {
|
|
||||||
return exportDb(db);
|
return exportDb(db);
|
||||||
},
|
case "import-db":
|
||||||
["import-db"]: (detail, sender) => {
|
|
||||||
return importDb(db, detail.dump);
|
return importDb(db, detail.dump);
|
||||||
},
|
case "get-tab-cookie":
|
||||||
["get-tab-cookie"]: (detail, sender) => {
|
|
||||||
if (!sender || !sender.tab || !sender.tab.id) {
|
if (!sender || !sender.tab || !sender.tab.id) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
@ -82,11 +84,9 @@ function makeHandlers(db: IDBDatabase,
|
|||||||
const info: any = paymentRequestCookies[id] as any;
|
const info: any = paymentRequestCookies[id] as any;
|
||||||
delete paymentRequestCookies[id];
|
delete paymentRequestCookies[id];
|
||||||
return Promise.resolve(info);
|
return Promise.resolve(info);
|
||||||
},
|
case "ping":
|
||||||
["ping"]: (detail, sender) => {
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
},
|
case "reset":
|
||||||
["reset"]: (detail, sender) => {
|
|
||||||
if (db) {
|
if (db) {
|
||||||
const tx = db.transaction(Array.from(db.objectStoreNames), "readwrite");
|
const tx = db.transaction(Array.from(db.objectStoreNames), "readwrite");
|
||||||
// tslint:disable-next-line:prefer-for-of
|
// tslint:disable-next-line:prefer-for-of
|
||||||
@ -95,69 +95,36 @@ function makeHandlers(db: IDBDatabase,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
deleteDb();
|
deleteDb();
|
||||||
|
|
||||||
chrome.browserAction.setBadgeText({ text: "" });
|
chrome.browserAction.setBadgeText({ text: "" });
|
||||||
console.log("reset done");
|
console.log("reset done");
|
||||||
// Response is synchronous
|
|
||||||
return Promise.resolve({});
|
return Promise.resolve({});
|
||||||
},
|
case "create-reserve": {
|
||||||
["create-reserve"]: (detail, sender) => {
|
|
||||||
const d = {
|
const d = {
|
||||||
amount: detail.amount,
|
amount: detail.amount,
|
||||||
exchange: detail.exchange,
|
exchange: detail.exchange,
|
||||||
};
|
};
|
||||||
const req = CreateReserveRequest.checked(d);
|
const req = CreateReserveRequest.checked(d);
|
||||||
return wallet.createReserve(req);
|
return wallet.createReserve(req);
|
||||||
},
|
}
|
||||||
["confirm-reserve"]: (detail, sender) => {
|
case "confirm-reserve":
|
||||||
// TODO: make it a checkable
|
|
||||||
const d = {
|
const d = {
|
||||||
reservePub: detail.reservePub,
|
reservePub: detail.reservePub,
|
||||||
};
|
};
|
||||||
const req = ConfirmReserveRequest.checked(d);
|
const req = ConfirmReserveRequest.checked(d);
|
||||||
return wallet.confirmReserve(req);
|
return wallet.confirmReserve(req);
|
||||||
},
|
case "generate-nonce":
|
||||||
["generate-nonce"]: (detail, sender) => {
|
|
||||||
return wallet.generateNonce();
|
return wallet.generateNonce();
|
||||||
},
|
case "confirm-pay":
|
||||||
["confirm-pay"]: (detail, sender) => {
|
if (typeof detail.proposalId !== "number") {
|
||||||
let offer: OfferRecord;
|
throw Error("proposalId must be number");
|
||||||
try {
|
|
||||||
offer = OfferRecord.checked(detail.offer);
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof Checkable.SchemaError) {
|
|
||||||
console.error("schema error:", e.message);
|
|
||||||
return Promise.resolve({
|
|
||||||
detail,
|
|
||||||
error: "invalid contract",
|
|
||||||
hint: e.message,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return wallet.confirmPay(detail.proposalId);
|
||||||
return wallet.confirmPay(offer);
|
case "check-pay":
|
||||||
},
|
if (typeof detail.proposalId !== "number") {
|
||||||
["check-pay"]: (detail, sender) => {
|
throw Error("proposalId must be number");
|
||||||
let offer: OfferRecord;
|
|
||||||
try {
|
|
||||||
offer = OfferRecord.checked(detail.offer);
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof Checkable.SchemaError) {
|
|
||||||
console.error("schema error:", e.message);
|
|
||||||
return Promise.resolve({
|
|
||||||
detail,
|
|
||||||
error: "invalid contract",
|
|
||||||
hint: e.message,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return wallet.checkPay(offer);
|
return wallet.checkPay(detail.proposalId);
|
||||||
},
|
case "query-payment":
|
||||||
["query-payment"]: (detail: any, sender: MessageSender) => {
|
|
||||||
if (sender.tab && sender.tab.id) {
|
if (sender.tab && sender.tab.id) {
|
||||||
rateLimitCache[sender.tab.id]++;
|
rateLimitCache[sender.tab.id]++;
|
||||||
if (rateLimitCache[sender.tab.id] > 10) {
|
if (rateLimitCache[sender.tab.id] > 10) {
|
||||||
@ -171,120 +138,98 @@ function makeHandlers(db: IDBDatabase,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wallet.queryPayment(detail.url);
|
return wallet.queryPayment(detail.url);
|
||||||
},
|
case "exchange-info":
|
||||||
["exchange-info"]: (detail) => {
|
|
||||||
if (!detail.baseUrl) {
|
if (!detail.baseUrl) {
|
||||||
return Promise.resolve({ error: "bad url" });
|
return Promise.resolve({ error: "bad url" });
|
||||||
}
|
}
|
||||||
return wallet.updateExchangeFromUrl(detail.baseUrl);
|
return wallet.updateExchangeFromUrl(detail.baseUrl);
|
||||||
},
|
case "currency-info":
|
||||||
["currency-info"]: (detail) => {
|
|
||||||
if (!detail.name) {
|
if (!detail.name) {
|
||||||
return Promise.resolve({ error: "name missing" });
|
return Promise.resolve({ error: "name missing" });
|
||||||
}
|
}
|
||||||
return wallet.getCurrencyRecord(detail.name);
|
return wallet.getCurrencyRecord(detail.name);
|
||||||
},
|
case "hash-contract":
|
||||||
["hash-contract"]: (detail) => {
|
|
||||||
if (!detail.contract) {
|
if (!detail.contract) {
|
||||||
return Promise.resolve({ error: "contract missing" });
|
return Promise.resolve({ error: "contract missing" });
|
||||||
}
|
}
|
||||||
return wallet.hashContract(detail.contract).then((hash) => {
|
return wallet.hashContract(detail.contract).then((hash) => {
|
||||||
return { hash };
|
return hash;
|
||||||
});
|
});
|
||||||
},
|
case "put-history-entry":
|
||||||
["put-history-entry"]: (detail: any) => {
|
|
||||||
if (!detail.historyEntry) {
|
if (!detail.historyEntry) {
|
||||||
return Promise.resolve({ error: "historyEntry missing" });
|
return Promise.resolve({ error: "historyEntry missing" });
|
||||||
}
|
}
|
||||||
return wallet.putHistory(detail.historyEntry);
|
return wallet.putHistory(detail.historyEntry);
|
||||||
},
|
case "save-proposal":
|
||||||
["save-offer"]: (detail: any) => {
|
console.log("handling save-proposal", detail);
|
||||||
const offer = detail.offer;
|
const checkedRecord = ProposalRecord.checked({
|
||||||
if (!offer) {
|
contractTerms: detail.data,
|
||||||
return Promise.resolve({ error: "offer missing" });
|
contractTermsHash: detail.hash,
|
||||||
}
|
merchantSig: detail.sig,
|
||||||
console.log("handling safe-offer", detail);
|
});
|
||||||
// FIXME: fully migrate to new terminology
|
return wallet.saveProposal(checkedRecord);
|
||||||
const checkedOffer = OfferRecord.checked(offer);
|
case "reserve-creation-info":
|
||||||
return wallet.saveOffer(checkedOffer);
|
|
||||||
},
|
|
||||||
["reserve-creation-info"]: (detail, sender) => {
|
|
||||||
if (!detail.baseUrl || typeof detail.baseUrl !== "string") {
|
if (!detail.baseUrl || typeof detail.baseUrl !== "string") {
|
||||||
return Promise.resolve({ error: "bad url" });
|
return Promise.resolve({ error: "bad url" });
|
||||||
}
|
}
|
||||||
const amount = AmountJson.checked(detail.amount);
|
const amount = AmountJson.checked(detail.amount);
|
||||||
return wallet.getReserveCreationInfo(detail.baseUrl, amount);
|
return wallet.getReserveCreationInfo(detail.baseUrl, amount);
|
||||||
},
|
case "get-history":
|
||||||
["get-history"]: (detail, sender) => {
|
|
||||||
// TODO: limit history length
|
// TODO: limit history length
|
||||||
return wallet.getHistory();
|
return wallet.getHistory();
|
||||||
},
|
case "get-proposal":
|
||||||
["get-offer"]: (detail, sender) => {
|
return wallet.getProposal(detail.proposalId);
|
||||||
return wallet.getOffer(detail.offerId);
|
case "get-exchanges":
|
||||||
},
|
|
||||||
["get-exchanges"]: (detail, sender) => {
|
|
||||||
return wallet.getExchanges();
|
return wallet.getExchanges();
|
||||||
},
|
case "get-currencies":
|
||||||
["get-currencies"]: (detail, sender) => {
|
|
||||||
return wallet.getCurrencies();
|
return wallet.getCurrencies();
|
||||||
},
|
case "update-currency":
|
||||||
["update-currency"]: (detail, sender) => {
|
|
||||||
return wallet.updateCurrency(detail.currencyRecord);
|
return wallet.updateCurrency(detail.currencyRecord);
|
||||||
},
|
case "get-reserves":
|
||||||
["get-reserves"]: (detail, sender) => {
|
|
||||||
if (typeof detail.exchangeBaseUrl !== "string") {
|
if (typeof detail.exchangeBaseUrl !== "string") {
|
||||||
return Promise.reject(Error("exchangeBaseUrl missing"));
|
return Promise.reject(Error("exchangeBaseUrl missing"));
|
||||||
}
|
}
|
||||||
return wallet.getReserves(detail.exchangeBaseUrl);
|
return wallet.getReserves(detail.exchangeBaseUrl);
|
||||||
},
|
case "get-payback-reserves":
|
||||||
["get-payback-reserves"]: (detail, sender) => {
|
|
||||||
return wallet.getPaybackReserves();
|
return wallet.getPaybackReserves();
|
||||||
},
|
case "withdraw-payback-reserve":
|
||||||
["withdraw-payback-reserve"]: (detail, sender) => {
|
|
||||||
if (typeof detail.reservePub !== "string") {
|
if (typeof detail.reservePub !== "string") {
|
||||||
return Promise.reject(Error("reservePub missing"));
|
return Promise.reject(Error("reservePub missing"));
|
||||||
}
|
}
|
||||||
return wallet.withdrawPaybackReserve(detail.reservePub);
|
return wallet.withdrawPaybackReserve(detail.reservePub);
|
||||||
},
|
case "get-coins":
|
||||||
["get-coins"]: (detail, sender) => {
|
|
||||||
if (typeof detail.exchangeBaseUrl !== "string") {
|
if (typeof detail.exchangeBaseUrl !== "string") {
|
||||||
return Promise.reject(Error("exchangBaseUrl missing"));
|
return Promise.reject(Error("exchangBaseUrl missing"));
|
||||||
}
|
}
|
||||||
return wallet.getCoins(detail.exchangeBaseUrl);
|
return wallet.getCoins(detail.exchangeBaseUrl);
|
||||||
},
|
case "get-precoins":
|
||||||
["get-precoins"]: (detail, sender) => {
|
|
||||||
if (typeof detail.exchangeBaseUrl !== "string") {
|
if (typeof detail.exchangeBaseUrl !== "string") {
|
||||||
return Promise.reject(Error("exchangBaseUrl missing"));
|
return Promise.reject(Error("exchangBaseUrl missing"));
|
||||||
}
|
}
|
||||||
return wallet.getPreCoins(detail.exchangeBaseUrl);
|
return wallet.getPreCoins(detail.exchangeBaseUrl);
|
||||||
},
|
case "get-denoms":
|
||||||
["get-denoms"]: (detail, sender) => {
|
|
||||||
if (typeof detail.exchangeBaseUrl !== "string") {
|
if (typeof detail.exchangeBaseUrl !== "string") {
|
||||||
return Promise.reject(Error("exchangBaseUrl missing"));
|
return Promise.reject(Error("exchangBaseUrl missing"));
|
||||||
}
|
}
|
||||||
return wallet.getDenoms(detail.exchangeBaseUrl);
|
return wallet.getDenoms(detail.exchangeBaseUrl);
|
||||||
},
|
case "refresh-coin":
|
||||||
["refresh-coin"]: (detail, sender) => {
|
|
||||||
if (typeof detail.coinPub !== "string") {
|
if (typeof detail.coinPub !== "string") {
|
||||||
return Promise.reject(Error("coinPub missing"));
|
return Promise.reject(Error("coinPub missing"));
|
||||||
}
|
}
|
||||||
return wallet.refresh(detail.coinPub);
|
return wallet.refresh(detail.coinPub);
|
||||||
},
|
case "payback-coin":
|
||||||
["payback-coin"]: (detail, sender) => {
|
|
||||||
if (typeof detail.coinPub !== "string") {
|
if (typeof detail.coinPub !== "string") {
|
||||||
return Promise.reject(Error("coinPub missing"));
|
return Promise.reject(Error("coinPub missing"));
|
||||||
}
|
}
|
||||||
return wallet.payback(detail.coinPub);
|
return wallet.payback(detail.coinPub);
|
||||||
},
|
case "payment-failed":
|
||||||
["payment-failed"]: (detail, sender) => {
|
|
||||||
// For now we just update exchanges (maybe the exchange did something
|
// For now we just update exchanges (maybe the exchange did something
|
||||||
// wrong and the keys were messed up).
|
// wrong and the keys were messed up).
|
||||||
// FIXME: in the future we should look at what actually went wrong.
|
// FIXME: in the future we should look at what actually went wrong.
|
||||||
console.error("payment reported as failed");
|
console.error("payment reported as failed");
|
||||||
wallet.updateExchanges();
|
wallet.updateExchanges();
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
},
|
case "payment-succeeded":
|
||||||
["payment-succeeded"]: (detail, sender) => {
|
|
||||||
const contractTermsHash = detail.contractTermsHash;
|
const contractTermsHash = detail.contractTermsHash;
|
||||||
const merchantSig = detail.merchantSig;
|
const merchantSig = detail.merchantSig;
|
||||||
if (!contractTermsHash) {
|
if (!contractTermsHash) {
|
||||||
@ -294,24 +239,16 @@ function makeHandlers(db: IDBDatabase,
|
|||||||
return Promise.reject(Error("merchantSig missing"));
|
return Promise.reject(Error("merchantSig missing"));
|
||||||
}
|
}
|
||||||
return wallet.paymentSucceeded(contractTermsHash, merchantSig);
|
return wallet.paymentSucceeded(contractTermsHash, merchantSig);
|
||||||
},
|
default:
|
||||||
};
|
// Exhaustiveness check.
|
||||||
|
// See https://www.typescriptlang.org/docs/handbook/advanced-types.html
|
||||||
|
return assertNotFound(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function dispatch(db: IDBDatabase, wallet: Wallet, req: any, sender: any, sendResponse: any): Promise<void> {
|
||||||
async function dispatch(handlers: any, req: any, sender: any, sendResponse: any): Promise<void> {
|
|
||||||
if (!(req.type in handlers)) {
|
|
||||||
console.error(`Request type ${req.type} unknown`);
|
|
||||||
console.error(`Request was ${req}`);
|
|
||||||
try {
|
|
||||||
sendResponse({ error: "request unknown", requestType: req.type });
|
|
||||||
} catch (e) {
|
|
||||||
// might fail if tab disconnected
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const p = handlers[req.type](req.detail, sender);
|
const p = handleMessage(db, wallet, sender, req.type, req.detail);
|
||||||
const r = await p;
|
const r = await p;
|
||||||
try {
|
try {
|
||||||
sendResponse(r);
|
sendResponse(r);
|
||||||
@ -587,9 +524,8 @@ export async function wxMain() {
|
|||||||
|
|
||||||
// Handlers for messages coming directly from the content
|
// Handlers for messages coming directly from the content
|
||||||
// script on the page
|
// script on the page
|
||||||
const handlers = makeHandlers(db, wallet!);
|
|
||||||
chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
|
chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
|
||||||
dispatch(handlers, req, sender, sendResponse);
|
dispatch(db, wallet, req, sender, sendResponse);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user