Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion backend/tally/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ def get_required_env(key):
SECRET_KEY = get_required_env('SECRET_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = get_required_env('DEBUG').lower() == 'true'
_debug_raw = get_required_env('DEBUG')
DEBUG = _debug_raw.lower() == 'true'
print(f"[STARTUP] DEBUG={DEBUG} (raw: {repr(_debug_raw)})")

ALLOWED_HOSTS = get_required_env('ALLOWED_HOSTS').split(',')

Expand Down
27 changes: 1 addition & 26 deletions backend/users/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,7 @@ def complete_builder_journey(self, request):
Requirements:
1. Has at least one contribution (any type)
2. Has testnet balance > 0
3. Has deployed at least one contract on GenLayer


Also creates Builder profile if it doesn't exist.
"""
from contributions.models import Contribution, ContributionType
Expand Down Expand Up @@ -519,30 +518,6 @@ def complete_builder_journey(self, request):
# If we can't check balance, we'll allow proceeding (fail open)
pass

# Check requirement 3: Has deployed at least one contract
try:
genlayer_service = GenLayerDeploymentService()

# Convert address to checksum format for GenLayer API
checksum_address = Web3.to_checksum_address(user.address)

deployment_result = genlayer_service.get_user_deployments(checksum_address)

if not deployment_result.get('has_deployments', False):
return Response(
{'error': 'You need to deploy at least one contract to complete the builder journey. Use GenLayer Studio to deploy your first contract.'},
status=status.HTTP_400_BAD_REQUEST
)

logger.debug(f"Deployment check passed: {deployment_result.get('deployment_count', 0)} deployments")

except Exception as e:
logger.error(f"Failed to check deployments: {str(e)}")
return Response(
{'error': 'Failed to verify contract deployments. Please try again later.'},
status=status.HTTP_500_INTERNAL_SERVER_ERROR
)

# All requirements met, create the BUILDER contribution and Builder profile atomically
try:
with transaction.atomic():
Expand Down
51 changes: 29 additions & 22 deletions frontend/src/components/BuilderProgress.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
isRefreshingBalance = false,
onCheckRequirements = null,
isCheckingRequirements = false,
onCheckDeployments = null,
isCheckingDeployments = false,
onOpenStudio = null,
onGitHubLinked = null,
onCheckRepoStar = null,
isCheckingRepoStar = false
isCheckingRepoStar = false,
onCompleteJourney = null,
isCompletingJourney = false
} = $props();

// Network states
Expand Down Expand Up @@ -181,6 +181,11 @@

// Check if wallet has testnet balance
let hasTestnetBalance = $derived(testnetBalance && testnetBalance > 0);

// Core requirements that gate journey completion
let allCoreRequirementsMet = $derived(
hasBuilderWelcome && !!githubUsername && hasStarredRepo && hasTestnetBalance && hasDeployedContract
);
</script>

<div class="bg-white rounded-lg p-5 border border-orange-200">
Expand Down Expand Up @@ -584,25 +589,6 @@
</div>
{#if showActions}
<div class="flex items-center gap-2">
{#if !hasDeployedContract && onCheckDeployments}
<button
onclick={onCheckDeployments}
disabled={isCheckingDeployments || !$authState.isAuthenticated}
class="px-2 py-1 text-xs font-medium text-gray-600 hover:text-gray-900 disabled:opacity-50 disabled:cursor-not-allowed"
title="Check for deployed contracts"
>
{#if isCheckingDeployments}
<svg class="animate-spin h-3 w-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
{:else}
<svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z" clip-rule="evenodd"/>
</svg>
{/if}
</button>
{/if}
{#if onOpenStudio}
<button
onclick={onOpenStudio}
Expand Down Expand Up @@ -638,6 +624,27 @@
<div class="mt-4 text-xs text-gray-500">
<span class="font-medium">{completedCount} of 8</span> requirements completed
</div>

<!-- Complete Builder Journey button -->
{#if onCompleteJourney}
<div class="mt-4">
<button
onclick={onCompleteJourney}
disabled={!allCoreRequirementsMet || isCompletingJourney}
class="w-full inline-flex items-center justify-center px-6 py-2.5 rounded-lg font-medium text-sm transition-colors shadow-sm {allCoreRequirementsMet && !isCompletingJourney ? 'bg-orange-600 text-white hover:bg-orange-700' : 'bg-gray-200 text-gray-400 cursor-not-allowed'}"
>
{#if isCompletingJourney}
<svg class="animate-spin -ml-1 mr-2 h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
Completing your Builder Journey...
{:else}
Complete Builder Journey
{/if}
</button>
</div>
{/if}
{/if}
</div>
</div>
2 changes: 0 additions & 2 deletions frontend/src/lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ export const usersAPI = {
getCurrentUser: () => api.get('/users/me/'),
updateUserProfile: (data) => api.patch('/users/me/', data),
getAccountBalance: () => api.get('/users/balance/'),
checkDeployments: () => api.get('/users/check_deployments/'),
getDeploymentStatus: () => api.get('/users/deployment_status/'),
getActiveValidators: () => api.get('/users/validators/'),
getReferrals: () => api.get('/users/referrals/'),
getReferralPoints: () => api.get('/users/referral_points/'),
Expand Down
Loading