From 6ce19bb7dd244777c57d367ddcd84fd210f9b396 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 27 Aug 2025 18:45:52 +0000 Subject: [PATCH 1/6] Add --type h100v flag to buy command examples Co-authored-by: danieltaox --- src/lib/buy/index.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib/buy/index.tsx b/src/lib/buy/index.tsx index 6f723680..981dc765 100644 --- a/src/lib/buy/index.tsx +++ b/src/lib/buy/index.tsx @@ -129,19 +129,19 @@ export function _registerBuy(program: Command) { ` Examples: \x1b[2m# Buy 8 H100s for 1 hour at market price\x1b[0m - $ sf buy -n 8 -d 1h + $ sf buy --type h100v -n 8 -d 1h \x1b[2m# Buy 32 H100s for 6 hours starting in 3 hours\x1b[0m - $ sf buy -n 32 -d 6h -s +3h + $ sf buy --type h100v -n 32 -d 6h -s +3h \x1b[2m# Buy 64 H100s for 12 hours starting tomorrow at 9am\x1b[0m - $ sf buy -n 64 -d 12h -s "tomorrow at 9am" + $ sf buy --type h100v -n 64 -d 12h -s "tomorrow at 9am" \x1b[2m# Extend an existing contract that ends at 4pm by 4 hours\x1b[0m - $ sf buy -s 4pm -d 4h -colo + $ sf buy --type h100v -s 4pm -d 4h -colo \x1b[2m# Place a standing order at a specific price\x1b[0m - $ sf buy -n 16 -d 24h -p 1.50 --standing + $ sf buy --type h100v -n 16 -d 24h -p 1.50 --standing `, ) .action(function buyOrderAction(options) { From fd83f4056c5f3d1aea5d980266ab0dd350417cf3 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 27 Aug 2025 19:06:40 +0000 Subject: [PATCH 2/6] Update buy command help text and colocate option handling Co-authored-by: danieltaox --- src/lib/buy/index.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/buy/index.tsx b/src/lib/buy/index.tsx index 981dc765..74a71fa5 100644 --- a/src/lib/buy/index.tsx +++ b/src/lib/buy/index.tsx @@ -90,7 +90,7 @@ export function _registerBuy(program: Command) { .option("-y, --yes", "Automatically confirm the order") .option( "-colo, --colocate ", - "Colocate with existing contracts", + "Colocate with existing contracts. If provided, `-t`/`--type` will be ignored.", ) .option( "-q, --quote", @@ -109,9 +109,9 @@ export function _registerBuy(program: Command) { "Send into a specific cluster (deprecated, alias for --zone). If provided, \`-t\`/`--type` will be ignored.", ) .hook("preAction", (command) => { - const { type, zone, cluster } = command.opts(); - if (!type && !zone && !cluster) { - console.error(chalk.yellow("Must specify either --type or --zone")); + const { type, zone, cluster, colocate } = command.opts(); + if (!type && !zone && !cluster && !colocate) { + console.error(chalk.yellow("Must specify either --type, --zone, or --colocate")); command.help(); process.exit(1); } @@ -129,19 +129,19 @@ export function _registerBuy(program: Command) { ` Examples: \x1b[2m# Buy 8 H100s for 1 hour at market price\x1b[0m - $ sf buy --type h100v -n 8 -d 1h + $ sf buy -t h100v -n 8 -d 1h \x1b[2m# Buy 32 H100s for 6 hours starting in 3 hours\x1b[0m - $ sf buy --type h100v -n 32 -d 6h -s +3h + $ sf buy -t h100v -n 32 -d 6h -s +3h \x1b[2m# Buy 64 H100s for 12 hours starting tomorrow at 9am\x1b[0m - $ sf buy --type h100v -n 64 -d 12h -s "tomorrow at 9am" + $ sf buy -t h100v -n 64 -d 12h -s "tomorrow at 9am" \x1b[2m# Extend an existing contract that ends at 4pm by 4 hours\x1b[0m - $ sf buy --type h100v -s 4pm -d 4h -colo + $ sf buy -s 4pm -d 4h -colo \x1b[2m# Place a standing order at a specific price\x1b[0m - $ sf buy --type h100v -n 16 -d 24h -p 1.50 --standing + $ sf buy -t h100v -n 16 -d 24h -p 1.50 --standing `, ) .action(function buyOrderAction(options) { From f6e8964cafb81b70ca60f4c50ef9519825e62999 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 28 Aug 2025 03:10:39 +0000 Subject: [PATCH 3/6] release: v0.20.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0f55ffba..997ef85a 100644 --- a/package.json +++ b/package.json @@ -49,5 +49,5 @@ "peerDependencies": { "typescript": "^5.6.2" }, - "version": "0.19.13" + "version": "0.20.0" } From 841587d8161c66e13cbb424100b2bf4a23a84c96 Mon Sep 17 00:00:00 2001 From: Daniel Tao Date: Thu, 28 Aug 2025 13:43:57 -0700 Subject: [PATCH 4/6] fix: instance type is also optional in quote --- src/lib/buy/index.tsx | 51 ++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/lib/buy/index.tsx b/src/lib/buy/index.tsx index 74a71fa5..901a55f8 100644 --- a/src/lib/buy/index.tsx +++ b/src/lib/buy/index.tsx @@ -111,7 +111,9 @@ export function _registerBuy(program: Command) { .hook("preAction", (command) => { const { type, zone, cluster, colocate } = command.opts(); if (!type && !zone && !cluster && !colocate) { - console.error(chalk.yellow("Must specify either --type, --zone, or --colocate")); + console.error( + chalk.yellow("Must specify either --type, --zone or --colocate"), + ); command.help(); process.exit(1); } @@ -275,7 +277,7 @@ export function QuoteAndBuy(props: { options: SfBuyOptions }) { props.options; setOrderProps({ - type: type ?? "h100i", // We still need to pass something even if --zone is provided + type, price: pricePerGpuHour, size: accelerators / GPUS_PER_NODE, startAt, @@ -313,7 +315,7 @@ function BuyOrderPreview(props: { size: number; startAt: Date | "NOW"; endsAt: Date; - type: string; + type?: string; }) { const startDate = props.startAt === "NOW" ? dayjs() : dayjs(props.startAt); const start = startDate.format("MMM D h:mm a").toLowerCase(); @@ -332,9 +334,10 @@ function BuyOrderPreview(props: { const totalPrice = getTotalPrice(props.price, props.size, realDurationHours) / 100; - const isSupportedType = props.type in InstanceTypeMetadata; + const isSupportedType = typeof props.type === "string" && + props.type in InstanceTypeMetadata; const typeLabel = isSupportedType - ? InstanceTypeMetadata[props.type].displayName + ? InstanceTypeMetadata[props.type!]?.displayName : props.type; return ( @@ -365,19 +368,21 @@ function BuyOrderPreview(props: { head="size" value={`${props.size * GPUS_PER_NODE} gpus`} /> - - - type - - - {typeLabel} - {isSupportedType && ( - - ({props.type}) - - )} + {typeLabel && ( + + + type + + + {typeLabel} + {isSupportedType && ( + + ({props.type!}) + + )} + - + )} Date: Thu, 28 Aug 2025 13:26:44 -0700 Subject: [PATCH 5/6] build: update OAPI schema build artifact --- src/schema.ts | 1870 +------------------------------------------------ 1 file changed, 14 insertions(+), 1856 deletions(-) diff --git a/src/schema.ts b/src/schema.ts index af173e3a..e67e9e96 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -299,1701 +299,6 @@ export interface paths { patch?: never; trace?: never; }; - "/v0/admin/accounts/{id}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description The account details */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "account"; - id: string; - waitlist: boolean; - /** @enum {string} */ - role: "admin" | "user" | "vendor" | "clops" | "sfcd"; - kyc: components["schemas"]["San_Francisco_Compute_Documentation_AccountKycLevel"]; - can_buy?: boolean; - can_sell?: boolean; - balance?: components["schemas"]["San_Francisco_Compute_Documentation_AccountBalance"]; - instant_deposit_limit?: number; - is_legacy: boolean; - users?: { - clerk_id: string; - full_name?: string; - avatar?: string; - emails: string[]; - }[]; - }; - }; - }; - /** @description Not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_NotFoundError"]; - }; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/balance": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description The account balance */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountBalance"]; - }; - }; - /** @description Not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_NotFoundError"]; - }; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get: { - parameters: { - query?: { - limit?: number | null; - offset?: number | null; - fuzzy_id?: string; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description The list of accounts */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "list"; - data: { - /** @enum {string} */ - object: "account"; - id: string; - waitlist: boolean; - /** @enum {string} */ - role: "admin" | "user" | "vendor" | "clops" | "sfcd"; - kyc: components["schemas"]["San_Francisco_Compute_Documentation_AccountKycLevel"]; - can_buy?: boolean; - can_sell?: boolean; - balance?: components["schemas"]["San_Francisco_Compute_Documentation_AccountBalance"]; - instant_deposit_limit?: number; - is_legacy: boolean; - users?: { - clerk_id: string; - full_name?: string; - avatar?: string; - emails: string[]; - }[]; - }[]; - has_more: boolean; - }; - }; - }; - }; - }; - put?: never; - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: { - content: { - "application/json": { - id: string; - clerk_id: string; - }; - }; - }; - responses: { - /** @description The account details */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "account"; - id: string; - waitlist: boolean; - /** @enum {string} */ - role: "admin" | "user" | "vendor" | "clops" | "sfcd"; - kyc: components["schemas"]["San_Francisco_Compute_Documentation_AccountKycLevel"]; - can_buy?: boolean; - can_sell?: boolean; - balance?: components["schemas"]["San_Francisco_Compute_Documentation_AccountBalance"]; - instant_deposit_limit?: number; - is_legacy: boolean; - users?: { - clerk_id: string; - full_name?: string; - avatar?: string; - emails: string[]; - }[]; - }; - }; - }; - /** @description The account details */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "account"; - id: string; - waitlist: boolean; - /** @enum {string} */ - role: "admin" | "user" | "vendor" | "clops" | "sfcd"; - kyc: components["schemas"]["San_Francisco_Compute_Documentation_AccountKycLevel"]; - can_buy?: boolean; - can_sell?: boolean; - balance?: components["schemas"]["San_Francisco_Compute_Documentation_AccountBalance"]; - instant_deposit_limit?: number; - is_legacy: boolean; - users?: { - clerk_id: string; - full_name?: string; - avatar?: string; - emails: string[]; - }[]; - }; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_InvalidRequestError"]; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_InternalServerError"]; - }; - }; - }; - }; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/approve": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: { - content: { - "application/json": { - kyc_level: components["schemas"]["San_Francisco_Compute_Documentation_AccountKycLevel"]; - }; - }; - }; - responses: { - /** @description The account details */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "account"; - id: string; - waitlist: boolean; - /** @enum {string} */ - role: "admin" | "user" | "vendor" | "clops" | "sfcd"; - kyc: components["schemas"]["San_Francisco_Compute_Documentation_AccountKycLevel"]; - can_buy?: boolean; - can_sell?: boolean; - balance?: components["schemas"]["San_Francisco_Compute_Documentation_AccountBalance"]; - instant_deposit_limit?: number; - is_legacy: boolean; - users?: { - clerk_id: string; - full_name?: string; - avatar?: string; - emails: string[]; - }[]; - }; - }; - }; - /** @description Not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_NotFoundError"]; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_InternalServerError"]; - }; - }; - }; - }; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/instant-deposit-limit": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: { - content: { - "application/json": { - amount: number; - }; - }; - }; - responses: { - /** @description The account details */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "account"; - id: string; - waitlist: boolean; - /** @enum {string} */ - role: "admin" | "user" | "vendor" | "clops" | "sfcd"; - kyc: components["schemas"]["San_Francisco_Compute_Documentation_AccountKycLevel"]; - can_buy?: boolean; - can_sell?: boolean; - balance?: components["schemas"]["San_Francisco_Compute_Documentation_AccountBalance"]; - instant_deposit_limit?: number; - is_legacy: boolean; - users?: { - clerk_id: string; - full_name?: string; - avatar?: string; - emails: string[]; - }[]; - }; - }; - }; - /** @description Not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_NotFoundError"]; - }; - }; - }; - }; - trace?: never; - }; - "/v0/admin/accounts/{id}/waitlist": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: { - content: { - "application/json": { - isWaitlist: boolean; - }; - }; - }; - responses: { - /** @description The account details after waitlist status update */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "account"; - id: string; - waitlist: boolean; - /** @enum {string} */ - role: "admin" | "user" | "vendor" | "clops" | "sfcd"; - kyc: components["schemas"]["San_Francisco_Compute_Documentation_AccountKycLevel"]; - can_buy?: boolean; - can_sell?: boolean; - balance?: components["schemas"]["San_Francisco_Compute_Documentation_AccountBalance"]; - instant_deposit_limit?: number; - is_legacy: boolean; - users?: { - clerk_id: string; - full_name?: string; - avatar?: string; - emails: string[]; - }[]; - }; - }; - }; - /** @description Not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_NotFoundError"]; - }; - }; - }; - }; - trace?: never; - }; - "/v0/admin/accounts/{id}/bank-accounts/has-connected": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Check if the account has connected bank accounts */ - get: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - hasConnected: boolean; - }; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountNotFoundError"]; - }; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/bank-accounts": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "list"; - accounts: { - /** @enum {string} */ - object: "bank_account"; - id: string; - columnCounterpartyId: string; - accountName: string; - last4Digits: string; - institutionPrimaryColor?: string; - institutionLogoBase64?: string; - }[]; - }; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountNotFoundError"]; - }; - }; - }; - }; - put?: never; - post: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: { - content: { - "application/json": { - plaidAccessToken: string; - selectedAccountIds: string[]; - }; - }; - }; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "success"; - success: boolean; - created: { - /** @enum {string} */ - object: "bank_account"; - id: string; - columnCounterpartyId: string; - accountName: string; - last4Digits: string; - institutionPrimaryColor?: string; - institutionLogoBase64?: string; - }[]; - }; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** - * @example error - * @enum {string} - */ - object: "error"; - /** - * @example bank-accounts.invalid_account_type - * @enum {string} - */ - code: "bank-accounts.invalid_account_type"; - /** @example Selected accounts must all be depository accounts. */ - message?: string; - /** @example {} */ - details?: { - [key: string]: unknown; - }; - }; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountNotFoundError"]; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_InternalServerError"]; - }; - }; - /** @description Service deprecated */ - 503: { - headers: { - /** - * Format: integer - * @description The timestamp of the deprecation - * @example 1749772800 - */ - Deprecation?: unknown; - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_ServiceDeprecatedError"]; - }; - }; - }; - }; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/bank-accounts/debit": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: { - content: { - "application/json": { - bankAccountId: string; - amountCents: number; - }; - }; - }; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "success"; - /** @enum {boolean} */ - success: true; - initiated: boolean; - }; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountNotFoundError"]; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_InternalServerError"]; - }; - }; - /** @description Service deprecated */ - 503: { - headers: { - /** - * Format: integer - * @description The timestamp of the deprecation - * @example 1749772800 - */ - Deprecation?: unknown; - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_ServiceDeprecatedError"]; - }; - }; - }; - }; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/transfers/pending": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - ach: { - incoming: { - volumeCents: number; - count: number; - }; - outgoing: { - volumeCents: number; - count: number; - }; - }; - }; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountNotFoundError"]; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_InternalServerError"]; - }; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/tokens/cli": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description CLI token created successfully */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_Token"]; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - }; - }; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/tokens": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: { - content: { - "application/json": { - account: string; - name: string; - description?: string; - }; - }; - }; - responses: { - /** @description Token created successfully */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_Token"]; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - }; - }; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/tokens/{id}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Token details */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_Token"]; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Token not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/prices": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** @description Get historical prices for a given instance type */ - get: { - parameters: { - query?: { - instance_type?: ("h100i" | "h100v" | "h200ki") | string; - min_quantity?: number; - max_quantity?: number; - min_duration?: number | null; - max_duration?: number | null; - since_n_days_ago?: number | null; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description The historical prices for the given instance type */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - data: components["schemas"]["San_Francisco_Compute_Documentation_PriceHistoryItem"][]; - /** - * @example true - * @example false - */ - has_more: boolean; - /** - * @example list - * @enum {string} - */ - object: "list"; - }; - }; - }; - /** @description The request is too far in past */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_PriceRequestTooFarInPastError"] | components["schemas"]["San_Francisco_Compute_Documentation_InvalidRequestError"]; - }; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/instant-deposits/limits": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Account instant deposit limits */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "instant_deposit_limits"; - volume_used: number; - volume_remaining: number; - volume_per_period: number; - period_duration: number; - period_unit: string; - limits_refresh_on: string; - }; - }; - }; - /** @description Account frozen */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountFrozenError"]; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountNotFoundError"]; - }; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/instant-deposits/checkout-session": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get: { - parameters: { - query: { - amount_cents: string | number; - }; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Stripe checkout session URL */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "url"; - checkoutUrl: string; - }; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_InvalidRequestError"]; - }; - }; - /** @description Account frozen */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountFrozenError"]; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountNotFoundError"]; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_InternalServerError"]; - }; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/instant-deposits/{instantDepositId}/status": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - instantDepositId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Instant deposit status */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "success"; - success: boolean; - completed: boolean; - amount: number; - }; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_NotAuthenticatedError"]; - }; - }; - /** @description Account frozen */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountFrozenError"]; - }; - }; - /** @description Account or deposit not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_NotFoundError"]; - }; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/metadata": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description User metadata */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - id: string; - account_id: string | null; - is_org: boolean; - primary_email: string; - avatar: string | null; - created_at: string; - primary_phone: string | null; - first_name: string | null; - last_name: string | null; - date_of_birth: string | null; - ip_address: string | null; - primary_address_street_1: string | null; - primary_address_street_2: string | null; - primary_address_region: string | null; - primary_address_postal_code: string | null; - primary_address_city: string | null; - primary_address_country: string | null; - business_name: string | null; - business_address_street_1: string | null; - business_address_street_2: string | null; - business_address_region: string | null; - business_address_postal_code: string | null; - business_address_city: string | null; - business_address_country: string | null; - compute_usage_statement: string | null; - business_primary_contact_id: string | null; - }; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountNotFoundError"]; - }; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/compliance/kyc": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: { - content: { - "application/json": { - id: string; - account_id?: string | null; - is_org?: boolean; - primary_email: string; - avatar?: string | null; - created_at?: string; - primary_phone?: string | null; - first_name?: string | null; - last_name?: string | null; - date_of_birth?: string | null; - ip_address?: string | null; - primary_address_street_1?: string | null; - primary_address_street_2?: string | null; - primary_address_region?: string | null; - primary_address_postal_code?: string | null; - primary_address_city?: string | null; - primary_address_country?: string | null; - business_name?: string | null; - business_address_street_1?: string | null; - business_address_street_2?: string | null; - business_address_region?: string | null; - business_address_postal_code?: string | null; - business_address_city?: string | null; - business_address_country?: string | null; - compute_usage_statement?: string | null; - business_primary_contact_id?: string | null; - id_number?: string; - }; - }; - }; - responses: { - /** @description Existing KYC verification result */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "status"; - data: { - status?: string; - complete_outcome?: string; - }; - }; - }; - }; - /** @description New KYC verification result */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "status"; - data: { - status?: string; - complete_outcome?: string; - }; - }; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_InvalidRequestError"]; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountNotFoundError"]; - }; - }; - }; - }; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/compliance/tax": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: { - content: { - "application/json": { - id_number: string; - }; - }; - }; - responses: { - /** @description KYC verification result */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "status"; - data: { - status?: string; - complete_outcome?: string; - }; - }; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountNotFoundError"]; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_InternalServerError"]; - }; - }; - }; - }; - trace?: never; - }; - "/v0/admin/accounts/{id}/compliance/kyb": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: { - content: { - "application/json": { - business_primary_contact_id: string; - business_name: string; - business_address_street_1: string; - business_address_street_2?: string; - business_address_city?: string; - business_address_region?: string; - business_address_postal_code?: string; - business_address_country?: string; - }; - }; - }; - responses: { - /** @description KYB verification result */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "status"; - data: { - user: string; - business: string; - }; - }; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_InvalidRequestError"]; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountNotFoundError"]; - }; - }; - }; - }; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v0/admin/accounts/{id}/compliance/kycb": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: { - content: { - "application/json": { - id: string; - account_id?: string | null; - is_org?: boolean; - primary_email: string; - avatar?: string | null; - created_at?: string; - primary_phone?: string | null; - first_name?: string | null; - last_name?: string | null; - date_of_birth?: string | null; - ip_address?: string | null; - primary_address_street_1?: string | null; - primary_address_street_2?: string | null; - primary_address_region?: string | null; - primary_address_postal_code?: string | null; - primary_address_city?: string | null; - primary_address_country?: string | null; - business_name: string; - business_address_street_1: string; - business_address_street_2?: string; - business_address_region?: string; - business_address_postal_code?: string; - business_address_city?: string; - business_address_country?: string; - compute_usage_statement?: string | null; - business_primary_contact_id: string; - business_primary_contact_account_id: string; - }; - }; - }; - responses: { - /** @description KYB verification result */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** @enum {string} */ - object: "status"; - data: { - user: string; - business: string; - }; - }; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_InvalidRequestError"]; - }; - }; - /** @description Account not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["San_Francisco_Compute_Documentation_AccountNotFoundError"]; - }; - }; - }; - }; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; "/v0/credentials": { parameters: { query?: never; @@ -2314,7 +619,7 @@ export interface paths { head?: never; /** * Release node - * @description Release an on-demand VM node from its procurement, reducing the procurement's desired quantity by 1 + * @description Release an auto reserved VM node from its procurement, reducing the procurement's desired quantity by 1 */ patch: operations["release_node_handler"]; trace?: never; @@ -3258,154 +1563,6 @@ export interface components { newest_timestamp: string | null; }; }; - San_Francisco_Compute_Documentation_AccountKycLevel: "none" | "basic" | "core"; - San_Francisco_Compute_Documentation_NotFoundError: { - /** - * @example error - * @enum {string} - */ - object: "error"; - /** - * @example not_found - * @enum {string} - */ - code: "not_found"; - /** @example Not found. */ - message?: string; - /** @example {} */ - details?: { - [key: string]: unknown; - }; - }; - San_Francisco_Compute_Documentation_InvalidRequestError: { - /** - * @example error - * @enum {string} - */ - object: "error"; - /** - * @example invalid_request - * @enum {string} - */ - code: "invalid_request"; - /** @example Invalid request */ - message?: string; - /** @example {} */ - details?: { - [key: string]: unknown; - }; - }; - San_Francisco_Compute_Documentation_InternalServerError: { - /** - * @example error - * @enum {string} - */ - object: "error"; - /** - * @example internal_server - * @enum {string} - */ - code: "internal_server"; - /** @example An unknown error has occurred. Our engineers have been notified. */ - message?: string; - /** @example {} */ - details?: { - [key: string]: unknown; - }; - }; - San_Francisco_Compute_Documentation_ServiceDeprecatedError: { - /** - * @example error - * @enum {string} - */ - object: "error"; - /** - * @example service_deprecated - * @enum {string} - */ - code: "service_deprecated"; - /** @example Service has been deprecated and is no longer available. */ - message?: string; - /** @example {} */ - details?: { - [key: string]: unknown; - }; - }; - San_Francisco_Compute_Documentation_PriceHistoryItem: { - /** @enum {string} */ - object: "price-history-item"; - /** - * @description ISO 8601 datetime marking the start of the period. - * @example 2024-10-05T07:00:00.000Z - */ - period_start: string; - /** - * @description ISO 8601 datetime marking the end of the period. - * @example 2024-10-06T06:59:59.999Z - */ - period_end: string; - /** @enum {boolean} */ - no_data: false; - gpu_hour: { - /** @description The minimum price per GPU hour for the period (in cents, 1 = $0.01). */ - min: number; - /** @description The maximum price per GPU hour for the period (in cents, 1 = $0.01). */ - max: number; - /** @description The average price per GPU hour for the period (in cents, 1 = $0.01). */ - avg: number; - }; - } | { - /** @enum {string} */ - object: "price-history-item"; - /** - * @description ISO 8601 datetime marking the start of the period. - * @example 2024-10-05T07:00:00.000Z - */ - period_start: string; - /** - * @description ISO 8601 datetime marking the end of the period. - * @example 2024-10-06T06:59:59.999Z - */ - period_end: string; - /** @enum {boolean} */ - no_data: true; - }; - San_Francisco_Compute_Documentation_PriceRequestTooFarInPastError: { - /** - * @example error - * @enum {string} - */ - object: "error"; - /** - * @example price.historical_price_request_too_far_in_past - * @enum {string} - */ - code: "price.historical_price_request_too_far_in_past"; - /** @example Historical price request too far in past */ - message?: string; - /** @example {} */ - details?: { - [key: string]: unknown; - }; - }; - San_Francisco_Compute_Documentation_NotAuthenticatedError: { - /** - * @example error - * @enum {string} - */ - object: "error"; - /** - * @example not_authenticated - * @enum {string} - */ - code: "not_authenticated"; - /** @example Not authenticated, did you pass an auth token? */ - message?: string; - /** @example {} */ - details?: { - [key: string]: unknown; - }; - }; "SF_Compute_K8s_Orchestration_API_frontend_server.BaseCredentialResponse": { cluster?: components["schemas"]["SF_Compute_K8s_Orchestration_API_frontend_server.ClusterInfo"]; id?: string; @@ -3527,7 +1684,7 @@ export interface components { * Format: int64 * @description End time as Unix timestamp in seconds. * If provided, end time must be aligned to the hour. - * If not provided, the node will be created as an on-demand node. + * If not provided, the node will be created as an autoreserved node. */ end_at?: number | null; /** @@ -3688,7 +1845,7 @@ export interface components { object: string; /** @example sfcompute */ owner: string; - /** @example proc_h100ondemand_1 */ + /** @example proc_b1dc52505c6de142 */ procurement_id?: string | null; /** * Format: int64 @@ -3713,7 +1870,7 @@ export interface components { "node-api_ListResponse_ZoneInfo": { data: { /** @description The available capacity on this cluster, in the - * shape of consequtive "availability rectangles". */ + * shape of consecutive "availability rectangles". */ available_capacity: components["schemas"]["node-api_AvailabilityRectangle"][]; delivery_type: components["schemas"]["node-api_DeliveryType"]; hardware_type: components["schemas"]["node-api_AcceleratorType"]; @@ -3760,7 +1917,7 @@ export interface components { object: string; /** @example sfcompute */ owner: string; - /** @example proc_h100ondemand_1 */ + /** @example proc_b1dc52505c6de142 */ procurement_id?: string | null; /** * Format: int64 @@ -3829,7 +1986,7 @@ export interface components { "node-api_VmStatus": "Pending" | "Running" | "Destroyed" | "NodeFailure" | "Unspecified"; "node-api_ZoneInfo": { /** @description The available capacity on this cluster, in the - * shape of consequtive "availability rectangles". */ + * shape of consecutive "availability rectangles". */ available_capacity: components["schemas"]["node-api_AvailabilityRectangle"][]; delivery_type: components["schemas"]["node-api_DeliveryType"]; hardware_type: components["schemas"]["node-api_AcceleratorType"]; @@ -3939,10 +2096,11 @@ export interface components { "market-api_ContractStatus": "active" | "pending"; "market-api_CreateOrderRequest": { cluster?: null | components["schemas"]["market-api_ClusterName"]; + /** @description A contract to colocate with. This overrides the instance_type if specified. */ colocate_with?: components["schemas"]["market-api_ContractId"][]; end_at: components["schemas"]["market-api_NowOrISO8601DateTime"]; flags?: components["schemas"]["market-api_OrderFlags"]; - instance_type: components["schemas"]["market-api_Ticker"]; + instance_type?: null | components["schemas"]["market-api_Ticker"]; /** * Format: int64 * @description Price in cents @@ -5170,7 +3328,7 @@ export interface operations { * "created_at": 1640995200, * "updated_at": 1640995200, * "start_at": 1640995200, - * "procurement_id": "proc_h100ondemand_1", + * "procurement_id": "proc_b1dc52505c6de142", * "max_price_per_node_hour": 1000, * "node_type": "autoreserved", * "vms": { @@ -5295,7 +3453,7 @@ export interface operations { * "created_at": 1640995200, * "updated_at": 1640995200, * "start_at": 1640995200, - * "procurement_id": "proc_h100ondemand_1", + * "procurement_id": "proc_b1dc52505c6de142", * "max_price_per_node_hour": 1000, * "node_type": "autoreserved" * } @@ -5412,7 +3570,7 @@ export interface operations { * "created_at": 1640995200, * "updated_at": 1640995200, * "start_at": 1640995200, - * "procurement_id": "proc_h100ondemand_1", + * "procurement_id": "proc_b1dc52505c6de142", * "max_price_per_node_hour": 1000, * "node_type": "autoreserved", * "vms": { @@ -5580,7 +3738,7 @@ export interface operations { /** @example { * "error": { * "type": "invalid_request_error", - * "message": "Node is On Demand not Reserved - only reservation nodes can be extended", + * "message": "Node is Auto Reserved not Reserved - only reservation nodes can be extended", * "details": [ * { * "field": "duration_seconds", @@ -5702,7 +3860,7 @@ export interface operations { * "end_at": 1641000000, * "max_price_per_node_hour": 1000, * "node_type": "autoreserved", - * "procurement_id": "proc_h100ondemand_1", + * "procurement_id": "proc_b1dc52505c6de142", * "vms": { * "object": "list", * "data": [ @@ -5730,7 +3888,7 @@ export interface operations { /** @example { * "error": { * "type": "invalid_request_error", - * "message": "Node is Reserved not On Demand - only on-demand nodes can be released" + * "message": "Node is Reserved not Auto Reserved - only autoreserved nodes can be released" * } * } */ "application/json": components["schemas"]["node-api_ErrorObject"]; From ab2b5bbbabc30fc9785e938e15c18a0b0e4ae34d Mon Sep 17 00:00:00 2001 From: Daniel Tao Date: Fri, 29 Aug 2025 16:23:43 -0700 Subject: [PATCH 6/6] fix: show zone or colocate in the buy preview --- src/lib/buy/index.tsx | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/lib/buy/index.tsx b/src/lib/buy/index.tsx index 901a55f8..db26f5f1 100644 --- a/src/lib/buy/index.tsx +++ b/src/lib/buy/index.tsx @@ -310,13 +310,7 @@ export function getTotalPrice( return Math.ceil(pricePerGpuHour * size * GPUS_PER_NODE * durationInHours); } -function BuyOrderPreview(props: { - price: number; - size: number; - startAt: Date | "NOW"; - endsAt: Date; - type?: string; -}) { +function BuyOrderPreview(props: BuyOrderProps) { const startDate = props.startAt === "NOW" ? dayjs() : dayjs(props.startAt); const start = startDate.format("MMM D h:mm a").toLowerCase(); @@ -383,6 +377,28 @@ function BuyOrderPreview(props: { )} + {props.cluster && ( + + + zone + + + {props.cluster} + + + )} + {props.colocate && ( + + + + colocate with + + + + {props.colocate} + + + )}