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