Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
132 commits
Select commit Hold shift + click to select a range
7eab428
Implemented the Api key Authentification Middleware
KAMALDEEN333 Mar 26, 2026
82b2040
fixed build error
KAMALDEEN333 Mar 26, 2026
2201d4a
Implemented the Size limit
KAMALDEEN333 Mar 26, 2026
584da6b
fixed all error
KAMALDEEN333 Mar 26, 2026
e2a2cd2
Merge pull request #347 from KAMALDEEN333/Auth-Middleware
A6dulmalik Mar 26, 2026
4f87c59
Merge pull request #348 from KAMALDEEN333/Size-Limit
A6dulmalik Mar 26, 2026
1e1d28b
feat: Implement Streak Calendar Component with Monthly Grid View
DIFoundation Mar 26, 2026
209a650
edited file to make StreakCalendar work
DIFoundation Mar 26, 2026
2158a42
Merge branch 'main' of https://github.com/DIFoundation/mindBlock_app
DIFoundation Mar 26, 2026
6d8050f
Revert "Size limit"
A6dulmalik Mar 26, 2026
8527348
Merge pull request #358 from MindBlockLabs/revert-348-Size-Limit
A6dulmalik Mar 26, 2026
db3f0e8
Revert "Implemented the Api key Authentification Middleware"
A6dulmalik Mar 26, 2026
6d9ed74
Merge pull request #359 from MindBlockLabs/revert-347-Auth-Middleware
A6dulmalik Mar 26, 2026
3ced7ec
Merge pull request #357 from DIFoundation/main
A6dulmalik Mar 26, 2026
6d3cb34
implemented the patches
nafiuishaaq Mar 26, 2026
86fbfb1
implemented the patches
nafiuishaaq Mar 26, 2026
20043c3
implemented the patches
nafiuishaaq Mar 26, 2026
cb453f5
implemented the patches
nafiuishaaq Mar 26, 2026
c718b77
implemented the patches
nafiuishaaq Mar 26, 2026
3d30765
implemented the patches
nafiuishaaq Mar 26, 2026
e43b356
Merge pull request #360 from nafiuishaaq/feat/versionioning
A6dulmalik Mar 26, 2026
40ca5ab
Revert "Feat/versionioning"
A6dulmalik Mar 26, 2026
c821a50
Merge pull request #361 from nafiuishaaq/feat/role
A6dulmalik Mar 26, 2026
2dea0de
Merge pull request #362 from nafiuishaaq/feat/time
A6dulmalik Mar 26, 2026
9cb3f89
Merge pull request #363 from nafiuishaaq/feat/perf
A6dulmalik Mar 26, 2026
3095090
Revert "Feat/perf"
A6dulmalik Mar 26, 2026
a14a208
Merge pull request #365 from MindBlockLabs/revert-363-feat/perf
A6dulmalik Mar 26, 2026
bad8244
Revert "Feat/time"
A6dulmalik Mar 26, 2026
f4f4e03
Merge pull request #366 from MindBlockLabs/revert-362-feat/time
A6dulmalik Mar 26, 2026
e0f4916
Revert "Feat/role"
A6dulmalik Mar 26, 2026
60bc1e0
Merge pull request #367 from MindBlockLabs/revert-361-feat/role
A6dulmalik Mar 26, 2026
104b260
Merge pull request #364 from MindBlockLabs/revert-360-feat/versionioning
A6dulmalik Mar 26, 2026
e8bf905
Implemented User Activity Tracking
KAMALDEEN333 Mar 26, 2026
aa4bef2
fixed errors
KAMALDEEN333 Mar 26, 2026
56813e1
feat: hide sidenav and mobile menu toggle on streak and auth pages
simplicityf Mar 26, 2026
e3eb5e0
Conditional-Middleware-Execution
shamoo53 Mar 26, 2026
0279cb2
Merge branch 'main' of https://github.com/shamoo53/mindBlock_Backend …
shamoo53 Mar 26, 2026
08e2117
fix
shamoo53 Mar 26, 2026
475bff5
Merge pull request #370 from shamoo53/Conditional-Middleware-Execution
A6dulmalik Mar 26, 2026
fd9ec72
Revert "Conditional middleware execution"
A6dulmalik Mar 26, 2026
067c4e0
Merge pull request #376 from MindBlockLabs/revert-370-Conditional-Mid…
A6dulmalik Mar 26, 2026
8a2a6c6
Merge pull request #369 from simplicityf/feat/streak
A6dulmalik Mar 26, 2026
563f966
Merge pull request #368 from KAMALDEEN333/User-Activity-Tracking
A6dulmalik Mar 26, 2026
8603690
Revert "Implemented User Activity Tracking"
A6dulmalik Mar 26, 2026
bcfc043
Merge pull request #382 from MindBlockLabs/revert-368-User-Activity-T…
A6dulmalik Mar 26, 2026
d8bc8e3
refactor: Explicitly name the Progress entity's table as user_progres…
Mar 27, 2026
2525bb8
feat(middleware): implement conditional execution, timeout, circuit b…
BigBen-7 Mar 27, 2026
f2ad950
Merge pull request #386 from BigBen-7/feat/middleware-suite
phertyameen Mar 27, 2026
f2dc4e6
feat: Implement GetPlayerProvider to fetch on-chain player data, upda…
Mar 27, 2026
7e7c7ba
test: Add snapshots for leaderboard sorting, player registration, and…
Mar 27, 2026
cdc8f82
Merge branch 'main' of https://github.com/PeterOche/mindBlock_app int…
Mar 27, 2026
2e74acc
Implement advanced Timeout & Circuit Breaker For Middleware
ohamamarachi474-del Mar 27, 2026
e6a3299
Implement Request Correlation ID Middleware for Distributed Tracing
gabito1451 Mar 27, 2026
dca309a
fix
gabito1451 Mar 27, 2026
2329d56
fix
gabito1451 Mar 27, 2026
9ef215b
fix
gabito1451 Mar 27, 2026
dfa294e
Content Security Policy (CSP) Middleware
sadeeq6400 Mar 27, 2026
a6e1dac
Benchmarking Infrastructure Setup For Middleware
sadeeq6400 Mar 27, 2026
b4d6a1c
Merge pull request #389 from ohamamarachi474-del/375
A6dulmalik Mar 27, 2026
6e65e5e
Merge pull request #390 from gabito1451/328
A6dulmalik Mar 27, 2026
c0229be
Merge pull request #391 from sadeeq6400/cat
A6dulmalik Mar 27, 2026
8ea1947
Merge pull request #392 from sadeeq6400/benchMark
A6dulmalik Mar 27, 2026
dc305e6
fix(contract): prevent XP farming, auto-reset streak, expand tests (#…
Kaylahray Mar 27, 2026
6e1bb0c
Merge pull request #388 from PeterOche/feat/resolve-duplicate
phertyameen Mar 27, 2026
9b06c31
Merge pull request #393 from Kaylahray/feat/project-requirements
phertyameen Mar 27, 2026
1a4563f
rater added
sadeeq6400 Mar 27, 2026
c902938
rater controller added
sadeeq6400 Mar 27, 2026
d3f0e2f
Distributed Tracing Middleware
ayshadogo Mar 27, 2026
7412839
Middleware Execution Order Validator
ayshadogo Mar 27, 2026
572183d
removed PR title
ayshadogo Mar 27, 2026
8ad6899
removed PR title
ayshadogo Mar 27, 2026
d948447
removed PR title
sadeeq6400 Mar 27, 2026
1b9ab7a
removed PR title
sadeeq6400 Mar 27, 2026
11cb025
feat(database): implement transaction middleware with ACID guarantees…
mijinummi Mar 27, 2026
c712c0d
feat(middleware): implement request deduplication with idempotency su…
mijinummi Mar 27, 2026
748a81d
Merge pull request #404 from mijinummi/feat/db-transaction-middleware…
phertyameen Mar 27, 2026
d49ce9e
Merge pull request #405 from mijinummi/feat/middleware-idempotency-de…
phertyameen Mar 27, 2026
d723184
feat(middleware): implement response compression middleware (#325)
mijinummi Mar 27, 2026
be4d09b
feat(security): implement security headers middleware (#327)
mijinummi Mar 27, 2026
c9c5f3a
Merge pull request #406 from mijinummi/feat/middleware-response-compr…
phertyameen Mar 27, 2026
cb2b4ca
Merge pull request #407 from mijinummi/feat/middleware-security-heade…
phertyameen Mar 27, 2026
70976e0
restored PR template
ayshadogo Mar 27, 2026
6f72be3
restored PR template
ayshadogo Mar 27, 2026
b62d74c
restored PR template
sadeeq6400 Mar 27, 2026
898d265
restored PR template
sadeeq6400 Mar 27, 2026
bed1692
Merge pull request #403 from ayshadogo/explorer
phertyameen Mar 27, 2026
7fbe72e
Merge pull request #402 from ayshadogo/builder
phertyameen Mar 27, 2026
6d0df74
Merge pull request #399 from sadeeq6400/rater
phertyameen Mar 27, 2026
dffecbb
Merge pull request #400 from sadeeq6400/raterCont
phertyameen Mar 27, 2026
271f9e6
feat: add ShareStreakCard modal component and wire to streak page
wheval Mar 27, 2026
09977ee
feat(middleware): implement blockchain module for issues #307, #308, …
Tinna23 Mar 28, 2026
98c4a08
Implemented the Middleware Chain Performance
KAMALDEEN333 Mar 28, 2026
b369b0f
moved the README.md file!
Lynndabel Mar 28, 2026
bd097c7
Merge pull request #411 from Lynndabel/readme
phertyameen Mar 28, 2026
f03398f
feat: Add reusable ShareOptionsSheet component and fix streak navigation
Henrichy Mar 28, 2026
fc4c759
Merge pull request #1 from MindBlockLabs/main
Henrichy Mar 28, 2026
125a9cc
Merge pull request #408 from wheval/feat/streak-card
A6dulmalik Mar 28, 2026
36f41c7
Merge pull request #409 from Tinna23/Tinna23/issues-307-308-309-310
A6dulmalik Mar 28, 2026
20d180b
Merge branch 'main' into Middleware-Chain-Performace
A6dulmalik Mar 28, 2026
9375584
Merge pull request #410 from KAMALDEEN333/Middleware-Chain-Performace
A6dulmalik Mar 28, 2026
cc814e6
Revert "Implemented the Middleware Chain Performance"
A6dulmalik Mar 28, 2026
86222d9
Merge pull request #414 from MindBlockLabs/revert-410-Middleware-Chai…
A6dulmalik Mar 28, 2026
dc0f55c
Merge branch 'main' into main
Henrichy Mar 28, 2026
62ba4f6
Merge pull request #412 from Henrichy/main
A6dulmalik Mar 28, 2026
454ac5f
Implement on-chain puzzle submission and retry mechanism
Mkalbani Mar 28, 2026
be0b304
Merge branch 'main' into feat/submit-puzzle-onchain-provider
Mkalbani Mar 28, 2026
4f83f97
feat: #369 add per-middleware performance benchmarks
OthmanImam Mar 28, 2026
1de6568
updated
OthmanImam Mar 28, 2026
1e04e8f
feat: External Plugin Loader for npm packages
OthmanImam Mar 28, 2026
f6daf13
feat: First-Party Request Logger Plugin - HTTP request logging with c…
OthmanImam Mar 28, 2026
1411ca2
updated
OthmanImam Mar 28, 2026
7fbfc8e
feat: Lifecycle Error Handling and Timeouts - Robust timeout and retr…
OthmanImam Mar 28, 2026
db74981
updated
OthmanImam Mar 28, 2026
8b92d9a
Merge pull request #428 from Mkalbani/feat/submit-puzzle-onchain-prov…
A6dulmalik Mar 28, 2026
a41033b
Revert "Implement on-chain puzzle submission and retry mechanism"
A6dulmalik Mar 28, 2026
621d96c
Merge pull request #436 from MindBlockLabs/revert-428-feat/submit-puz…
A6dulmalik Mar 28, 2026
064a251
Merge pull request #434 from OthmanImam/feat/Pre-Midleware
A6dulmalik Mar 28, 2026
5179e75
Revert "Middleware Performance Benchmarks & External Plugin System"
A6dulmalik Mar 28, 2026
b6a9d6b
Merge pull request #437 from MindBlockLabs/revert-434-feat/Pre-Midleware
A6dulmalik Mar 28, 2026
a84ad26
Revert "Revert "Middleware Performance Benchmarks & External Plugin S…
A6dulmalik Mar 28, 2026
e3ef8f5
Merge pull request #438 from MindBlockLabs/revert-437-revert-434-feat…
A6dulmalik Mar 28, 2026
e4a1662
Merge pull request #435 from OthmanImam/feat/Request
A6dulmalik Mar 28, 2026
1e86128
Revert "Complete Plugin System with Error Handling, Timeouts, and Fir…
A6dulmalik Mar 28, 2026
044f75c
Merge pull request #439 from MindBlockLabs/revert-435-feat/Request
A6dulmalik Mar 28, 2026
eaf4483
Revert "Revert "Revert "Middleware Performance Benchmarks & External …
A6dulmalik Mar 28, 2026
c1b7a8b
Merge pull request #440 from MindBlockLabs/revert-438-revert-437-reve…
A6dulmalik Mar 28, 2026
e142eb6
feat(plugin-system): implement plugin lifecycle management with order…
Xhristin3 Mar 29, 2026
3fdcb88
feat(metrics): add Prometheus metrics plugin with observability
Xhristin3 Mar 29, 2026
28add34
feat(testing): establish comprehensive testing infrastructure
Xhristin3 Mar 29, 2026
272b085
feat(pdk): create plugin development kit with starter template
Xhristin3 Mar 29, 2026
c05cadf
Merge pull request #451 from Xhristin3/feature/plugin-system-lifecycl…
A6dulmalik Mar 29, 2026
5c1c38d
feat(middleware): add redis-backed api rate limiting
David-patrick-chuks Mar 29, 2026
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
Binary file modified .DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ jobs:
workspaces: "contract"
- name: Build contract
run: cargo build --target wasm32-unknown-unknown --release
working-directory: contract
working-directory: contract
13 changes: 12 additions & 1 deletion backend/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import jwtConfig from './auth/authConfig/jwt.config';
import { UsersService } from './users/providers/users.service';
import { GeolocationMiddleware } from './common/middleware/geolocation.middleware';
import { HealthModule } from './health/health.module';
import { RateLimitMiddleware } from './common/middleware/rate-limit.middleware';

// const ENV = process.env.NODE_ENV;
// console.log('NODE_ENV:', process.env.NODE_ENV);
Expand Down Expand Up @@ -104,7 +105,7 @@ import { HealthModule } from './health/health.module';
HealthModule,
],
controllers: [AppController],
providers: [AppService],
providers: [AppService, RateLimitMiddleware],
})
export class AppModule implements NestModule {
/**
Expand All @@ -124,5 +125,15 @@ export class AppModule implements NestModule {
{ path: 'health', method: RequestMethod.GET },
)
.forRoutes('*');

consumer
.apply(RateLimitMiddleware)
.exclude(
{ path: 'health/(.*)', method: RequestMethod.ALL },
{ path: 'health', method: RequestMethod.ALL },
{ path: 'api', method: RequestMethod.ALL },
{ path: 'docs', method: RequestMethod.ALL },
)
.forRoutes('*');
}
}
8 changes: 6 additions & 2 deletions backend/src/auth/middleware/jwt-auth.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,12 @@ export class JwtAuthMiddleware implements NestMiddleware {

// 1. Allow certain routes to bypass authentication (public endpoints)
const isPublic = publicRoutes.some((route) => req.path.startsWith(route));
if (isPublic) {
if (logging) this.logger.debug(`Public route accessed: ${req.path}`);

// Special case: Allow POST /users for user registration
const isUserRegistration = req.method === 'POST' && req.path === '/users';

if (isPublic || isUserRegistration) {
if (logging) this.logger.debug(`Public route accessed: ${req.method} ${req.path}`);
return next();
}

Expand Down
3 changes: 2 additions & 1 deletion backend/src/blockchain/blockchain.module.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Module } from '@nestjs/common';
import { BlockchainController } from './controller/blockchain.controller';
import { BlockchainService } from './provider/blockchain.service';
import { GetPlayerProvider } from './providers/get-player.provider';

@Module({
controllers: [BlockchainController],
providers: [BlockchainService],
providers: [BlockchainService, GetPlayerProvider],
exports: [BlockchainService],
})
export class BlockchainModule {}
12 changes: 12 additions & 0 deletions backend/src/blockchain/provider/blockchain.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import { Injectable } from '@nestjs/common';
import { GetPlayerProvider } from '../providers/get-player.provider';

@Injectable()
export class BlockchainService {
constructor(private readonly getPlayerProvider: GetPlayerProvider) {}

getHello(): string {
return 'Hello from Blockchain Service';
}

/**
* Fetches a player's on-chain profile from the Soroban contract.
* @param stellarWallet The player's Stellar wallet address.
* @returns The player object if found, null otherwise.
*/
async getPlayerOnChain(stellarWallet: string): Promise<object | null> {
return this.getPlayerProvider.getPlayerOnChain(stellarWallet);
}
}
151 changes: 151 additions & 0 deletions backend/src/blockchain/providers/get-player.provider.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigService } from '@nestjs/config';
import { GetPlayerProvider } from './get-player.provider';
import * as StellarSdk from 'stellar-sdk';

