Skip to content

altTimeChecks: deny transfers by hour, weekday, month, day of month, or ISO week, in UTC or with a timezone offset.

altTimeChecks denies a transfer when the block time falls inside an offline window. transferTimes says when a transfer is allowed; altTimeChecks says when it is denied on a calendar basis (nights, weekends, month ends, blackout weeks).

Shape

A complete approvalCriteria with the altTimeChecks object open. Folded lines are defaults.

json
{
  "approvalAmounts": {
    "resetTimeIntervals": { "startTime": "0", "intervalLength": "0" }
  },
  "maxNumTransfers": {
    "resetTimeIntervals": { "startTime": "0", "intervalLength": "0" }
  },
  "overridesFromOutgoingApprovals": true,
  "altTimeChecks": {
    "offlineDays": [
      { "start": "0", "end": "0" },
      { "start": "6", "end": "6" }
    ],
    "timezoneOffsetMinutes": "300",
    "timezoneOffsetNegative": true
  },
  "userApprovalSettings": {
    "userRoyalties": { "percentage": "0", "payoutAddress": "" }
  }
}
{
  "merkleChallenges": [],
  "predeterminedBalances": {
    "manualBalances": [],
    "incrementedBalances": {
      "startBalances": [],
      "incrementTokenIdsBy": "0",
      "incrementOwnershipTimesBy": "0",
      "durationFromTimestamp": "0",
      "allowOverrideTimestamp": false,
      "recurringOwnershipTimes": {
        "startTime": "0",
        "intervalLength": "0",
        "chargePeriodLength": "0"
      },
      "allowOverrideWithAnyValidToken": false,
      "allowAmountScaling": false,
      "maxScalingMultiplier": "0"
    },
    "orderCalculationMethod": {
      "useOverallNumTransfers": false,
      "usePerToAddressNumTransfers": false,
      "usePerFromAddressNumTransfers": false,
      "usePerInitiatedByAddressNumTransfers": false,
      "useMerkleChallengeLeafIndex": false,
      "challengeTrackerId": ""
    }
  },
  "approvalAmounts": {
    "overallApprovalAmount": "0",
    "perToAddressApprovalAmount": "0",
    "perFromAddressApprovalAmount": "0",
    "perInitiatedByAddressApprovalAmount": "0",
    "amountTrackerId": "",
    "resetTimeIntervals": { "startTime": "0", "intervalLength": "0" }
  },
  "maxNumTransfers": {
    "overallMaxNumTransfers": "0",
    "perToAddressMaxNumTransfers": "0",
    "perFromAddressMaxNumTransfers": "0",
    "perInitiatedByAddressMaxNumTransfers": "0",
    "amountTrackerId": "",
    "resetTimeIntervals": { "startTime": "0", "intervalLength": "0" }
  },
  "coinTransfers": [],
  "requireToEqualsInitiatedBy": false,
  "requireFromEqualsInitiatedBy": false,
  "requireToDoesNotEqualInitiatedBy": false,
  "requireFromDoesNotEqualInitiatedBy": false,
  "overridesFromOutgoingApprovals": true,
  "overridesToIncomingApprovals": false,
  "autoDeletionOptions": {
    "afterOneUse": false,
    "afterOverallMaxNumTransfers": false,
    "allowCounterpartyPurge": false,
    "allowPurgeIfExpired": false
  },
  "mustOwnTokens": [],
  "dynamicStoreChallenges": [],
  "ethSignatureChallenges": [],
  "senderChecks": {
    "mustBeEvmContract": false,
    "mustNotBeEvmContract": false,
    "mustBeLiquidityPool": false,
    "mustNotBeLiquidityPool": false
  },
  "recipientChecks": {
    "mustBeEvmContract": false,
    "mustNotBeEvmContract": false,
    "mustBeLiquidityPool": false,
    "mustNotBeLiquidityPool": false
  },
  "initiatorChecks": {
    "mustBeEvmContract": false,
    "mustNotBeEvmContract": false,
    "mustBeLiquidityPool": false,
    "mustNotBeLiquidityPool": false
  },
  "altTimeChecks": {
    "offlineHours": [],
    "offlineDays": [
      { "start": "0", "end": "0" },
      { "start": "6", "end": "6" }
    ],
    "offlineMonths": [],
    "offlineDaysOfMonth": [],
    "offlineWeeksOfYear": [],
    "timezoneOffsetMinutes": "300",
    "timezoneOffsetNegative": true
  },
  "mustPrioritize": false,
  "votingChallenges": [],
  "allowBackedMinting": false,
  "allowSpecialWrapping": false,
  "evmQueryChallenges": [],
  "userApprovalSettings": {
    "allowedDenoms": [],
    "disableUserCoinTransfers": false,
    "userRoyalties": { "percentage": "0", "payoutAddress": "" }
  }
}
ts
interface AltTimeChecks {
  offlineHours?: UintRange[];        // 0-23
  offlineDays?: UintRange[];         // 0-6, 0 = Sunday
  offlineMonths?: UintRange[];       // 1-12
  offlineDaysOfMonth?: UintRange[];  // 1-31
  offlineWeeksOfYear?: UintRange[];  // 1-53, ISO 8601
  timezoneOffsetMinutes?: Uint;      // 0-840
  timezoneOffsetNegative?: boolean;  // true = west of UTC
}
FieldRangeDescription
offlineHours0-23Hours of the day to deny. 0 is midnight, 23 is 11 PM.
offlineDays0-6Weekdays to deny. 0 Sunday, 1 Monday, ... 6 Saturday.
offlineMonths1-12Months to deny. 1 January, 12 December.
offlineDaysOfMonth1-31Days of the month to deny. Days a month does not have never match.
offlineWeeksOfYear1-53ISO 8601 weeks to deny. Week 1 contains the first Thursday. Most years have 52 weeks; 2026 has 53.
timezoneOffsetMinutes0-840Magnitude of the offset from UTC in minutes. 840 is 14 hours, the widest real offset.
timezoneOffsetNegativebooltrue for offsets west of UTC. Unset or false means east.

