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

feat(release): update cb63985 #8

Merged
merged 2 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
71 changes: 56 additions & 15 deletions docs/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,14 @@ components:
description: Token type for a given transaction
example: arweave

PriceFiatOrTokenType:
type: string
description: Type for a given price request. Either "fiat" type or "token" type
example: kyve

PaymentAmount:
type: integer
description: Payment amount in a given currency's smallest unit value. For example, $10 USD is 1000
description: Payment amount in a given currency's smallest unit value. For example, $10 USD is 1000. 1 AR is 1000000000000
example: 1000

SignatureHeader:
Expand Down Expand Up @@ -242,6 +247,27 @@ components:
description: Available on a checkout-session top up flow, this is the URL in which to fulfill the quote
example: https://checkout.stripe.com/c/pay/cs_test_a1lFM2vIpifSqH8VtIjnbSGnr0RAQtEx6R2OMbhvbeK7fradNG7357Roxy#fidkdWxOYHwnPyd1blpxYHZxWjA0T1BEcXJGPWR1VUpSbkFJbTdDVV9uVG5sTl9AblFqM3J0YklGcVRqRmlJM1YxaTdvaWdnZjBIYkphckpQYVA8UWs8NktLc3REQmdwNDQwaW5PRm1IbG5CNTVdUGNRaGo3fycpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl

ReturnUrl:
type: string
description: The URL to return to after a successful payment
default: https://app.ardrive.io

SuccessUrl:
type: string
description: The URL to return to after a successful payment
default: https://app.ardrive.io

CancelUrl:
type: string
description: The URL to return to after a canceled payment
default: https://app.ardrive.io

UiMode:
type: string
description: Which UI Mode to create the checkout session in
default: hosted
example: embedded

paths:
# winc Price for ByteCount of Data Items
/price/bytes/{byteCount}:
Expand Down Expand Up @@ -272,8 +298,8 @@ paths:
type: string
default: "Invalid byte count"

"502":
description: Bad Gateway
"503":
description: Service Unavailable
content:
text/plain:
schema:
Expand Down Expand Up @@ -309,7 +335,7 @@ paths:
in: path
required: true
schema:
"$ref": "#/components/schemas/CurrencyType"
"$ref": "#/components/schemas/PriceFiatOrTokenType"

- name: amount
in: path
Expand Down Expand Up @@ -347,8 +373,8 @@ paths:
description: "Error message string dependent on cause"
example: "Payment Amount is Invalid"

"502":
description: Bad Gateway
"503":
description: Service Unavailable
content:
text/plain:
schema:
Expand Down Expand Up @@ -378,7 +404,7 @@ paths:

get:
summary: Get Current Balance of winc
description: Use a signed request or a previously obtained JWT to get the the signing wallet's current service balance in winc
description: Use a signed request or a previously obtained JWT to get the signing wallet's current service balance in winc

responses:
"200":
Expand Down Expand Up @@ -472,10 +498,25 @@ paths:
in: query
required: false
schema:
type: string
description: Which UI Mode to create the checkout session in
default: hosted
example: embedded
"$ref": "#/components/schemas/UiMode"

- name: returnUrl
in: query
required: false
schema:
"$ref": "#/components/schemas/ReturnUrl"

- name: successUrl
in: query
required: false
schema:
"$ref": "#/components/schemas/SuccessUrl"

- name: cancelUrl
in: query
required: false
schema:
"$ref": "#/components/schemas/CancelUrl"

responses:
"200":
Expand Down Expand Up @@ -513,8 +554,8 @@ paths:
description: "Error message string dependent on cause"
example: "Payment Amount is Invalid!"

"502":
description: Bad Gateway
"503":
description: Service Unavailable
content:
text/plain:
schema:
Expand Down Expand Up @@ -764,8 +805,8 @@ paths:
type: string
default: "Transaction ID not found!"

"500":
description: Internal Server Error
"503":
description: Service Unavailable
content:
text/plain:
schema:
Expand Down
5 changes: 5 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { ByteCount } from "./types/byteCount";
import { SupportedFiatPaymentCurrencyType } from "./types/supportedCurrencies";