// Mock StellarSdk
jest.mock('stellar-sdk', () => {
return {
rpc: {
Server: jest.fn().mockImplementation(() => ({
simulateTransaction: jest.fn(),
})),
Api: {
isSimulationSuccess: jest.fn() as unknown as jest.Mock,
},
},
Contract: jest.fn().mockImplementation(() => ({
call: jest.fn().mockReturnValue({}),
})),
Address: {
fromString: jest.fn().mockReturnValue({}),
},
Account: jest.fn(),
TransactionBuilder: jest.fn().mockImplementation(() => ({
addOperation: jest.fn().mockReturnThis(),
setTimeout: jest.fn().mockReturnThis(),
build: jest.fn().mockReturnValue({}),
})),
Networks: {
TESTNET: 'testnet',
},
TimeoutInfinite: 0,
nativeToScVal: jest.fn(),
scValToNative: jest.fn(),
xdr: {
ScValType: {
scvVoid: jest.fn().mockImplementation(() => ({
value: 0,
switch: () => 0,
})),
},
},
};
});

describe('GetPlayerProvider', () => {
let provider: GetPlayerProvider;
let configService: ConfigService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
GetPlayerProvider,
{
provide: ConfigService,
useValue: {
get: jest.fn((key: string) => {
if (key === 'SOROBAN_CONTRACT_ID') return 'CA1234567890';
if (key === 'SOROBAN_RPC_URL') return 'https://soroban-testnet.stellar.org';
return null;
}),
},
},
],
}).compile();

