Skip to content

Commit

Permalink
Record balance changes
Browse files Browse the repository at this point in the history
  • Loading branch information
chiliec committed Aug 14, 2024
1 parent c36d41f commit 5689dbb
Show file tree
Hide file tree
Showing 41 changed files with 398 additions and 502 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"trailingComma": "all",
"semi": false,
"singleQuote": false,
"printWidth": 80,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
Expand Down
12 changes: 2 additions & 10 deletions src/backend/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,7 @@ function aesEncrypt(
}

// Main function to process and send an event
async function processEvent(
event: object,
publicKey: string,
apiGateway: string,
apiKey: string,
) {
async function processEvent(event: object, publicKey: string, apiGateway: string, apiKey: string) {
try {
// Generate AES key and IV
const { key, iv } = generateAESKeyIV()
Expand Down Expand Up @@ -116,10 +111,7 @@ async function processEvent(

const analyticsHandler = (fastify: any, _options: any, done: () => void) => {
fastify.get("/config", async (_request: any, _reply: any) => {
return getEncryptionKeys(
config.TELEMETREE_PROJECT_ID,
config.TELEMETREE_API_KEY,
)
return getEncryptionKeys(config.TELEMETREE_PROJECT_ID, config.TELEMETREE_API_KEY)
})

fastify.post("/send", async (_request: any, _reply: any) => {
Expand Down
6 changes: 1 addition & 5 deletions src/backend/auth-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ import { logger } from "#root/logger"
import { validate } from "@tma.js/init-data-node"
import { FastifyInstance } from "fastify"

export const authHandler = (
fastify: FastifyInstance,
_options: unknown,
done: () => void,
) => {
export const authHandler = (fastify: FastifyInstance, _options: unknown, done: () => void) => {
// eslint-disable-next-line no-unused-vars
fastify.post("/:userId", async (request, _reply) => {
const { userId } = request.params as any
Expand Down
9 changes: 2 additions & 7 deletions src/backend/captcha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,10 @@ const checkCaptcha = (fastify: any, _options: any, done: () => void) => {
const user = await findUserById(userId)
if (!user || !user.suspicionDices) return { result: false }
if (user.suspicionDices === Number(data) + 1 + 100) {
logger.info(
`Solved captcha from ${user.id} with ${user.suspicionDices} suspicion dices`,
)
logger.info(`Solved captcha from ${user.id} with ${user.suspicionDices} suspicion dices`)
user.suspicionDices = 0
await user.save()
await _options.bot.api.sendMessage(
userId,
i18n.t(user.language, "dice.captcha_solved"),
)
await _options.bot.api.sendMessage(userId, i18n.t(user.language, "dice.captcha_solved"))
return { result: true }
}
}
Expand Down
11 changes: 2 additions & 9 deletions src/backend/nft-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,15 @@ function toJSON(nft: DocumentType<CNFT>) {
}
}

const nftHandler = (
fastify: FastifyInstance,
_options: any,
done: () => void,
) => {
const nftHandler = (fastify: FastifyInstance, _options: any, done: () => void) => {
fastify.get("/collection.json", (_request: any, _reply: any) => {
return {
name: "Cube Worlds Citizens",
description: "Cube Worlds Project Citizens",
image: "https://cubeworlds.club/avatar.png",
// external_url: null,
// external_link: null,
social_links: [
"https://t.me/cube_worlds_bot",
"https://twitter.com/cube_worlds",
],
social_links: ["https://t.me/cube_worlds_bot", "https://twitter.com/cube_worlds"],
marketplace: "getgems.io",
cover_image: "https://cubeworlds.club/background.png",
}
Expand Down
15 changes: 4 additions & 11 deletions src/bot/features/admin/parameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ feature.command("description", logHandle("command-description"), async ctx => {
await ctx.reply(`<code>/description ${ctx.dbuser.customDescription}</code>`)
return
}
await ctx.reply(
`<code>/description</code> ${oldCustomDescription ?? "about selected person"}`,
)
await ctx.reply(`<code>/description</code> ${oldCustomDescription ?? "about selected person"}`)
})

feature.command("positive", logHandle("command-positive"), async ctx => {
Expand Down Expand Up @@ -73,9 +71,7 @@ feature.command("scale", logHandle("command-scale"), async ctx => {
await ctx.dbuser.save()
return ctx.reply(`New scale: <code>/scale ${newScale}</code>`)
}
return ctx.reply(
`Current scale: <code>/scale ${oldScale}</code>. Can be in range [0 .. 35]`,
)
return ctx.reply(`Current scale: <code>/scale ${oldScale}</code>. Can be in range [0 .. 35]`)
})

feature.command("steps", logHandle("command-steps"), async ctx => {
Expand All @@ -89,9 +85,7 @@ feature.command("steps", logHandle("command-steps"), async ctx => {
await ctx.dbuser.save()
return ctx.reply(`New steps: <code>/steps ${newSteps}</code>`)
}
return ctx.reply(
`Current steps: <code>/steps ${oldSteps}</code>. Can be in range [ 10 .. 50 ]`,
)
return ctx.reply(`Current steps: <code>/steps ${oldSteps}</code>. Can be in range [ 10 .. 50 ]`)
})

feature.command("preset", logHandle("command-preset"), async ctx => {
Expand All @@ -115,8 +109,7 @@ Can be: ${presets.join(", ")}`,

feature.command("sampler", logHandle("command-sampler"), async ctx => {
const oldSampler = ctx.dbuser.sampler ?? SDSampler.K_DPMPP_2S_ANCESTRAL
const newSampler: SDSampler =
SDSampler[ctx.match.trim() as keyof typeof SDSampler]
const newSampler: SDSampler = SDSampler[ctx.match.trim() as keyof typeof SDSampler]
if (newSampler) {
ctx.dbuser.sampler = newSampler
await ctx.dbuser.save()
Expand Down
45 changes: 10 additions & 35 deletions src/bot/features/admin/queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@
import { Composer, InputFile } from "grammy"
import type { Context } from "#root/bot/context.js"
import { logHandle } from "#root/bot/helpers/logging.js"
import {
photoCaption,
queueMenu,
sendUserMetadata,
} from "#root/bot/keyboards/queue-menu.js"
import { photoCaption, queueMenu, sendUserMetadata } from "#root/bot/keyboards/queue-menu.js"
import { isAdmin } from "#root/bot/filters/is-admin.js"
import { config } from "#root/config.js"
import { Address, toNano } from "@ton/core"
Expand All @@ -15,17 +11,8 @@ import { changeImageData } from "#root/bot/callback-data/image-selection.js"
import { SelectImageButton, photoKeyboard } from "#root/bot/keyboards/photo.js"
import { NftCollection } from "#root/bot/helpers/nft-collection.js"
import { NFTMintParameters, NftItem } from "#root/bot/helpers/nft-item.js"
import {
pinImageURLToIPFS,
pinJSONToIPFS,
unpin,
warmIPFSHash,
} from "#root/bot/helpers/ipfs.js"
import {
ClipGuidancePreset,
SDSampler,
generate,
} from "#root/bot/helpers/generation.js"
import { pinImageURLToIPFS, pinJSONToIPFS, unpin, warmIPFSHash } from "#root/bot/helpers/ipfs.js"
import { ClipGuidancePreset, SDSampler, generate } from "#root/bot/helpers/generation.js"
import { randomAttributes } from "#root/bot/helpers/attributes.js"
import { countUsers, findUserById } from "#root/bot/models/user.js"
import { ChatGPTAPI } from "chatgpt"
Expand All @@ -37,7 +24,7 @@ import {
sendPreviewNFT,
sendToGroupsNewNFT,
// sendNewPlaces,
} from "../../helpers/telegram"
} from "#root/bot/helpers/telegram.js"

const composer = new Composer<Context>()

Expand Down Expand Up @@ -78,8 +65,7 @@ feature.callbackQuery(
},
})
const name = selectedUser.name ?? ""
const info =
ctx.dbuser.customDescription ?? selectedUser.description ?? ""
const info = ctx.dbuser.customDescription ?? selectedUser.description ?? ""
const result = await api.sendMessage(
`Write an inspiring text about a person named "${name}" who has decided to start a journey.
You could also use additional information: "${info}", if it feels appropriate, and translate into English if not.
Expand Down Expand Up @@ -139,14 +125,10 @@ feature.callbackQuery(

case SelectImageButton.Avatar: {
const nextAvatarNumber =
ctx.dbuser.selectedUser === selectedUser.id
? (ctx.dbuser.avatarNumber ?? -1) + 1
: 0
ctx.dbuser.selectedUser === selectedUser.id ? (ctx.dbuser.avatarNumber ?? -1) + 1 : 0
ctx.dbuser.avatarNumber = nextAvatarNumber
await ctx.dbuser.save()
sendUserMetadata(ctx, selectedUser).catch(error =>
ctx.reply((error as Error).message),
)
sendUserMetadata(ctx, selectedUser).catch(error => ctx.reply((error as Error).message))
break
}

Expand Down Expand Up @@ -185,11 +167,7 @@ feature.callbackQuery(
attributes: randomAttributes(),
}
ctx.logger.info(json)
const ipfsJSONHash = await pinJSONToIPFS(
adminIndex(ctx.dbuser.id),
username,
json,
)
const ipfsJSONHash = await pinJSONToIPFS(adminIndex(ctx.dbuser.id), username, json)
selectedUser.nftImage = ipfsImageHash
selectedUser.nftJson = ipfsJSONHash
await selectedUser.save()
Expand Down Expand Up @@ -222,8 +200,7 @@ feature.callbackQuery(
selectedUser.mintedAt = new Date()
await selectedUser.save()

const nextItemIndex =
await NftCollection.fetchNextItemIndexWithRetry()
const nextItemIndex = await NftCollection.fetchNextItemIndexWithRetry()
const userAddress = Address.parse(selectedUser.wallet ?? "")
const parameters: NFTMintParameters = {
queryId: 0,
Expand Down Expand Up @@ -297,9 +274,7 @@ feature.callbackQuery(
} catch (error) {
ctx.logger.error(error)
const { message } = error as Error
await (message
? ctx.reply(`Error: ${message}`)
: ctx.reply(ctx.t("wrong")))
await (message ? ctx.reply(`Error: ${message}`) : ctx.reply(ctx.t("wrong")))
}
ctx.chatAction = null
},
Expand Down
21 changes: 8 additions & 13 deletions src/bot/features/admin/topup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,13 @@ const composer = new Composer<Context>()

const feature = composer.chatType("private").filter(isAdmin)

feature.command(
"topup",
logHandle("command-topup"),
chatAction("upload_document"),
async ctx => {
const wallet = await openWallet(config.MNEMONICS!.split(" "))
const collectionAddress = Address.parse(config.COLLECTION_ADDRESS)
const seqno = await topUpBalance(wallet, collectionAddress, 10)
ctx.logger.info(`Collection ${collectionAddress} will be topUpped`)
await waitSeqno(seqno, wallet)
await ctx.reply(`Collection ${collectionAddress} topUpped!`)
},
)
feature.command("topup", logHandle("command-topup"), chatAction("upload_document"), async ctx => {
const wallet = await openWallet(config.MNEMONICS!.split(" "))
const collectionAddress = Address.parse(config.COLLECTION_ADDRESS)
const seqno = await topUpBalance(wallet, collectionAddress, 10)
ctx.logger.info(`Collection ${collectionAddress} will be topUpped`)
await waitSeqno(seqno, wallet)
await ctx.reply(`Collection ${collectionAddress} topUpped!`)
})

export { composer as topupFeature }
7 changes: 3 additions & 4 deletions src/bot/features/admin/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Context } from "#root/bot/context.js"
import { logHandle } from "#root/bot/helpers/logging.js"
import { isAdmin } from "#root/bot/filters/is-admin.js"
import { fromNano } from "@ton/core"
import { BalanceChangeType } from "#root/bot/models/balance"
import { addPoints, findUserByName } from "../../models/user"
import { findTransaction } from "../../models/transaction"
import { tonToPoints } from "../../helpers/ton"
Expand All @@ -20,9 +21,7 @@ feature.command("transaction", logHandle("command-transaction"), async ctx => {

const trx = await findTransaction(numberLt, hash)
if (!trx) {
return ctx.reply(
`Transaction with hash \`${hash}\` and lt \`${numberLt}\` not found`,
)
return ctx.reply(`Transaction with hash \`${hash}\` and lt \`${numberLt}\` not found`)
}

if (trx.accepted) {
Expand All @@ -45,7 +44,7 @@ feature.command("transaction", logHandle("command-transaction"), async ctx => {
// add points to user balance
const ton = fromNano(trx.coins)
const points = tonToPoints(Number(ton))
await addPoints(user.id, points)
await addPoints(user.id, points, BalanceChangeType.Donation)

// send messages
await sendPlaceInLine(ctx.api, user.id, true)
Expand Down
34 changes: 34 additions & 0 deletions src/bot/features/balance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Composer } from "grammy"
import { getMarkdownTable, Row } from "markdown-table-ts"
import type { Context } from "#root/bot/context.js"
import { logHandle } from "#root/bot/helpers/logging.js"
import { kFormatter } from "#root/bot/helpers/numbers.js"
import {
countAllBalanceRecords,
getBalanceChangeTypeName,
getUserBalanceRecords,
} from "#root/bot/models/balance.js"
import { formatDateTimeCompact } from "#root/bot/helpers/time.js"

const composer = new Composer<Context>()
const feature = composer.chatType("private")

feature.command("balance", logHandle("command-balance"), async ctx => {
const count = await countAllBalanceRecords()
const records = await getUserBalanceRecords(ctx.dbuser.id, count)
const body: Row[] = records.map(v => [
kFormatter(v.amount),
getBalanceChangeTypeName(v.type),
v.createdAt ? formatDateTimeCompact(v.createdAt) : "",
])
const md = `${ctx.t("line.count", { count })}
\`\`\`\n${getMarkdownTable({
table: {
head: ["$CUBE", "Type", "Date"],
body,
},
})}\n\`\`\``
await ctx.replyWithMarkdown(md)
})

export { composer as balanceFeature }
Loading

0 comments on commit 5689dbb

Please sign in to comment.