export const isTestEnv = process.env.NODE_ENV === "test";
export const isDevEnv = process.env.NODE_ENV === "dev";

export const migrateOnStartup = process.env.MIGRATE_ON_STARTUP === "true";
export const defaultPort = +(process.env.PORT ?? 3000);
export const msPerMinute = 1000 * 60;
Expand Down Expand Up @@ -320,6 +322,9 @@ export const maxGiftMessageLength = process.env.MAX_GIFT_MESSAGE_LENGTH ?? 250;
export const giftingEmailAddress =
process.env.GIFTING_EMAIL_ADDRESS ?? "[email protected]";

export const defaultCheckoutSuccessUrl = "https://app.ardrive.io";
export const defaultCheckoutCancelUrl = "https://app.ardrive.io";

/** gifting on top up via email depends on GIFTING_ENABLED="true" env var */
export const isGiftingEnabled = process.env.GIFTING_ENABLED === "true";

Expand Down
2 changes: 1 addition & 1 deletion src/database/dbTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const userAddressTypes = [
"solana",
"ethereum",
"kyve",
"matic"
"matic",
] as const;
export type UserAddressType = (typeof userAddressTypes)[number];

Expand Down
57 changes: 25 additions & 32 deletions src/database/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,32 @@
*/
import { CurrencyType, PaymentAmount, Timestamp, UserAddress } from "./dbTypes";

export class UserNotFoundWarning extends Error {
abstract class BaseError extends Error {
constructor(message: string) {
super(message);
this.name = this.constructor.name;
}
}

export class UserNotFoundWarning extends BaseError {
constructor(userAddress: UserAddress) {
super(`No user found in database with address '${userAddress}'`);
this.name = "UserNotFoundWarning";
}
}

export class InsufficientBalance extends Error {
export class InsufficientBalance extends BaseError {
constructor(userAddress: UserAddress) {
super(`Insufficient balance for '${userAddress}'`);
this.name = "InsufficientBalance";
}
}

export abstract class PaymentValidationError extends Error {}
export abstract class PaymentValidationError extends BaseError {}

export class UnsupportedCurrencyType extends PaymentValidationError {
constructor(currencyType: CurrencyType) {
super(
`The currency type '${currencyType}' is currently not supported by this API!`
);
this.name = "UnsupportedCurrencyType";
}
}

Expand All @@ -46,7 +50,6 @@ export class InvalidPaymentAmount extends PaymentValidationError {
super(
`The provided payment amount (${paymentAmount}) is invalid; it must be a positive non-decimal integer!`
);
this.name = "InvalidPaymentAmount";
}
}

Expand All @@ -59,7 +62,6 @@ export class PaymentAmountTooSmall extends PaymentValidationError {
super(
`The provided payment amount (${paymentAmount}) is too small for the currency type "${currencyType}"; it must be above ${minimumAllowedAmount}!`
);
this.name = "PaymentAmountTooSmall";
}
}

Expand All @@ -72,32 +74,28 @@ export class PaymentAmountTooLarge extends PaymentValidationError {
super(
`The provided payment amount (${paymentAmount}) is too large for the currency type "${currencyType}"; it must be below or equal to ${maximumAllowedAmount}!`
);
this.name = "PaymentAmountTooLarge";
}
}

export abstract class PromoCodeError extends Error {}
export abstract class PromoCodeError extends BaseError {}

export class UserIneligibleForPromoCode extends PromoCodeError {
constructor(userAddress: UserAddress, promoCode: string) {
super(
`The user '${userAddress}' is ineligible for the promo code '${promoCode}'`
);
this.name = "UserIneligibleForPromoCode";
}
}

export class PromoCodeNotFound extends PromoCodeError {
constructor(promoCode: string) {
super(`No promo code found with code '${promoCode}'`);
this.name = "PromoCodeNotFound";
}
}

export class PromoCodeExpired extends PromoCodeError {
constructor(promoCode: string, endDate: Timestamp) {
super(`The promo code '${promoCode}' expired on '${endDate}'`);
this.name = "PromoCodeExpired";
}
}

