Skip to content

Commit

Permalink
feat(release): update 2007959 (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
dtfiedler authored Apr 2, 2024
2 parents 183023a + 2fa3cce commit 681669d
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 73 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@
"@ardrive/ardrive-promise-cache": "^1.1.4",
"@aws-sdk/client-secrets-manager": "^3.290.0",
"@aws-sdk/client-ssm": "^3.369.0",
"@koa/cors": "^4.0.0",
"@koa/cors": "^5.0.0",
"arweave": "^1.13.4",
"axios": "0.27.2",
"axios": "^1.6.7",
"axios-retry": "^3.4.0",
"bignumber.js": "^9.1.0",
"dotenv": "^16.0.3",
Expand Down
5 changes: 5 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,8 @@ export const giftingEmailAddress =

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

const thirtyMinutesMs = 1000 * 60 * 30;
export const topUpQuoteExpirationMs = +(
process.env.TOP_UP_QUOTE_EXPIRATION_MS ?? thirtyMinutesMs
);
31 changes: 30 additions & 1 deletion src/database/postgres.ts
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,36 @@ export class PostgresDatabase implements Database {
adjustments = [],
}: CreateBalanceReservationParams): Promise<void> {
await this.writer.transaction(async (knexTransaction) => {
const user = await this.getUser(userAddress, knexTransaction);
let user: User;
try {
user = await this.getUser(userAddress, knexTransaction);
} catch (error) {
if (error instanceof UserNotFoundWarning) {
if (reservedWincAmount.winc.isNonZeroNegativeInteger()) {
throw new UserNotFoundWarning(userAddress);
}
this.log.info(
`No user found with address '${userAddress}', but this reservation is free. Creating a new user without balance.`
);
const userDbInsert: UserDBInsert = {
user_address: userAddress,
// TODO: user_address_type should be injected as a parameter
user_address_type: "arweave",
winston_credit_balance: "0",
};
const dbResult = await knexTransaction<UserDBResult>(tableNames.user)
.insert(userDbInsert)
.returning("user_creation_date");
user = {
userAddress,
winstonCreditBalance: new Winston("0"),
promotionalInfo: {},
userAddressType: "arweave",
userCreationDate: dbResult[0].user_creation_date,
};
}
throw error; // Re throw the error if it's not a UserNotFoundWarning
}

const currentWinstonBalance = user.winstonCreditBalance;
const newBalance = currentWinstonBalance.minus(reservedWincAmount.winc);
Expand Down
29 changes: 17 additions & 12 deletions src/routes/checkBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { Next } from "koa";
import { UserNotFoundWarning } from "../database/errors";
import { WincForBytesResponse } from "../pricing/pricing";
import { KoaContext } from "../server";
import { W, Winston } from "../types";
import {
validateAuthorizedRoute,
validateByteCount,
Expand Down Expand Up @@ -66,27 +67,31 @@ export async function checkBalance(ctx: KoaContext, next: Next) {
const { finalPrice, adjustments } = priceWithAdjustments;

try {
const userBalance = await paymentDatabase.getBalance(walletAddress);
let userBalance: Winston = W("0");
// If price is more than 0, check if user has sufficient balance
if (finalPrice.winc.isNonZeroPositiveInteger() === true) {
userBalance = await paymentDatabase.getBalance(walletAddress);

if (finalPrice.winc.isGreaterThan(userBalance)) {
ctx.response.status = 402;
ctx.response.message = "Insufficient balance";
ctx.body = {
userHasSufficientBalance: false,
bytesCostInWinc: finalPrice.winc.toString(),
userBalanceInWinc: userBalance.toString(),
adjustments: adjustments,
};
return next();
if (finalPrice.winc.isGreaterThan(userBalance)) {
ctx.response.status = 402;
ctx.response.message = "Insufficient balance";
ctx.body = {
userHasSufficientBalance: false,
bytesCostInWinc: finalPrice.winc.toString(),
userBalanceInWinc: userBalance.toString(),
adjustments: adjustments,
};
return next();
}
}

ctx.response.status = 200;
ctx.response.message = "User has sufficient balance";
ctx.body = {
userHasSufficientBalance: true,
bytesCostInWinc: finalPrice.winc.toString(),
userBalanceInWinc: userBalance.toString(),
adjustments: adjustments,
userBalanceInWinc: userBalance.toString(),
};
} catch (error: UserNotFoundWarning | unknown) {
if (error instanceof UserNotFoundWarning) {
Expand Down
13 changes: 8 additions & 5 deletions src/routes/topUp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
isGiftingEnabled,
paymentIntentTopUpMethod,
topUpMethods,
topUpQuoteExpirationMs,
} from "../constants";
import { CreateTopUpQuoteParams } from "../database/dbTypes";
import { PaymentValidationError, PromoCodeError } from "../database/errors";
Expand Down Expand Up @@ -175,10 +176,10 @@ export async function topUp(ctx: KoaContext, next: Next) {
return next();
}

const oneSecondMs = 1000;
const oneMinuteMs = oneSecondMs * 60;
const fiveMinutesMs = oneMinuteMs * 5;
const fiveMinutesFromNow = new Date(Date.now() + fiveMinutesMs).toISOString();
const quoteExpirationDate = new Date(
Date.now() + topUpQuoteExpirationMs
).toISOString();
const quoteExpirationMs = new Date(quoteExpirationDate).getTime();

const {
adjustments,
Expand All @@ -198,7 +199,7 @@ export async function topUp(ctx: KoaContext, next: Next) {
winstonCreditAmount: finalPrice.winc,
destinationAddress,
currencyType: payment.type,
quoteExpirationDate: fiveMinutesFromNow,
quoteExpirationDate,
paymentProvider: "stripe",
adjustments,
giftMessage,
Expand Down Expand Up @@ -272,6 +273,8 @@ export async function topUp(ctx: KoaContext, next: Next) {
automatic_tax: {
enabled: !!process.env.ENABLE_AUTO_STRIPE_TAX || false,
},
// Convert to stripe compatible timestamp, trim off precision
expires_at: Math.floor(quoteExpirationMs / 1000),
payment_method_types: ["card"],
line_items: [
{
Expand Down
4 changes: 2 additions & 2 deletions tests/helpers/signData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/
import Arweave from "arweave/node/common";
import { stringToBuffer } from "arweave/node/lib/utils";
import { AxiosRequestHeaders } from "axios";
import { RawAxiosRequestHeaders } from "axios";
import { Buffer } from "buffer";
import { randomUUID } from "crypto";

Expand All @@ -36,7 +36,7 @@ export async function signedRequestHeadersFromJwk(
jwk: JWKInterface,
nonce: string = randomUUID(),
data = ""
): Promise<AxiosRequestHeaders> {
): Promise<RawAxiosRequestHeaders> {
const signature = await signData(jwk, data + nonce);

return {
Expand Down
4 changes: 2 additions & 2 deletions tests/helpers/testExpectations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { AxiosResponseHeaders } from "axios";
import { RawAxiosRequestHeaders } from "axios";
import { expect } from "chai";

export function assertExpectedHeadersWithContentLength(
headers: AxiosResponseHeaders,
headers: RawAxiosRequestHeaders,
contentLength: number
) {
expect(headers.date).to.exist;
Expand Down
68 changes: 34 additions & 34 deletions tests/router.int.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,19 +245,19 @@ describe("Router tests", () => {
expect(data).to.deep.equal({
// No Infra Fee
fiat: {
aud: 8.888074843239,
brl: 29.787061636803,
cad: 8.055890229538,
eur: 5.48212338304,
gbp: 4.770047888842,
hkd: 47.177146296308,
inr: 493.502634370348,
jpy: 809.295247212831,
sgd: 7.987256446965,
usd: 6.022614420805,
aud: 7.756335974575,
brl: 25.994207049929,
cad: 7.030115328307,
eur: 4.784072092426,
gbp: 4.162666797166,
hkd: 41.169972513698,
inr: 430.663816858609,
jpy: 706.245835090421,
sgd: 6.970220842017,
usd: 5.255741171961,
},
// No Subsidy
winc: "857922282166",
winc: "748681078627",
adjustments: [],
});
clock.restore();
Expand All @@ -277,18 +277,18 @@ describe("Router tests", () => {
expect(data).to.deep.equal({
// No Subsidy
fiat: {
aud: 11.110093554049,
brl: 37.233827046004,
cad: 10.069862786923,
eur: 6.8526542288,
gbp: 5.962559861053,
hkd: 58.971432870385,
inr: 616.878292962935,
jpy: 1011.619059016038,
sgd: 9.984070558706,
usd: 7.528268026006,
aud: 9.695419968219,
brl: 32.492758812411,
cad: 8.787644160384,
eur: 5.980090115533,
gbp: 5.203333496457,
hkd: 51.462465642123,
inr: 538.329771073261,
jpy: 882.807293863027,
sgd: 8.712776052521,
usd: 6.569676464951,
},
winc: "857922282166",
winc: "748681078627",
adjustments: [],
});
clock.restore();
Expand All @@ -308,21 +308,21 @@ describe("Router tests", () => {

expect(data.fiat).to.deep.equal({
// 23.4% Infra Fee applied
aud: 6.381776976212,
brl: 21.387576893252,
cad: 5.78425538674,
eur: 3.936250470849,
gbp: 3.424969110785,
hkd: 33.873930108293,
inr: 354.34262258945,
jpy: 581.086665752968,
sgd: 5.73497525565,
usd: 4.324331503186,
aud: 5.569170738913,
brl: 18.664247881764,
cad: 5.047732938069,
eur: 3.435038708654,
gbp: 2.988859971849,
hkd: 29.560685225179,
inr: 309.223367195491,
jpy: 507.095573497297,
sgd: 5.004727758618,
usd: 3.773704496831,
});

// 45% Subsidy Event applied
expect(data.winc).to.equal("471857255191");
expect(data.adjustments[0].adjustmentAmount).to.equal("-386065026975");
expect(data.winc).to.equal("411774593244");
expect(data.adjustments[0].adjustmentAmount).to.equal("-336906485383");
clock.restore();
});

Expand Down
38 changes: 23 additions & 15 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1081,12 +1081,12 @@ __metadata:
languageName: node
linkType: hard

"@koa/cors@npm:^4.0.0":
version: 4.0.0
resolution: "@koa/cors@npm:4.0.0"
"@koa/cors@npm:^5.0.0":
version: 5.0.0
resolution: "@koa/cors@npm:5.0.0"
dependencies:
vary: ^1.1.2
checksum: e0760544823532f2d71d792e3076858e38bab9b1c090abea175f1319fd91ea58a1da384a2fe7f5108f1c681e3830b01f62a1cafe271d6406751976af443187aa
checksum: 050701fb57dede2fefe0217459782bab7c9488fd07ff1f87fff680005cab43e03b7509e6015ea68082aadb1b31fe3eea7858ebdc93a2cf6f26d36d071190d50c
languageName: node
linkType: hard

Expand Down Expand Up @@ -2478,13 +2478,14 @@ __metadata:
languageName: node
linkType: hard

"axios@npm:0.27.2":
version: 0.27.2
resolution: "axios@npm:0.27.2"
"axios@npm:^1.6.7":
version: 1.6.7
resolution: "axios@npm:1.6.7"
dependencies:
follow-redirects: ^1.14.9
follow-redirects: ^1.15.4
form-data: ^4.0.0
checksum: 38cb7540465fe8c4102850c4368053c21683af85c5fdf0ea619f9628abbcb59415d1e22ebc8a6390d2bbc9b58a9806c874f139767389c862ec9b772235f06854
proxy-from-env: ^1.1.0
checksum: 87d4d429927d09942771f3b3a6c13580c183e31d7be0ee12f09be6d5655304996bb033d85e54be81606f4e89684df43be7bf52d14becb73a12727bf33298a082
languageName: node
linkType: hard

Expand Down Expand Up @@ -3598,13 +3599,13 @@ __metadata:
languageName: node
linkType: hard

"follow-redirects@npm:^1.14.9":
version: 1.15.2
resolution: "follow-redirects@npm:1.15.2"
"follow-redirects@npm:^1.15.4":
version: 1.15.5
resolution: "follow-redirects@npm:1.15.5"
peerDependenciesMeta:
debug:
optional: true
checksum: faa66059b66358ba65c234c2f2a37fcec029dc22775f35d9ad6abac56003268baf41e55f9ee645957b32c7d9f62baf1f0b906e68267276f54ec4b4c597c2b190
checksum: 5ca49b5ce6f44338cbfc3546823357e7a70813cecc9b7b768158a1d32c1e62e7407c944402a918ea8c38ae2e78266312d617dc68783fac502cbb55e1047b34ec
languageName: node
linkType: hard

Expand Down Expand Up @@ -5650,7 +5651,7 @@ __metadata:
"@aws-sdk/client-secrets-manager": ^3.290.0
"@aws-sdk/client-ssm": ^3.369.0
"@istanbuljs/nyc-config-typescript": ^1.0.2
"@koa/cors": ^4.0.0
"@koa/cors": ^5.0.0
"@trivago/prettier-plugin-sort-imports": ^3.3.0
"@types/bn.js": ^5.1.0
"@types/chai": ^4.3.1
Expand All @@ -5669,7 +5670,7 @@ __metadata:
"@typescript-eslint/eslint-plugin": ^5.25.0
"@typescript-eslint/parser": ^5.25.0
arweave: ^1.13.4
axios: 0.27.2
axios: ^1.6.7
axios-mock-adapter: ^1.21.2
axios-retry: ^3.4.0
bignumber.js: ^9.1.0
Expand Down Expand Up @@ -5913,6 +5914,13 @@ __metadata:
languageName: node
linkType: hard

"proxy-from-env@npm:^1.1.0":
version: 1.1.0
resolution: "proxy-from-env@npm:1.1.0"
checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4
languageName: node
linkType: hard

"pstree.remy@npm:^1.1.8":
version: 1.1.8
resolution: "pstree.remy@npm:1.1.8"
Expand Down

0 comments on commit 681669d

Please sign in to comment.