Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIM-less Checkout #411

Merged
merged 4 commits into from
Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/config/config.local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export default {
privilegedOrigins: [ '*' ],
redirectTarget: window.location.protocol + '//' + window.location.hostname + ':8080/demos.html',
reportToSentry: false,
allowsCheckoutWithoutNim: (origin: string): boolean => true,
sisou marked this conversation as resolved.
Show resolved Hide resolved
};
3 changes: 3 additions & 0 deletions src/config/config.mainnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ export default {
],
redirectTarget: 'https://safe.nimiq.com',
reportToSentry: true,
allowsCheckoutWithoutNim: (origin: string): boolean => [
'https://vendor.cryptopayment.link',
].includes(origin),
};
3 changes: 3 additions & 0 deletions src/config/config.testnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ export default {
],
redirectTarget: 'https://safe.nimiq-testnet.com',
reportToSentry: true,
allowsCheckoutWithoutNim: (origin: string): boolean => [
'https://checkout-service-staging-0.web.app',
].includes(origin),
};
29 changes: 15 additions & 14 deletions src/lib/RequestParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { ParsedNimiqDirectPaymentOptions } from './paymentOptions/NimiqPaymentOp
import { ParsedEtherDirectPaymentOptions } from './paymentOptions/EtherPaymentOptions';
import { ParsedBitcoinDirectPaymentOptions } from './paymentOptions/BitcoinPaymentOptions';
import { Utf8Tools } from '@nimiq/utils';
import config from 'config';

export class RequestParser {
public static parse(
Expand Down Expand Up @@ -118,9 +119,12 @@ export class RequestParser {
}

if (checkoutRequest.version === 2) {
if (!checkoutRequest.paymentOptions.some((option) => option.currency === Currency.NIM)) {
throw new Error('CheckoutRequest must provide a NIM paymentOption.');
if (!config.allowsCheckoutWithoutNim(state.origin)) {
if (!checkoutRequest.paymentOptions.some((option) => option.currency === Currency.NIM)) {
throw new Error('CheckoutRequest must provide a NIM paymentOption.');
}
}
sisou marked this conversation as resolved.
Show resolved Hide resolved

if (!checkoutRequest.shopLogoUrl) {
throw new Error('shopLogoUrl: string is required'); // shop logo non optional in version 2
}
Expand All @@ -144,15 +148,11 @@ export class RequestParser {
}

if (!checkoutRequest.callbackUrl || typeof checkoutRequest.callbackUrl !== 'string') {
if (checkoutRequest.paymentOptions.some(
(option) => option.currency !== Currency.NIM,
)) {
if (checkoutRequest.paymentOptions.some((option) => option.currency !== Currency.NIM)) {
throw new Error('A callbackUrl: string is required for currencies other than NIM to ' +
'monitor payments.');
}
if (!checkoutRequest.paymentOptions.every(
(option) => !!option.protocolSpecific.recipient,
)) {
if (!checkoutRequest.paymentOptions.every((option) => !!option.protocolSpecific.recipient)) {
throw new Error('A callbackUrl: string or all recipients must be provided');
}
} else {
Expand Down Expand Up @@ -206,13 +206,12 @@ export class RequestParser {
case Currency.NIM:
// Once extraData from MultiCurrencyCheckoutRequest is removed
// the next few lines become obsolete.
if (!option.protocolSpecific.extraData) {
if (!option.protocolSpecific.extraData && checkoutRequest.extraData) {
console.warn('Usage of MultiCurrencyCheckoutRequest.extraData is'
+ ' deprecated. Use NimiqDirectPaymentOptions.protocolSpecific'
+ '.extraData instead');
sisou marked this conversation as resolved.
Show resolved Hide resolved

option.protocolSpecific.extraData = checkoutRequest.extraData;
if (option.protocolSpecific.extraData) {
console.warn('Usage of MultiCurrencyCheckoutRequest.extraData is'
+ ' deprecated. Use NimiqDirectPaymentOptions.protocolSpecific'
+ '.extraData instead');
}
}
return new ParsedNimiqDirectPaymentOptions(option);
case Currency.ETH:
Expand All @@ -228,6 +227,8 @@ export class RequestParser {
}),
} as ParsedCheckoutRequest;
}

throw new Error('Invalid version: must be 1 or 2');
case RequestType.ONBOARD:
const onboardRequest = request as OnboardRequest;
return {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/RpcApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ export default class RpcApi {
}
} else if (requestType === RequestType.CHECKOUT) {
const checkoutRequest = request as ParsedCheckoutRequest;
// forceSender only applies to non-multi-currency checkouts.
// forceSender only applies to NIM-only checkouts.
if (checkoutRequest.paymentOptions.length === 1
&& checkoutRequest.paymentOptions[0].currency === Currency.NIM) {

Expand Down
9 changes: 8 additions & 1 deletion src/views/Checkout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class Checkout extends Vue {
@Static private rpcState!: RpcState;
@Static private request!: ParsedCheckoutRequest;
private choosenCurrency: PublicCurrency | null = null;
private selectedCurrency: PublicCurrency = PublicCurrency.NIM;
private selectedCurrency: PublicCurrency | null = null;
private leftCard: PublicCurrency | null = null;
private rightCard: PublicCurrency | null = null;
private initialCurrencies: PublicCurrency[] = [];
Expand All @@ -109,6 +109,8 @@ class Checkout extends Vue {

@Watch('selectedCurrency', { immediate: true })
private updateUnselected() {
if (!this.selectedCurrency) return;

sisou marked this conversation as resolved.
Show resolved Hide resolved
const entries = this.request.paymentOptions.map((paymentOptions) => paymentOptions.currency);
if (entries.length === 1) return;

Expand All @@ -132,6 +134,11 @@ class Checkout extends Vue {
|| history.state[HISTORY_KEY_SELECTED_CURRENCY] === currency,
);
this.availableCurrencies = [ ...this.initialCurrencies ];
if (this.availableCurrencies.includes(PublicCurrency.NIM)) {
this.selectedCurrency = PublicCurrency.NIM;
} else {
this.selectedCurrency = this.availableCurrencies[0];
}
document.title = 'Nimiq Checkout';
const lastDisclaimerClose = parseInt(window.localStorage[Checkout.DISCLAIMER_CLOSED_STORAGE_KEY], 10);
this.disclaimerRecentlyClosed = !Number.isNaN(lastDisclaimerClose)
Expand Down
8 changes: 6 additions & 2 deletions src/views/SignTransactionLedger.vue
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,11 @@ export default class SignTransactionLedger extends Vue {
if (checkoutRequest.callbackUrl && checkoutRequest.csrf) {
try {
const fetchedPaymentOptions = await CheckoutServerApi.fetchPaymentOption(
checkoutRequest.callbackUrl, Currency.NIM, checkoutPaymentOptions.type, checkoutRequest.csrf);
checkoutRequest.callbackUrl,
checkoutPaymentOptions.currency,
checkoutPaymentOptions.type,
checkoutRequest.csrf,
);
checkoutPaymentOptions.update(fetchedPaymentOptions);
} catch (e) {
this.$rpc.reject(e);
Expand Down Expand Up @@ -375,7 +379,7 @@ export default class SignTransactionLedger extends Vue {
if (this.request.kind !== RequestType.CHECKOUT) return null;
const checkoutRequest = this.request as ParsedCheckoutRequest;
return checkoutRequest.paymentOptions.find(
(option) => option.currency === Currency.NIM,
(option) => option.currency === Currency.NIM, // TODO: Also handle BTC payments
) as ParsedNimiqDirectPaymentOptions;
}

Expand Down