All ranges are inclusive. Ranges in one array must not overlap, and start must be less than or equal to end.

Ask your agent:

text
Add a transfer approval to collection 1 that blocks transfers on weekends in US Eastern time.

The MCP builder tools (add_approval) produce the objects on this page.

How It Works

  1. Take the block time in UTC. If timezoneOffsetMinutes is set, add or subtract it to get local time.
  2. Check the local hour against offlineHours.
  3. Check the local weekday against offlineDays.
  4. Check the local month against offlineMonths.
  5. Check the local day of month against offlineDaysOfMonth.
  6. Check the local ISO week against offlineWeeksOfYear.
  7. If any check matches, the approval is denied.

altTimeChecks runs in addition to transferTimes. The block time must be inside transferTimes and outside every offline range.

Ranges do not wrap. A window that crosses midnight needs two ranges: [22, 23] and [0, 5]. A range like { "start": "22", "end": "5" } fails validation.

Timezone examples: US Eastern Standard Time (UTC-5) is timezoneOffsetMinutes: "300", timezoneOffsetNegative: true. India Standard Time (UTC+5:30) is timezoneOffsetMinutes: "330" with timezoneOffsetNegative unset. The offset is fixed; the chain does not track daylight saving changes.

Examples

Deny 10 PM to 6 AM UTC:

json
{
  "altTimeChecks": {
    "offlineHours": [
      { "start": "22", "end": "23" },
      { "start": "0", "end": "5" }
    ],
    "offlineDays": [],
    "offlineMonths": [],
    "offlineDaysOfMonth": [],
    "offlineWeeksOfYear": [],
    "timezoneOffsetMinutes": "0",
    "timezoneOffsetNegative": false
  }
}

Deny weekends in US Eastern time. A transfer at 03:00 UTC Monday is 22:00 EST Sunday and is denied:

json
{
  "altTimeChecks": {
    "offlineHours": [],
    "offlineDays": [
      { "start": "0", "end": "0" },
      { "start": "6", "end": "6" }
    ],
    "offlineMonths": [],
    "offlineDaysOfMonth": [],
    "offlineWeeksOfYear": [],
    "timezoneOffsetMinutes": "300",
    "timezoneOffsetNegative": true
  }
}

Deny all of December:

json
{
  "altTimeChecks": {
    "offlineHours": [],
    "offlineDays": [],
    "offlineMonths": [
      { "start": "12", "end": "12" }
    ],
    "offlineDaysOfMonth": [],
    "offlineWeeksOfYear": [],
    "timezoneOffsetMinutes": "0",
    "timezoneOffsetNegative": false
  }
}

Deny the 1st and 15th of every month:

json
{
  "altTimeChecks": {
    "offlineHours": [],
    "offlineDays": [],
    "offlineMonths": [],
    "offlineDaysOfMonth": [
      { "start": "1", "end": "1" },
      { "start": "15", "end": "15" }
    ],
    "offlineWeeksOfYear": [],
    "timezoneOffsetMinutes": "0",
    "timezoneOffsetNegative": false
  }
}

Edit this page on GitHub