diff --git a/functions/api/ccd006-citycoin-mining-v2/get-block-winner.ts b/functions/api/ccd006-citycoin-mining-v2/get-block-winner.ts new file mode 100644 index 0000000..d6d8710 --- /dev/null +++ b/functions/api/ccd006-citycoin-mining-v2/get-block-winner.ts @@ -0,0 +1,39 @@ +import { fetchReadOnlyFunction } from 'micro-stacks/api'; +import { uintCV } from 'micro-stacks/clarity'; +import { createResponse, DEPLOYER, NETWORK } from '../../../lib/api-helpers'; + +// TODO: upgrade types and check if EventContext is found +export async function onRequest(context: any): Promise { + // check query parameters + const requestUrl = new URL(context.request.url); + const cityId = requestUrl.searchParams.get('cityId'); + if (!cityId) return createResponse('Missing cityId parameter', 400); + const height = requestUrl.searchParams.get('height'); + if (!height) return createResponse('Missing height parameter', 400); + + // get result from contract + const blockWinner = await getBlockWinner(cityId, height); + + // return result + if (blockWinner === null) return createResponse(`Block winner not found: ${cityId} ${height}`, 404); + return createResponse(blockWinner); +} + +// returns the block winner for a given city ID and block height +async function getBlockWinner(cityId: string, height: string) { + try { + const result = await fetchReadOnlyFunction( + { + contractAddress: DEPLOYER('mainnet'), + contractName: 'ccd006-citycoin-mining-v2', + functionName: 'get-block-winner', + functionArgs: [uintCV(Number(cityId)), uintCV(Number(height))], + network: NETWORK('mainnet'), + }, + true + ); + return typeof result === 'boolean' ? Boolean(result) : null; + } catch (err) { + return null; + } +} diff --git a/functions/api/ccd006-citycoin-mining-v2/get-coinbase-amount.ts b/functions/api/ccd006-citycoin-mining-v2/get-coinbase-amount.ts new file mode 100644 index 0000000..a41fb71 --- /dev/null +++ b/functions/api/ccd006-citycoin-mining-v2/get-coinbase-amount.ts @@ -0,0 +1,39 @@ +import { fetchReadOnlyFunction } from 'micro-stacks/api'; +import { uintCV } from 'micro-stacks/clarity'; +import { createResponse, DEPLOYER, NETWORK } from '../../../lib/api-helpers'; + +// TODO: upgrade types and check if EventContext is found +export async function onRequest(context: any): Promise { + // check query parameters + const requestUrl = new URL(context.request.url); + const cityId = requestUrl.searchParams.get('cityId'); + if (!cityId) return createResponse('Missing cityId parameter', 400); + const height = requestUrl.searchParams.get('height'); + if (!height) return createResponse('Missing height parameter', 400); + + // get result from contract + const coinbaseAmount = await getCoinbaseAmount(cityId, height); + + // return result + if (!coinbaseAmount) return createResponse(`Coinbase amount not found: ${cityId} ${height}`, 404); + return createResponse(coinbaseAmount); +} + +// returns the coinbase amount for a given city ID and block height +async function getCoinbaseAmount(cityId: string, height: string) { + try { + const result = await fetchReadOnlyFunction( + { + contractAddress: DEPLOYER('mainnet'), + contractName: 'ccd006-citycoin-mining-v2', + functionName: 'get-coinbase-amount', + functionArgs: [uintCV(Number(cityId)), uintCV(Number(height))], + network: NETWORK('mainnet'), + }, + true + ); + return Number(result); + } catch (err) { + return null; + } +} diff --git a/functions/api/ccd006-citycoin-mining-v2/get-high-value.ts b/functions/api/ccd006-citycoin-mining-v2/get-high-value.ts new file mode 100644 index 0000000..e477b3f --- /dev/null +++ b/functions/api/ccd006-citycoin-mining-v2/get-high-value.ts @@ -0,0 +1,39 @@ +import { fetchReadOnlyFunction } from 'micro-stacks/api'; +import { uintCV } from 'micro-stacks/clarity'; +import { createResponse, DEPLOYER, NETWORK } from '../../../lib/api-helpers'; + +// TODO: upgrade types and check if EventContext is found +export async function onRequest(context: any): Promise { + // check query parameters + const requestUrl = new URL(context.request.url); + const cityId = requestUrl.searchParams.get('cityId'); + if (!cityId) return createResponse('Missing cityId parameter', 400); + const height = requestUrl.searchParams.get('height'); + if (!height) return createResponse('Missing height parameter', 400); + + // get result from contract + const highValue = await getHighValue(cityId, height); + + // return result + if (!highValue) return createResponse(`High value not found: ${cityId} ${height}`, 404); + return createResponse(highValue); +} + +// returns the high value for a given city ID and block height +async function getHighValue(cityId: string, height: string) { + try { + const result = await fetchReadOnlyFunction( + { + contractAddress: DEPLOYER('mainnet'), + contractName: 'ccd006-citycoin-mining-v2', + functionName: 'get-high-value', + functionArgs: [uintCV(Number(cityId)), uintCV(Number(height))], + network: NETWORK('mainnet'), + }, + true + ); + return Number(result); + } catch (err) { + return null; + } +} diff --git a/functions/api/ccd006-citycoin-mining-v2/get-miner.ts b/functions/api/ccd006-citycoin-mining-v2/get-miner.ts new file mode 100644 index 0000000..5768972 --- /dev/null +++ b/functions/api/ccd006-citycoin-mining-v2/get-miner.ts @@ -0,0 +1,41 @@ +import { fetchReadOnlyFunction } from 'micro-stacks/api'; +import { uintCV } from 'micro-stacks/clarity'; +import { createResponse, DEPLOYER, Miner, NETWORK } from '../../../lib/api-helpers'; + +// TODO: upgrade types and check if EventContext is found +export async function onRequest(context: any): Promise { + // check query parameters + const requestUrl = new URL(context.request.url); + const cityId = requestUrl.searchParams.get('cityId'); + if (!cityId) return createResponse('Missing cityId parameter', 400); + const height = requestUrl.searchParams.get('height'); + if (!height) return createResponse('Missing height parameter', 400); + const userId = requestUrl.searchParams.get('userId'); + if (!userId) return createResponse('Missing userId parameter', 400); + + // get result from contract + const miner = await getMiner(cityId, height, userId); + + // return result + if (!miner) return createResponse(`Miner not found: ${cityId} ${height} ${userId}`, 404); + return createResponse(miner); +} + +// returns the miner for a given city ID, block height, and user ID +async function getMiner(cityId: string, height: string, userId: string) { + try { + const result = await fetchReadOnlyFunction( + { + contractAddress: DEPLOYER('mainnet'), + contractName: 'ccd006-citycoin-mining-v2', + functionName: 'get-miner', + functionArgs: [uintCV(Number(cityId)), uintCV(Number(height)), uintCV(Number(userId))], + network: NETWORK('mainnet'), + }, + true + ); + return result as Miner; + } catch (err) { + return null; + } +} diff --git a/functions/api/ccd006-citycoin-mining-v2/get-mining-stats.ts b/functions/api/ccd006-citycoin-mining-v2/get-mining-stats.ts new file mode 100644 index 0000000..abdab64 --- /dev/null +++ b/functions/api/ccd006-citycoin-mining-v2/get-mining-stats.ts @@ -0,0 +1,39 @@ +import { fetchReadOnlyFunction } from 'micro-stacks/api'; +import { uintCV } from 'micro-stacks/clarity'; +import { createResponse, DEPLOYER, MiningStats, NETWORK } from '../../../lib/api-helpers'; + +// TODO: upgrade types and check if EventContext is found +export async function onRequest(context: any): Promise { + // check query parameters + const requestUrl = new URL(context.request.url); + const cityId = requestUrl.searchParams.get('cityId'); + if (!cityId) return createResponse('Missing cityId parameter', 400); + const height = requestUrl.searchParams.get('height'); + if (!height) return createResponse('Missing height parameter', 400); + + // get result from contract + const miningStats = await getMiningStats(cityId, height); + + // return result + if (!miningStats) return createResponse(`Mining stats not found: ${cityId} ${height}`, 404); + return createResponse(miningStats); +} + +// returns the mining stats for a given city ID and block height +async function getMiningStats(cityId: string, height: string) { + try { + const result = await fetchReadOnlyFunction( + { + contractAddress: DEPLOYER('mainnet'), + contractName: 'ccd006-citycoin-mining-v2', + functionName: 'get-mining-stats', + functionArgs: [uintCV(Number(cityId)), uintCV(Number(height))], + network: NETWORK('mainnet'), + }, + true + ); + return result as MiningStats; + } catch (err) { + return null; + } +} diff --git a/functions/api/ccd006-citycoin-mining-v2/get-reward-delay.ts b/functions/api/ccd006-citycoin-mining-v2/get-reward-delay.ts new file mode 100644 index 0000000..1906a5c --- /dev/null +++ b/functions/api/ccd006-citycoin-mining-v2/get-reward-delay.ts @@ -0,0 +1,31 @@ +import { fetchReadOnlyFunction } from 'micro-stacks/api'; +import { createResponse, DEPLOYER, NETWORK } from '../../../lib/api-helpers'; + +// TODO: upgrade types and check if EventContext is found +export async function onRequest(context: any): Promise { + // get result from contract + const rewardDelay = await getRewardDelay(); + + // return result + if (!rewardDelay) return createResponse(`Reward delay not found`, 404); + return createResponse(rewardDelay); +} + +// returns the reward delay +async function getRewardDelay() { + try { + const result = await fetchReadOnlyFunction( + { + contractAddress: DEPLOYER('mainnet'), + contractName: 'ccd006-citycoin-mining-v2', + functionName: 'get-reward-delay', + functionArgs: [], + network: NETWORK('mainnet'), + }, + true + ); + return Number(result); + } catch (err) { + return null; + } +} diff --git a/functions/api/ccd006-citycoin-mining-v2/has-mined-at-block.ts b/functions/api/ccd006-citycoin-mining-v2/has-mined-at-block.ts new file mode 100644 index 0000000..0721650 --- /dev/null +++ b/functions/api/ccd006-citycoin-mining-v2/has-mined-at-block.ts @@ -0,0 +1,41 @@ +import { fetchReadOnlyFunction } from 'micro-stacks/api'; +import { uintCV } from 'micro-stacks/clarity'; +import { createResponse, DEPLOYER, NETWORK } from '../../../lib/api-helpers'; + +// TODO: upgrade types and check if EventContext is found +export async function onRequest(context: any): Promise { + // check query parameters + const requestUrl = new URL(context.request.url); + const cityId = requestUrl.searchParams.get('cityId'); + if (!cityId) return createResponse('Missing cityId parameter', 400); + const height = requestUrl.searchParams.get('height'); + if (!height) return createResponse('Missing height parameter', 400); + const userId = requestUrl.searchParams.get('userId'); + if (!userId) return createResponse('Missing userId parameter', 400); + + // get result from contract + const hasMined = await hasMinedAtBlock(cityId, height, userId); + + // return result + if (hasMined === null) return createResponse(`Miner not found: ${cityId} ${height} ${userId}`, 404); + return createResponse(hasMined); +} + +// returns true if the given user mined at the given block height +async function hasMinedAtBlock(cityId: string, height: string, userId: string) { + try { + const result = await fetchReadOnlyFunction( + { + contractAddress: DEPLOYER('mainnet'), + contractName: 'ccd006-citycoin-mining-v2', + functionName: 'has-mined-at-block', + functionArgs: [uintCV(Number(cityId)), uintCV(Number(height)), uintCV(Number(userId))], + network: NETWORK('mainnet'), + }, + true + ); + return typeof result === 'boolean' ? Boolean(result) : null; + } catch (err) { + return null; + } +} diff --git a/functions/api/ccd006-citycoin-mining-v2/is-block-winner.ts b/functions/api/ccd006-citycoin-mining-v2/is-block-winner.ts new file mode 100644 index 0000000..46fb6aa --- /dev/null +++ b/functions/api/ccd006-citycoin-mining-v2/is-block-winner.ts @@ -0,0 +1,41 @@ +import { fetchReadOnlyFunction } from 'micro-stacks/api'; +import { principalCV, uintCV } from 'micro-stacks/clarity'; +import { BlockWinner, createResponse, DEPLOYER, NETWORK } from '../../../lib/api-helpers'; + +// TODO: upgrade types and check if EventContext is found +export async function onRequest(context: any): Promise { + // check query parameters + const requestUrl = new URL(context.request.url); + const cityId = requestUrl.searchParams.get('cityId'); + if (!cityId) return createResponse('Missing cityId parameter', 400); + const user = requestUrl.searchParams.get('user'); + if (!user) return createResponse('Missing user parameter', 400); + const claimHeight = requestUrl.searchParams.get('claimHeight'); + if (!claimHeight) return createResponse('Missing claimHeight parameter', 400); + + // get result from contract + const winner = await isBlockWinner(cityId, user, claimHeight); + + // return result + if (!winner) return createResponse(`Block winner not found: ${cityId} ${user} ${claimHeight}`, 404); + return createResponse(winner); +} + +// returns true if the given user mined at the given block height +async function isBlockWinner(cityId: string, user: string, claimHeight: string) { + try { + const result = await fetchReadOnlyFunction( + { + contractAddress: DEPLOYER('mainnet'), + contractName: 'ccd006-citycoin-mining-v2', + functionName: 'is-block-winner', + functionArgs: [uintCV(Number(cityId)), principalCV(user), uintCV(Number(claimHeight))], + network: NETWORK('mainnet'), + }, + true + ); + return result as BlockWinner; + } catch (err) { + return null; + } +} diff --git a/functions/api/ccd006-citycoin-mining-v2/is-mining-enabled.ts b/functions/api/ccd006-citycoin-mining-v2/is-mining-enabled.ts new file mode 100644 index 0000000..e68f61b --- /dev/null +++ b/functions/api/ccd006-citycoin-mining-v2/is-mining-enabled.ts @@ -0,0 +1,31 @@ +import { fetchReadOnlyFunction } from 'micro-stacks/api'; +import { createResponse, DEPLOYER, NETWORK } from '../../../lib/api-helpers'; + +// TODO: upgrade types and check if EventContext is found +export async function onRequest(context: any): Promise { + // get result from contract + const enabled = await isMiningEnabled(); + + // return result + if (enabled === null) return createResponse(`Mining enabled status not found`, 404); + return createResponse(enabled); +} + +// returns true if mining is enabled +async function isMiningEnabled() { + try { + const result = await fetchReadOnlyFunction( + { + contractAddress: DEPLOYER('mainnet'), + contractName: 'ccd006-citycoin-mining-v2', + functionName: 'is-mining-enabled', + functionArgs: [], + network: NETWORK('mainnet'), + }, + true + ); + return typeof result === 'boolean' ? Boolean(result) : null; + } catch (err) { + return null; + } +}