provider = module.get<GetPlayerProvider>(GetPlayerProvider);
configService = module.get<ConfigService>(ConfigService);
jest.clearAllMocks();
});

it('should be defined', () => {
expect(provider).toBeDefined();
});

describe('getPlayerOnChain', () => {
const mockWallet = 'GABC...';

it('should return player data when simulation is successful and player exists', async () => {
const mockPlayerData = {
address: mockWallet,
username: 'testuser',
xp: 100,
};

(StellarSdk.rpc.Api.isSimulationSuccess as unknown as jest.Mock).mockReturnValue(true);
(StellarSdk.scValToNative as jest.Mock).mockReturnValue(mockPlayerData);

const server = (provider as any).server;
server.simulateTransaction.mockResolvedValue({
result: {
retval: {
switch: jest.fn().mockReturnValue(1), // Not void
},
},
});

const result = await provider.getPlayerOnChain(mockWallet);

expect(result).toEqual(mockPlayerData);
expect(server.simulateTransaction).toHaveBeenCalled();
});

it('should return null when player is not found (void response)', async () => {
(StellarSdk.rpc.Api.isSimulationSuccess as unknown as jest.Mock).mockReturnValue(true);
(StellarSdk.xdr.ScValType.scvVoid as jest.Mock).mockReturnValue({ value: 0 });

const server = (provider as any).server;
server.simulateTransaction.mockResolvedValue({
result: {
retval: {
switch: jest.fn().mockReturnValue({ value: 0 }), // Void
},
},
});

const result = await provider.getPlayerOnChain(mockWallet);

expect(result).toBeNull();
});

it('should return null when simulation fails', async () => {
(StellarSdk.rpc.Api.isSimulationSuccess as unknown as jest.Mock).mockReturnValue(false);

const result = await provider.getPlayerOnChain(mockWallet);

expect(result).toBeNull();
});

it('should return null and log error when RPC call throws', async () => {
const server = (provider as any).server;
server.simulateTransaction.mockRejectedValue(new Error('Network error'));

const result = await provider.getPlayerOnChain(mockWallet);

expect(result).toBeNull();
});

it('should return null if contractId is missing', async () => {
jest.spyOn(configService, 'get').mockReturnValue(null);

// Need to re-instantiate or bypass constructor for this test if contractId is set once
// but the current implementation sets it in constructor.
// Let's just mock the instance property for the test.
(provider as any).contractId = null;

const result = await provider.getPlayerOnChain(mockWallet);
expect(result).toBeNull();
});
});
});
88 changes: 88 additions & 0 deletions backend/src/blockchain/providers/get-player.provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as StellarSdk from 'stellar-sdk';

