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
442 changes: 442 additions & 0 deletions mobile/scripts/check-thaw-schedule.js

Large diffs are not rendered by default.

46 changes: 40 additions & 6 deletions mobile/src/features/Airdrop/common/useAirdropEligibility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,20 @@ export const useAirdropEligibility = () => {
: 'Manual address'
}

// Recalculate numberOfClaimedAllocations from confirmed/confirming thaws
// (API sometimes returns incorrect value, so we calculate it ourselves)
const numberOfClaimedAllocations =
cachedAllocation.schedule.thaws.filter(
(thaw) =>
thaw.status === 'confirmed' || thaw.status === 'confirming',
).length

allocations.push({
...cachedAllocation,
schedule: {
...cachedAllocation.schedule,
numberOfClaimedAllocations,
},
isExternal,
displayName,
nextThawDate,
Expand Down Expand Up @@ -219,9 +231,21 @@ export const useAirdropEligibility = () => {
continue
}

// Recalculate numberOfClaimedAllocations from confirmed/confirming thaws
// (API sometimes returns incorrect value, so we calculate it ourselves)
const numberOfClaimedAllocations =
cachedAllocation.schedule.thaws.filter(
(thaw) =>
thaw.status === 'confirmed' || thaw.status === 'confirming',
).length

// We have cached data - include it
allocations.push({
...cachedAllocation,
schedule: {
...cachedAllocation.schedule,
numberOfClaimedAllocations,
},
isExternal: true,
displayName,
nextThawDate,
Expand Down Expand Up @@ -263,11 +287,10 @@ export const useAirdropEligibility = () => {
.filter((thaw) => thaw.status === 'redeemable')
.reduce((sum, thaw) => sum + thaw.amount, 0)

// Calculate total allocation (sum of all thaws)
const totalAllocation = schedule.thaws.reduce(
(sum, thaw) => sum + thaw.amount,
0,
)
// Calculate total allocation (sum of all thaws excluding failed ones)
const totalAllocation = schedule.thaws
.filter((thaw) => thaw.status !== 'failed')
.reduce((sum, thaw) => sum + thaw.amount, 0)

// Calculate redeemed so far (sum of confirmed thaws)
const redeemedSoFar = schedule.thaws
Expand All @@ -277,6 +300,7 @@ export const useAirdropEligibility = () => {
)
.reduce((sum, thaw) => sum + thaw.amount, 0)

// Total left to redeem excludes redeemed thaws (failed already excluded from totalAllocation)
const totalLeftToRedeem = totalAllocation - redeemedSoFar

// Find the next upcoming thaw that hasn't started yet
Expand All @@ -297,6 +321,13 @@ export const useAirdropEligibility = () => {
? (upcomingThaws[0]?.thawing_period_start ?? null)
: null

// Calculate numberOfClaimedAllocations from confirmed/confirming thaws
// (API sometimes returns incorrect value, so we calculate it ourselves)
const numberOfClaimedAllocations = schedule.thaws.filter(
(thaw) =>
thaw.status === 'confirmed' || thaw.status === 'confirming',
).length

// Get display name for external address
const isExternal = externalAddresses.has(address)
let displayName: string | undefined
Expand All @@ -312,7 +343,10 @@ export const useAirdropEligibility = () => {

allocations.push({
address,
schedule,
schedule: {
...schedule,
numberOfClaimedAllocations,
},
redeemableAmount,
totalAllocation,
redeemedSoFar,
Expand Down
18 changes: 12 additions & 6 deletions mobile/src/features/Airdrop/common/useHasRedeemableThaws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,23 @@ export const useHasRedeemableThaws = () => {

// Also check if any thaw has started but isn't confirmed yet
// (in case backend hasn't updated status yet)
// Exclude failed and skipped thaws - they cannot be redeemed
return allocation.schedule.thaws.some((thaw) => {
const thawStatus = thaw.status
// Skip failed and skipped thaws - they cannot be redeemed
if (thawStatus === 'failed' || thawStatus === 'skipped') {
return false
}

const thawDate = new Date(thaw.thawing_period_start.replace(/\s/g, ''))
const hasStarted = thawDate <= now
const isRedeemable = thaw.status === 'redeemable'
const isRedeemable = thawStatus === 'redeemable'
const isPendingRedeemable =
thaw.status === 'upcoming' || thaw.status === 'queued'
thawStatus === 'upcoming' || thawStatus === 'queued'
const isNotRedeemed =
thaw.status !== 'confirmed' &&
thaw.status !== 'confirming' &&
thaw.status !== 'submitted' &&
thaw.status !== 'failed'
thawStatus !== 'confirmed' &&
thawStatus !== 'confirming' &&
thawStatus !== 'submitted'

return (
isRedeemable || (hasStarted && isPendingRedeemable && isNotRedeemed)
Expand Down
14 changes: 9 additions & 5 deletions mobile/src/features/Airdrop/ui/AirdropDetailsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,22 @@ const getCurrentThawIndex = (thaws: ReadonlyArray<Thaw>): number | null => {

const now = new Date()

// First, try to find an active/redeemable thaw (started but not confirmed)
// First, try to find an active/redeemable thaw (started but not confirmed and not failed)
for (let i = 0; i < thaws.length; i++) {
const thaw = thaws[i]
if (!thaw) continue
const thawDate = new Date(thaw.thawing_period_start.replace(/\s/g, ''))
// Active thaw: started and not confirmed
if (thawDate <= now && thaw.status !== 'confirmed') {
// Active thaw: started and not confirmed and not failed
if (
thawDate <= now &&
thaw.status !== 'confirmed' &&
thaw.status !== 'failed'
) {
return i
}
}

// If no active thaw, find the first upcoming thaw (next one to start)
// If no active thaw, find the first upcoming thaw (next one to start, not failed)
for (let i = 0; i < thaws.length; i++) {
const thaw = thaws[i]
if (!thaw) continue
Expand Down Expand Up @@ -293,7 +297,7 @@ export const AirdropDetailsScreen = () => {
)
resultNavigation.showResultScreen({
type: 'error',
context: 'default',
context: 'airdrop',
title: strings.airdrop.insufficientFunds,
message: strings.airdrop.redeemError,
primaryAction: {
Expand Down
Loading
Loading