celoclicker-game-sdk 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,49 @@
1
+ import { getDefaultConfig } from '@rainbow-me/rainbowkit';
2
+ import { QueryClient } from '@tanstack/react-query';
3
+ import { useEffect, useRef } from 'react';
4
+ import { useAccount, useConnect } from 'wagmi';
5
+ import { celo, celoAlfajores } from 'viem/chains';
6
+ import { APP_NAME, CELO_ALFAJORES_CHAIN_ID, CELO_MAINNET_CHAIN_ID } from './constants';
7
+ import { getInjectedConnector, isMiniPayBrowser } from './minipay';
8
+ function mergeQueryClientConfig(config = {}) {
9
+ return {
10
+ ...config,
11
+ defaultOptions: {
12
+ ...config.defaultOptions,
13
+ queries: {
14
+ refetchOnWindowFocus: false,
15
+ ...config.defaultOptions?.queries,
16
+ },
17
+ },
18
+ };
19
+ }
20
+ export function createCeloClickerQueryClient(config = {}) {
21
+ return new QueryClient(mergeQueryClientConfig(config));
22
+ }
23
+ export function getCeloClickerChains(chainId = CELO_MAINNET_CHAIN_ID) {
24
+ return chainId === CELO_ALFAJORES_CHAIN_ID ? [celoAlfajores] : [celo];
25
+ }
26
+ export function createCeloClickerWagmiConfig(options = {}) {
27
+ return getDefaultConfig({
28
+ appName: options.appName?.trim() || APP_NAME,
29
+ projectId: options.projectId?.trim() || '',
30
+ chains: [...getCeloClickerChains(options.chainId)],
31
+ ssr: options.ssr ?? true,
32
+ });
33
+ }
34
+ export function useMiniPayAutoConnect() {
35
+ const { isConnected } = useAccount();
36
+ const { connect, connectors } = useConnect();
37
+ const attemptedAutoConnect = useRef(false);
38
+ useEffect(() => {
39
+ if (!isMiniPayBrowser() || isConnected || attemptedAutoConnect.current) {
40
+ return;
41
+ }
42
+ const injectedConnector = getInjectedConnector(connectors);
43
+ if (!injectedConnector) {
44
+ return;
45
+ }
46
+ attemptedAutoConnect.current = true;
47
+ connect({ connector: injectedConnector });
48
+ }, [connect, connectors, isConnected]);
49
+ }
@@ -0,0 +1,28 @@
1
+ export type Address = `0x${string}`;
2
+ export type PlayerStatsTuple = readonly [bigint, bigint, bigint, bigint, bigint, bigint];
3
+ export type UpgradeCostsTuple = readonly [bigint, bigint, bigint];
4
+ export type LeaderboardTuple = readonly [readonly `0x${string}`[], readonly bigint[]];
5
+ export interface PlayerStats {
6
+ points: bigint;
7
+ clickPower: bigint;
8
+ autoClickerLevel: bigint;
9
+ multiplierLevel: bigint;
10
+ totalClicks: bigint;
11
+ gamesPlayed: bigint;
12
+ }
13
+ export interface UpgradeCosts {
14
+ clickPowerCost: bigint;
15
+ autoClickerCost: bigint;
16
+ multiplierCost: bigint;
17
+ }
18
+ export interface LeaderboardEntry {
19
+ address: Address;
20
+ points: bigint;
21
+ rank: number;
22
+ }
23
+ export interface CeloClickerSdkConfig {
24
+ contractAddress: Address;
25
+ chainId: number;
26
+ appName: string;
27
+ defaultFeeCurrencyId: 'CELO' | 'USDC';
28
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Ethereum zero address constant used for validation
3
+ */
4
+ export declare const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
5
+ /**
6
+ * Formats a number with K, M, B suffixes for display
7
+ * @param num - The number to format (bigint or number)
8
+ * @returns Formatted string with suffix (e.g., "1.5K", "2.3M", "1B")
9
+ */
10
+ export declare function formatNumber(num: bigint | number): string;
11
+ /**
12
+ * Formats an Ethereum address for display by truncating it
13
+ * @param address - The Ethereum address to format
14
+ * @returns Truncated address string (e.g., "0x1234...5678")
15
+ */
16
+ export declare function formatAddress(address: string): string;
17
+ /**
18
+ * Formats token amounts for display with appropriate decimal places
19
+ * @param value - The token amount as a string
20
+ * @param symbol - Optional token symbol to append
21
+ * @returns Formatted amount string with symbol
22
+ */
23
+ export declare function formatTokenAmount(value?: string, symbol?: string): string;
24
+ /**
25
+ * Validates if a string is a valid Ethereum address format
26
+ * @param address - The address string to validate
27
+ * @returns True if the address is a valid Ethereum address format
28
+ */
29
+ export declare function isValidAddress(address: string): boolean;
30
+ /**
31
+ * Checks if an address is the Ethereum zero address
32
+ * @param address - The address to check
33
+ * @returns True if the address is the zero address
34
+ */
35
+ export declare function isZeroAddress(address: string): boolean;
package/dist/utils.js ADDED
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Ethereum zero address constant used for validation
3
+ */
4
+ export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
5
+ /**
6
+ * Formats a number with K, M, B suffixes for display
7
+ * @param num - The number to format (bigint or number)
8
+ * @returns Formatted string with suffix (e.g., "1.5K", "2.3M", "1B")
9
+ */
10
+ export function formatNumber(num) {
11
+ const n = typeof num === 'bigint' ? Number(num) : num;
12
+ if (!Number.isFinite(n)) {
13
+ return '0';
14
+ }
15
+ if (n >= 1_000_000_000) {
16
+ return (n / 1_000_000_000).toFixed(2) + 'B';
17
+ }
18
+ if (n >= 1_000_000) {
19
+ return (n / 1_000_000).toFixed(2) + 'M';
20
+ }
21
+ if (n >= 1_000) {
22
+ return (n / 1_000).toFixed(2) + 'K';
23
+ }
24
+ return n.toLocaleString();
25
+ }
26
+ /**
27
+ * Formats an Ethereum address for display by truncating it
28
+ * @param address - The Ethereum address to format
29
+ * @returns Truncated address string (e.g., "0x1234...5678")
30
+ */
31
+ export function formatAddress(address) {
32
+ const normalizedAddress = typeof address === 'string' ? address.trim() : '';
33
+ if (!normalizedAddress || normalizedAddress.length < 10)
34
+ return normalizedAddress;
35
+ return `${normalizedAddress.slice(0, 6)}...${normalizedAddress.slice(-4)}`;
36
+ }
37
+ /**
38
+ * Formats token amounts for display with appropriate decimal places
39
+ * @param value - The token amount as a string
40
+ * @param symbol - Optional token symbol to append
41
+ * @returns Formatted amount string with symbol
42
+ */
43
+ export function formatTokenAmount(value, symbol) {
44
+ if (!value) {
45
+ return `0 ${symbol ?? ''}`.trim();
46
+ }
47
+ const numericValue = Number(value);
48
+ if (!Number.isFinite(numericValue)) {
49
+ return `0 ${symbol ?? ''}`.trim();
50
+ }
51
+ const decimals = numericValue >= 100 ? 2 : numericValue >= 1 ? 3 : 4;
52
+ const formattedValue = numericValue.toFixed(decimals).replace(/\.?0+$/, '');
53
+ return `${formattedValue} ${symbol ?? ''}`.trim();
54
+ }
55
+ /**
56
+ * Validates if a string is a valid Ethereum address format
57
+ * @param address - The address string to validate
58
+ * @returns True if the address is a valid Ethereum address format
59
+ */
60
+ export function isValidAddress(address) {
61
+ return /^0x[a-fA-F0-9]{40}$/.test(address);
62
+ }
63
+ /**
64
+ * Checks if an address is the Ethereum zero address
65
+ * @param address - The address to check
66
+ * @returns True if the address is the zero address
67
+ */
68
+ export function isZeroAddress(address) {
69
+ if (!address)
70
+ return false;
71
+ return address.trim().toLowerCase() === ZERO_ADDRESS;
72
+ }
@@ -0,0 +1,5 @@
1
+ export declare function validateContractAddress(address: string): boolean;
2
+ export declare function validateEnvironment(env?: Record<string, string | undefined>): {
3
+ isValid: boolean;
4
+ errors: string[];
5
+ };
@@ -0,0 +1,31 @@
1
+ import { CONTRACT_ADDRESS_ENV_KEY } from './constants';
2
+ import { isValidAddress, isZeroAddress } from './utils';
3
+ export function validateContractAddress(address) {
4
+ const normalizedAddress = typeof address === 'string' ? address.trim() : '';
5
+ if (!normalizedAddress)
6
+ return false;
7
+ if (isZeroAddress(normalizedAddress))
8
+ return false;
9
+ return isValidAddress(normalizedAddress);
10
+ }
11
+ export function validateEnvironment(env = process.env) {
12
+ const errors = [];
13
+ const contractAddress = env.NEXT_PUBLIC_CELOCLICKER_CONTRACT?.trim();
14
+ if (!contractAddress) {
15
+ errors.push(`${CONTRACT_ADDRESS_ENV_KEY} is not set`);
16
+ }
17
+ else if (!validateContractAddress(contractAddress)) {
18
+ errors.push(`${CONTRACT_ADDRESS_ENV_KEY} is not a valid address`);
19
+ }
20
+ const walletConnectId = env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID?.trim();
21
+ if (!walletConnectId) {
22
+ errors.push('NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID is not set');
23
+ }
24
+ else if (walletConnectId === 'your_project_id' || walletConnectId === 'your_project_id_here') {
25
+ errors.push('NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID is still set to a placeholder value');
26
+ }
27
+ return {
28
+ isValid: errors.length === 0,
29
+ errors,
30
+ };
31
+ }
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "celoclicker-game-sdk",
3
+ "version": "0.1.1",
4
+ "description": "Standalone SDK for CeloClicker contract state, gameplay math, fee currency handling, and MiniPay wallet helpers.",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "scripts": {
21
+ "clean": "rm -rf dist",
22
+ "build": "npm run clean && tsc -p tsconfig.json",
23
+ "typecheck": "tsc --noEmit",
24
+ "test": "vitest run",
25
+ "prepublishOnly": "npm run typecheck && npm run test && npm run build"
26
+ },
27
+ "keywords": [
28
+ "celo",
29
+ "celoclicker",
30
+ "gamefi",
31
+ "minipay",
32
+ "wagmi",
33
+ "viem",
34
+ "sdk"
35
+ ],
36
+ "author": "AK-Bit-Lab",
37
+ "license": "MIT",
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "engines": {
42
+ "node": ">=18"
43
+ },
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/AK-Bit-Lab/celoclicker-sdk.git"
47
+ },
48
+ "bugs": {
49
+ "url": "https://github.com/AK-Bit-Lab/celoclicker-sdk/issues"
50
+ },
51
+ "homepage": "https://github.com/AK-Bit-Lab/celoclicker-sdk#readme",
52
+ "dependencies": {
53
+ "@rainbow-me/rainbowkit": "^2.0.0",
54
+ "@tanstack/react-query": "^5.28.0"
55
+ },
56
+ "peerDependencies": {
57
+ "react": "^18.3.0",
58
+ "react-dom": "^18.3.0",
59
+ "viem": "^2.7.0",
60
+ "wagmi": "^2.5.0"
61
+ },
62
+ "devDependencies": {
63
+ "@types/node": "^24.10.1",
64
+ "@types/react": "^18.3.24",
65
+ "react": "^18.3.0",
66
+ "react-dom": "^18.3.0",
67
+ "typescript": "^5.9.2",
68
+ "viem": "^2.7.0",
69
+ "vitest": "^4.1.4",
70
+ "wagmi": "^2.5.0"
71
+ }
72
+ }