Expand All @@ -106,7 +104,6 @@ export class PaymentAmountTooSmallForPromoCode extends PromoCodeError {
super(
`The promo code '${promoCode}' can only used on payments above '${minimumPaymentAmount}'`
);
this.name = "PaymentAmountTooSmallForPromoCode";
}
}

Expand All @@ -115,77 +112,73 @@ export class PromoCodeExceedsMaxUses extends PromoCodeError {
super(
`The promo code '${promoCode}' has already been used the maximum number of times (${maxUses})`
);
this.name = "PromoCodeExceedsMaxUses";
}
}

export class GiftRedemptionError extends Error {
export class GiftRedemptionError extends BaseError {
constructor(errorMessage = "Failure to redeem payment receipt!") {
super(errorMessage);
this.name = "GiftRedemptionError";
}
}

export class GiftAlreadyRedeemed extends GiftRedemptionError {
constructor() {
super("Gift has already been redeemed!");
this.name = "GiftAlreadyRedeemed";
}
}

export class PaymentTransactionNotMined extends Error {
export class BadQueryParam extends BaseError {
constructor(message?: string) {
super(message ?? `Bad query parameter`);
}
}

export class PaymentTransactionNotMined extends BaseError {
constructor(transactionId: string) {
super(`Transaction with id '${transactionId}' has not been mined yet!`);
this.name = "PaymentTransactionNotMined";
}
}

export class PaymentTransactionNotFound extends Error {
export class PaymentTransactionNotFound extends BaseError {
constructor(transactionId: string) {
super(`No payment transaction found with id '${transactionId}'`);
this.name = "PaymentTransactionNotFound";
}
}

export class PaymentTransactionHasWrongTarget extends Error {
export class PaymentTransactionHasWrongTarget extends BaseError {
constructor(transactionId: string, targetAddress?: string) {
super(
`Payment transaction '${transactionId}' has wrong target address '${targetAddress}'`
);
this.name = "PaymentTransactionHasWrongTarget";
}
}

export class TransactionNotAPaymentTransaction extends Error {
export class TransactionNotAPaymentTransaction extends BaseError {
constructor(transactionId: string) {
super(
`Transaction with id '${transactionId}' is not a payment transaction!`
);
this.name = "TransactionNotAPaymentTransaction";
}
}

export class PaymentTransactionRecipientOnExcludedList extends Error {
export class PaymentTransactionRecipientOnExcludedList extends BaseError {
constructor(transactionId: string, senderAddress: string) {
super(
`Payment transaction '${transactionId}' has sender that is on the excluded address list: '${senderAddress}'`
);
this.name = "PaymentTransactionRecipientOnExcludedList";
}
}

export class BadRequest extends Error {
export class BadRequest extends BaseError {
constructor(message: string) {
super(message);
this.name = "BadRequest";
}
}

export class CryptoPaymentTooSmallError extends Error {
export class CryptoPaymentTooSmallError extends BadRequest {
constructor() {
super(
`Crypto payment amount is too small! Token value must convert to at least one winc`
);
this.name = "CryptoPaymentTooSmallError";
}
}
2 changes: 1 addition & 1 deletion src/gateway/gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const supportedPaymentTokens = [
"ethereum",
"solana",
"kyve",
"matic"
"matic",
] as const;
export type TokenType = (typeof supportedPaymentTokens)[number];
export function isSupportedPaymentToken(token: string): token is TokenType {
Expand Down
2 changes: 1 addition & 1 deletion src/gateway/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ export * from "./kyve";
export * from "./solana";
export * from "./ethereum";
export * from "./arweave";
export * from './matic';
export * from "./matic";
2 changes: 1 addition & 1 deletion src/gateway/matic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class MaticGateway extends Gateway {
endpoint = maticGatewayUrl,
paymentTxPollingWaitTimeMs,
pendingTxMaxAttempts,
minConfirmations = +(process.env.MATIC_MIN_CONFIRMATIONS || 5),
minConfirmations = +(process.env.MATIC_MIN_CONFIRMATIONS || 12),
}: MaticGatewayParams = {}) {
super({
paymentTxPollingWaitTimeMs,
Expand Down
Loading