Skip to content
Open
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
5 changes: 0 additions & 5 deletions .changeset/metal-socks-vanish.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/tall-mangos-run.md

This file was deleted.

17 changes: 17 additions & 0 deletions apps/auth/nextjs-ssr/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# @crossmint/server-sdk-next-starter

## 0.4.154

### Patch Changes

- Updated dependencies [92c894a]
- Updated dependencies [464292b]
- Updated dependencies [402001f]
- @crossmint/client-sdk-react-ui@3.1.0
- @crossmint/server-sdk@1.2.63

## 0.4.153

### Patch Changes

- Updated dependencies [a6fadd0]
- @crossmint/client-sdk-react-ui@3.0.3

## 0.4.152

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion apps/auth/nextjs-ssr/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@crossmint/auth-ssr-nextjs-demo",
"version": "0.4.152",
"version": "0.4.154",
"private": true,
"scripts": {
"dev": "next dev",
Expand Down
6 changes: 6 additions & 0 deletions apps/auth/node-and-express-server/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# crossmint-auth-node

## 1.1.74

### Patch Changes

- @crossmint/server-sdk@1.2.63

## 1.1.73

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion apps/auth/node-and-express-server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "crossmint-auth-node",
"version": "1.1.73",
"version": "1.1.74",
"description": "",
"main": "index.js",
"type": "module",
Expand Down
17 changes: 17 additions & 0 deletions apps/payments/nextjs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# @crossmint/client-sdk-nextjs-starter

## 2.0.4

### Patch Changes

- Updated dependencies [92c894a]
- Updated dependencies [464292b]
- Updated dependencies [402001f]
- @crossmint/client-sdk-react-ui@3.1.0
- @crossmint/client-sdk-base@2.1.0

## 2.0.3

### Patch Changes

- Updated dependencies [a6fadd0]
- @crossmint/client-sdk-react-ui@3.0.3

## 2.0.2

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion apps/payments/nextjs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@crossmint/client-sdk-nextjs-starter",
"version": "2.0.2",
"version": "2.0.4",
"private": true,
"repository": "https://github.com/Crossmint/crossmint-sdk",
"license": "Apache-2.0",
Expand Down
32 changes: 32 additions & 0 deletions apps/payments/nextjs/pages/hosted-checkout/v3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ export default function HostedCheckoutV3Page() {
{createTokenButtonSection("dark", false, true)}
</div>
</div>
<div style={{ marginTop: "40px", textAlign: "center" }}>
<h2 style={{ marginBottom: "16px" }}>Order-Based Checkout (orderId + clientSecret)</h2>
<p style={{ marginBottom: "16px", color: "#666" }}>
Create an order server-side first, then paste orderId + clientSecret below.
</p>
<div style={{ display: "flex", gap: "20px", justifyContent: "center" }}>
{createOrderBasedButtonSection("crossmint")}
{createOrderBasedButtonSection("dark")}
</div>
</div>
</HostedCheckoutV3ClientProviders>
</div>
);
Expand Down Expand Up @@ -153,3 +163,25 @@ function createTokenButtonSection(
</div>
);
}

const ORDER_ID = "YOUR_ORDER_ID";
const CLIENT_SECRET = "YOUR_CLIENT_SECRET";

function createOrderBasedButtonSection(buttonTheme: CrossmintHostedCheckoutV3ButtonTheme) {
return (
<div
style={{
backgroundColor: buttonTheme === "light" ? "black" : "white",
display: "flex",
justifyContent: "center",
padding: "20px",
}}
>
<CrossmintHostedCheckout
orderId={ORDER_ID}
clientSecret={CLIENT_SECRET}
appearance={{ theme: { button: buttonTheme } }}
/>
</div>
);
}
16 changes: 16 additions & 0 deletions apps/wallets/quickstart-devkit/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# @crossmint/wallets-quickstart-devkit

## 0.2.24

### Patch Changes

- Updated dependencies [92c894a]
- Updated dependencies [464292b]
- Updated dependencies [402001f]
- @crossmint/client-sdk-react-ui@3.1.0

## 0.2.23

### Patch Changes

- Updated dependencies [a6fadd0]
- @crossmint/client-sdk-react-ui@3.0.3

## 0.2.22