@Injectable()
export class GetPlayerProvider {
private readonly logger = new Logger(GetPlayerProvider.name);
private readonly server: StellarSdk.rpc.Server;
private readonly contractId: string | undefined;

constructor(private readonly configService: ConfigService) {
const rpcUrl =
this.configService.get<string>('SOROBAN_RPC_URL') ||
'https://soroban-testnet.stellar.org';
this.server = new StellarSdk.rpc.Server(rpcUrl);
this.contractId = this.configService.get<string>('SOROBAN_CONTRACT_ID');
}

/**
* Fetches a player's on-chain profile from the Soroban contract.
* @param stellarWallet The player's Stellar wallet address.
* @returns The player object if found, null otherwise.
*/
async getPlayerOnChain(stellarWallet: string): Promise<object | null> {
try {
if (!this.contractId) {
this.logger.error('SOROBAN_CONTRACT_ID is not defined in environment variables');
return null;
}

// 1. Prepare contract and address
const contract = new StellarSdk.Contract(this.contractId);
const address = StellarSdk.Address.fromString(stellarWallet);

// 2. Build simulation transaction
// We use a dummy source account as this is a read-only simulation
const sourceAccount = new StellarSdk.Account(
'GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF',
'0',
);

const transaction = new StellarSdk.TransactionBuilder(sourceAccount, {
fee: '100',
networkPassphrase: StellarSdk.Networks.TESTNET,
})
.addOperation(
contract.call(
'get_player',
StellarSdk.nativeToScVal(address, { type: 'address' }),
),
)
.setTimeout(StellarSdk.TimeoutInfinite)
.build();

// 3. Simulate the transaction
const simulation = await this.server.simulateTransaction(transaction);

// 4. Handle results
if (StellarSdk.rpc.Api.isSimulationSuccess(simulation)) {
const resultVal = simulation.result?.retval;

// If result is null/void, it means the player wasn't found (Option::None)
if (
!resultVal ||
resultVal.switch().value === StellarSdk.xdr.ScValType.scvVoid().value
) {
this.logger.debug(`Player ${stellarWallet} not found on-chain.`);
return null;
}

// Convert XDR value to native JS object
const player = StellarSdk.scValToNative(resultVal);
this.logger.log(`Successfully fetched on-chain stats for ${stellarWallet}`);

return player;
}

this.logger.warn(`Simulation failed for get_player(${stellarWallet})`);
return null;
} catch (error) {
this.logger.error(
`Error fetching player on-chain (${stellarWallet}): ${error.message}`,
error.stack,
);
return null;
}
}
}
Loading