### Patch Changes
Expand Down
11 changes: 5 additions & 6 deletions apps/wallets/quickstart-devkit/components/activity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,23 @@ export function Activity() {
<div className="text-gray-500 text-center" data-testid="activity-loading">
Loading...
</div>
) : !activity || activity.data.length === 0 ? (
) : !activity || activity.events.length === 0 ? (
<div className="text-gray-500 text-center" data-testid="activity-empty">
No recent activity
</div>
) : (
activity.data.map((transfer, idx) => (
activity.events.map((event, idx) => (
<div
key={`${transfer.sender.address}-${idx}`}
key={`${event.transaction_hash}-${idx}`}
data-testid={`activity-event-${idx}`}
className="flex justify-between items-center py-2.5 border-t border-gray-100 first:border-t-0"
>
<div>
<div className="font-medium">
{transfer.token.amount} {transfer.token.symbol ?? transfer.token.locator}
{event.amount} {event.token_symbol}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 token_symbol is optional — missing fallback

According to the WalletsActivityResponseUnstableDTO OpenAPI schema, token_symbol is not in the required array, meaning it can be absent for some activity events (e.g. unknown or non-standard tokens). The previous code guarded this with transfer.token.symbol ?? transfer.token.locator, but the new code renders nothing when token_symbol is undefined, leaving a blank next to the amount.

Consider falling back to a meaningful placeholder, for example:

Suggested change
{event.amount} {event.token_symbol}
{event.amount} {event.token_symbol ?? ""}

or a more informative fallback such as event.token_symbol ?? event.mint_hash?.slice(0, 8) ?? "Unknown".

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/wallets/quickstart-devkit/components/activity.tsx
Line: 56

Comment:
**`token_symbol` is optional — missing fallback**

According to the `WalletsActivityResponseUnstableDTO` OpenAPI schema, `token_symbol` is **not** in the `required` array, meaning it can be absent for some activity events (e.g. unknown or non-standard tokens). The previous code guarded this with `transfer.token.symbol ?? transfer.token.locator`, but the new code renders nothing when `token_symbol` is undefined, leaving a blank next to the amount.

Consider falling back to a meaningful placeholder, for example:

```suggestion
                                    {event.amount} {event.token_symbol ?? ""}
```

or a more informative fallback such as `event.token_symbol ?? event.mint_hash?.slice(0, 8) ?? "Unknown"`.

How can I resolve this? If you propose a fix, please make it concise.

</div>
<div className="text-xs text-gray-500">
From: {shortenAddress(transfer.sender.address)} → To:{" "}
{shortenAddress(transfer.recipient.address)}
From: {shortenAddress(event.from_address)} → To: {shortenAddress(event.to_address)}
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion apps/wallets/quickstart-devkit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@crossmint/wallets-quickstart-devkit",
"version": "0.2.22",
"version": "0.2.24",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
Expand Down
14 changes: 14 additions & 0 deletions apps/wallets/smart-wallet/expo/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# expo-demo

## 1.1.127

### Patch Changes

- Updated dependencies [e912d18]
- @crossmint/wallets-sdk@0.21.0
- @crossmint/client-sdk-react-native-ui@0.13.26

## 1.1.126

### Patch Changes

- @crossmint/client-sdk-react-native-ui@0.13.25

## 1.1.125

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion apps/wallets/smart-wallet/expo/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "expo-demo",
"main": "expo-router/entry",
"version": "1.1.125",
"version": "1.1.127",
"scripts": {
"start": "expo start",
"reset-project": "node ./scripts/reset-project.js",
Expand Down
8 changes: 8 additions & 0 deletions packages/client/auth/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# @crossmint/client-sdk-auth

## 1.2.51

### Patch Changes

- Updated dependencies [402001f]
- @crossmint/client-sdk-base@2.1.0
- @crossmint/common-sdk-auth@1.0.73

## 1.2.50

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/client/auth/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@crossmint/client-sdk-auth",
"version": "1.2.50",
"version": "1.2.51",
"repository": "https://github.com/Crossmint/crossmint-sdk",
"license": "Apache-2.0",
"author": "Paella Labs Inc",
Expand Down
6 changes: 6 additions & 0 deletions packages/client/base/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @crossmint/client-sdk-base

## 2.1.0

### Minor Changes

- 402001f: Add orderId + clientSecret support to hosted checkout for pre-created orders

## 2.0.2

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/client/base/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@crossmint/client-sdk-base",
"version": "2.0.2",
"version": "2.1.0",
"repository": "https://github.com/Crossmint/crossmint-sdk",
"license": "Apache-2.0",
"author": "Paella Labs Inc",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import type { CrossmintHostedCheckoutV3Props } from "@/types/hosted/v3/CrossmintHostedCheckoutV3Props";
import {
type CrossmintHostedCheckoutV3AllProps,
isHostedCheckoutV3ExistingOrderProps,
type CrossmintHostedCheckoutV3OrderProps,
} from "@/types/hosted/v3/CrossmintHostedCheckoutV3Props";
import { appendObjectToQueryParams } from "@/utils/appendObjectToQueryParams";
import { NewTabWindow, PopupWindow } from "@crossmint/client-sdk-window";
import type { CrossmintApiClient } from "@crossmint/common-sdk-base";
import { crossmintHostedCheckoutOverlayService } from "./crossmintHostedCheckoutOverlayService";

export type CrossmintHostedCheckoutV3ServiceProps = {
apiClient: CrossmintApiClient;
hostedCheckoutProps: CrossmintHostedCheckoutV3Props;
hostedCheckoutProps: CrossmintHostedCheckoutV3AllProps;
};

export function crossmintHostedCheckoutV3Service({
Expand All @@ -15,11 +19,20 @@ export function crossmintHostedCheckoutV3Service({
}: CrossmintHostedCheckoutV3ServiceProps) {
const overlayService = crossmintHostedCheckoutOverlayService();

function getUrl(props: CrossmintHostedCheckoutV3Props) {
const urlWithPath = apiClient.buildUrl("/sdk/2024-03-05/hosted-checkout");
function getUrl(props: CrossmintHostedCheckoutV3AllProps) {
const isExistingOrder = isHostedCheckoutV3ExistingOrderProps(props);
const path = isExistingOrder
? `/sdk/2024-03-05/hosted-checkout/${encodeURIComponent(props.orderId)}`
: "/sdk/2024-03-05/hosted-checkout";
const urlWithPath = apiClient.buildUrl(path);
const queryParams = new URLSearchParams();

appendObjectToQueryParams(queryParams, props);
if (isExistingOrder) {
const { orderId, ...restOfParams } = props as CrossmintHostedCheckoutV3OrderProps;
appendObjectToQueryParams(queryParams, restOfParams);
Comment on lines +31 to +32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 clientSecret leaked in URL query parameters for order-based checkout

When using the order-based checkout flow, the clientSecret is included in the URL query string. In crossmintHostedCheckoutV3Service.ts:31, only orderId is destructured out of the props before passing the rest to appendObjectToQueryParams. This means clientSecret is appended as a visible query parameter in the popup/new-tab URL. Query parameters are stored in browser history, can appear in server logs, referrer headers, and browser extensions. The clientSecret should either be excluded from query params or transmitted through a more secure channel (e.g., postMessage after the window opens).

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

} else {
appendObjectToQueryParams(queryParams, props);
}

queryParams.append("apiKey", apiClient.crossmint.apiKey);
queryParams.append("sdkMetadata", JSON.stringify(apiClient["internalConfig"].sdkMetadata));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { Locale } from "@/types";
import type {
CrossmintHostedCheckoutV3ButtonTheme,
CrossmintHostedCheckoutV3Props,
import {
type CrossmintHostedCheckoutV3ButtonTheme,
type CrossmintHostedCheckoutV3AllProps,
isHostedCheckoutV3ExistingOrderProps,
} from "@/types/hosted/v3/CrossmintHostedCheckoutV3Props";
import { t } from "@/utils/i18n";

Expand All @@ -14,7 +15,7 @@ const BUTTON_THEME_TO_CLASSNAME: Record<CrossmintHostedCheckoutV3ButtonTheme, st
crossmint: `${BUTTON_CLASSNAME}--Crossmint`,
};

export function crossmintHostedCheckoutV3StylesService(hostedCheckoutProps: CrossmintHostedCheckoutV3Props) {
export function crossmintHostedCheckoutV3StylesService(hostedCheckoutProps: CrossmintHostedCheckoutV3AllProps) {
const buttonTheme = hostedCheckoutProps.appearance?.theme?.button || "dark";

function generateCss() {
Expand Down Expand Up @@ -109,8 +110,8 @@ export function crossmintHostedCheckoutV3StylesService(hostedCheckoutProps: Cros
function getButtonText() {
const locale: Locale = hostedCheckoutProps.locale || "en-US";

const isCryptoEnabled = hostedCheckoutProps.payment?.crypto?.enabled;
const isFiatEnabled = hostedCheckoutProps.payment?.fiat?.enabled;
const isCryptoEnabled = hostedCheckoutProps.payment?.crypto?.enabled ?? false;
const isFiatEnabled = hostedCheckoutProps.payment?.fiat?.enabled ?? false;

const paymentMethodText = (() => {
if (isCryptoEnabled && isFiatEnabled) {
Expand All @@ -122,6 +123,9 @@ export function crossmintHostedCheckoutV3StylesService(hostedCheckoutProps: Cros
if (isFiatEnabled) {
return t("hostedCheckoutV3.card", locale);
}
if (isHostedCheckoutV3ExistingOrderProps(hostedCheckoutProps)) {
return t("hostedCheckoutV3.crossmint", locale);
}
throw new Error("Neither `payment.crypto.enabled` or `payment.fiat.enabled` is true");
})();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@ export interface CrossmintHostedCheckoutV3Props {
metadata?: JSONObject;
}

export interface CrossmintHostedCheckoutV3OrderProps {
orderId: string;
clientSecret: string;
locale?: Locale;
payment?: Omit<HostedCheckoutV3Payment, "fiat" | "crypto"> & {
fiat?: HostedCheckoutV3FiatPayment;
crypto?: HostedCheckoutV3CryptoPayment;
};
appearance?: CrossmintHostedCheckoutV3Appearance;
}

export type CrossmintHostedCheckoutV3AllProps = CrossmintHostedCheckoutV3Props | CrossmintHostedCheckoutV3OrderProps;

export function isHostedCheckoutV3ExistingOrderProps(
props: CrossmintHostedCheckoutV3AllProps
): props is CrossmintHostedCheckoutV3OrderProps {
return "orderId" in props && props.orderId != null;
}

export type HostedCheckoutV3Payment = {
receiptEmail?: string;
fiat: HostedCheckoutV3FiatPayment;
Expand Down
Loading
Loading