From 4ab93e0db85b7b63afeb5b9093163bf12b794124 Mon Sep 17 00:00:00 2001 From: Alberto <146016735+alberto-crossmint@users.noreply.github.com> Date: Tue, 28 Oct 2025 05:51:55 -0400 Subject: [PATCH 01/15] Wallets: Multi-wallet support (#1455) * Multi wallet support * undo * fixbuild * praction * fmt * openapi * addChangeset --- .changeset/fuzzy-panthers-prove.md | 7 + .../quickstart-devkit/app/providers.tsx | 173 +++++++++++++++--- .../quickstart-devkit/e2e/config/constants.ts | 12 +- .../providers/CrossmintWalletBaseProvider.tsx | 1 + .../client/react-base/src/types/wallet.ts | 3 + packages/wallets/src/wallets/evm.ts | 1 + packages/wallets/src/wallets/solana.ts | 1 + packages/wallets/src/wallets/stellar.ts | 1 + packages/wallets/src/wallets/types.ts | 1 + .../wallets/src/wallets/wallet-factory.ts | 10 +- packages/wallets/src/wallets/wallet.ts | 24 ++- 11 files changed, 198 insertions(+), 36 deletions(-) create mode 100644 .changeset/fuzzy-panthers-prove.md diff --git a/.changeset/fuzzy-panthers-prove.md b/.changeset/fuzzy-panthers-prove.md new file mode 100644 index 000000000..9ea1d0b87 --- /dev/null +++ b/.changeset/fuzzy-panthers-prove.md @@ -0,0 +1,7 @@ +--- +"@crossmint/wallets-quickstart-devkit": minor +"@crossmint/client-sdk-react-base": minor +"@crossmint/wallets-sdk": minor +--- + +Add wallet aliasing diff --git a/apps/wallets/quickstart-devkit/app/providers.tsx b/apps/wallets/quickstart-devkit/app/providers.tsx index 18cf0c734..e51f9cb54 100644 --- a/apps/wallets/quickstart-devkit/app/providers.tsx +++ b/apps/wallets/quickstart-devkit/app/providers.tsx @@ -8,6 +8,13 @@ import { SolanaWalletConnectors } from "@dynamic-labs/solana"; import { PrivyProvider } from "@privy-io/react-auth"; import { useSearchParams } from "next/navigation"; +const ALIAS_CONFIG = + process.env.NEXT_PUBLIC_WALLET_ALIAS != null + ? { + alias: process.env.NEXT_PUBLIC_WALLET_ALIAS, + } + : {}; + const crossmintApiKey = process.env.NEXT_PUBLIC_CROSSMINT_API_KEY ?? ""; if (!crossmintApiKey) { throw new Error("NEXT_PUBLIC_CROSSMINT_API_KEY is not set"); @@ -32,7 +39,11 @@ function EVMCrossmintAuthProvider({ children, apiKey, createOnLogin, -}: { children: React.ReactNode; apiKey?: string; createOnLogin?: any }) { +}: { + children: React.ReactNode; + apiKey?: string; + createOnLogin?: any; +}) { if (!process.env.NEXT_PUBLIC_EVM_CHAIN) { console.error("NEXT_PUBLIC_EVM_CHAIN is not set"); return; @@ -49,7 +60,11 @@ function EVMCrossmintAuthProvider({ createOnLogin={ createOnLogin != null ? createOnLogin - : { chain: process.env.NEXT_PUBLIC_EVM_CHAIN as any, signer: { type: "email" } } + : { + chain: process.env.NEXT_PUBLIC_EVM_CHAIN as any, + signer: { type: "email" }, + ...ALIAS_CONFIG, + } } > {children} @@ -59,7 +74,13 @@ function EVMCrossmintAuthProvider({ ); } -function EVMPrivyProvider({ children, apiKey }: { children: React.ReactNode; apiKey?: string }) { +function EVMPrivyProvider({ + children, + apiKey, +}: { + children: React.ReactNode; + apiKey?: string; +}) { if (!process.env.NEXT_PUBLIC_PRIVY_APP_ID) { throw new Error("NEXT_PUBLIC_PRIVY_APP_ID is not set"); } @@ -81,6 +102,7 @@ function EVMPrivyProvider({ children, apiKey }: { children: React.ReactNode; api createOnLogin={{ chain: process.env.NEXT_PUBLIC_EVM_CHAIN as any, signer: { type: "email" }, + ...ALIAS_CONFIG, }} > {children} @@ -90,7 +112,13 @@ function EVMPrivyProvider({ children, apiKey }: { children: React.ReactNode; api ); } -function EVMDynamicLabsProvider({ children, apiKey }: { children: React.ReactNode; apiKey?: string }) { +function EVMDynamicLabsProvider({ + children, + apiKey, +}: { + children: React.ReactNode; + apiKey?: string; +}) { if (!process.env.NEXT_PUBLIC_DYNAMIC_ENV_ID) { throw new Error("NEXT_PUBLIC_DYNAMIC_ENV_ID is not set"); } @@ -108,7 +136,13 @@ function EVMDynamicLabsProvider({ children, apiKey }: { children: React.ReactNod ); } -function EVMFirebaseProvider({ children, apiKey }: { children: React.ReactNode; apiKey?: string }) { +function EVMFirebaseProvider({ + children, + apiKey, +}: { + children: React.ReactNode; + apiKey?: string; +}) { if (!process.env.NEXT_PUBLIC_FIREBASE_API_KEY) { console.error("Make sure to set all firebase .env vars for Firebase BYOA"); return; @@ -116,7 +150,11 @@ function EVMFirebaseProvider({ children, apiKey }: { children: React.ReactNode; return ( {children} @@ -131,7 +169,11 @@ function SolanaCrossmintAuthProvider({ children, apiKey, createOnLogin, -}: { children: React.ReactNode; apiKey?: string; createOnLogin?: any }) { +}: { + children: React.ReactNode; + apiKey?: string; + createOnLogin?: any; +}) { return ( {children} @@ -151,7 +199,13 @@ function SolanaCrossmintAuthProvider({ ); } -function SolanaPrivyProvider({ children, apiKey }: { children: React.ReactNode; apiKey?: string }) { +function SolanaPrivyProvider({ + children, + apiKey, +}: { + children: React.ReactNode; + apiKey?: string; +}) { if (!process.env.NEXT_PUBLIC_PRIVY_APP_ID) { throw new Error("NEXT_PUBLIC_PRIVY_APP_ID is not set"); } @@ -170,7 +224,11 @@ function SolanaPrivyProvider({ children, apiKey }: { children: React.ReactNode; {children} @@ -197,7 +255,13 @@ function SolanaDynamicLabsProvider({ }} > - + {children} @@ -205,17 +269,37 @@ function SolanaDynamicLabsProvider({ ); } -function SolanaFirebaseProvider({ children, apiKey }: { children: React.ReactNode; apiKey?: string }) { +function SolanaFirebaseProvider({ + children, + apiKey, +}: { + children: React.ReactNode; + apiKey?: string; +}) { return ( - + {children} ); } -function StellarCrossmintAuthProvider({ children, apiKey }: { children: React.ReactNode; apiKey?: string }) { +function StellarCrossmintAuthProvider({ + children, + apiKey, + createOnLogin, +}: { + children: React.ReactNode; + apiKey?: string; + createOnLogin?: any; +}) { return ( {children} @@ -250,6 +341,7 @@ function QueryParamsProvider({ children }: { children: React.ReactNode }) { const chainId = searchParams.get("chainId") || process.env.NEXT_PUBLIC_EVM_CHAIN; const phoneNumber = searchParams.get("phoneNumber"); const crossmintApiKey = searchParams.get("crossmintApiKey") || undefined; + const alias = searchParams.get("alias") || undefined; if (chainType === "evm") { switch (providerType) { @@ -261,9 +353,16 @@ function QueryParamsProvider({ children }: { children: React.ReactNode }) { return {children}; case "crossmint": default: - const createOnLogin: any = { chain: chainId, signer: { type: signerType } }; + const createOnLogin: any = { + chain: chainId, + signer: { type: signerType }, + ...(alias != null ? { alias } : {}), + }; if (signerType === "phone" && phoneNumber != null) { - createOnLogin.signer = { type: signerType, phone: decodeURIComponent(phoneNumber) }; + createOnLogin.signer = { + type: signerType, + phone: decodeURIComponent(phoneNumber), + }; } return ( @@ -281,9 +380,16 @@ function QueryParamsProvider({ children }: { children: React.ReactNode }) { return {children}; case "crossmint": default: - const createOnLogin: any = { chain: "solana", signer: { type: signerType } }; + const createOnLogin: any = { + chain: "solana", + signer: { type: signerType }, + ...(alias != null ? { alias } : {}), + }; if (signerType === "phone" && phoneNumber != null) { - createOnLogin.signer = { type: signerType, phone: decodeURIComponent(phoneNumber) }; + createOnLogin.signer = { + type: signerType, + phone: decodeURIComponent(phoneNumber), + }; } return ( @@ -292,7 +398,22 @@ function QueryParamsProvider({ children }: { children: React.ReactNode }) { ); } } else if (chainType === "stellar") { - return {children}; + const createOnLogin: any = { + chain: "stellar", + signer: { type: signerType }, + ...(alias != null ? { alias } : {}), + }; + if (signerType === "phone" && phoneNumber != null) { + createOnLogin.signer = { + type: signerType, + phone: decodeURIComponent(phoneNumber), + }; + } + return ( + + {children} + + ); } return {children}; diff --git a/apps/wallets/quickstart-devkit/e2e/config/constants.ts b/apps/wallets/quickstart-devkit/e2e/config/constants.ts index a610a3e13..e367e3f72 100644 --- a/apps/wallets/quickstart-devkit/e2e/config/constants.ts +++ b/apps/wallets/quickstart-devkit/e2e/config/constants.ts @@ -24,23 +24,27 @@ if ( // Test configurations for different provider/chain/signer combinations export const TEST_CONFIGURATIONS = [ // EVM Configurations - { provider: "crossmint", chain: "evm", signer: "email", chainId: "optimism-sepolia" }, + { provider: "crossmint", chain: "evm", signer: "email", chainId: "optimism-sepolia", alias: undefined }, { provider: "crossmint", chain: "evm", signer: "phone", chainId: "optimism-sepolia", phoneNumber: AUTH_CONFIG.mailosaurPhoneNumber, + alias: undefined, }, // Solana Configurations - { provider: "crossmint", chain: "solana", signer: "email", chainId: "solana" }, + { provider: "crossmint", chain: "solana", signer: "email", chainId: "solana", alias: undefined }, { provider: "crossmint", chain: "solana", signer: "phone", chainId: "solana", phoneNumber: AUTH_CONFIG.mailosaurPhoneNumber, + alias: undefined, }, + // Stellar Configurations + { provider: "crossmint", chain: "stellar", signer: "email", chainId: "stellar", alias: "stellartestingwallet" }, ] as const; export type TestConfiguration = (typeof TEST_CONFIGURATIONS)[number]; @@ -65,6 +69,7 @@ export const SIGNER_EMAIL_MAPPING: Record = { export const TEST_RECIPIENT_WALLET_ADDRESSES = { evm: "0xDF8b5F9c19E187f1Ea00730a1e46180152244315", solana: "AsBWK4STzydYZHvacHFuFSSongkeBzZx7Bk8rCbDeH4d", + stellar: "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF", }; // Generate email address for a specific signer type @@ -84,5 +89,8 @@ export function buildTestUrl(config: TestConfiguration): string { if (config.signer === "phone" && config.phoneNumber != null) { url.searchParams.set("phoneNumber", config.phoneNumber); } + if (config.alias != null) { + url.searchParams.set("alias", config.alias); + } return url.toString(); } diff --git a/packages/client/react-base/src/providers/CrossmintWalletBaseProvider.tsx b/packages/client/react-base/src/providers/CrossmintWalletBaseProvider.tsx index 33b32333a..400914da1 100644 --- a/packages/client/react-base/src/providers/CrossmintWalletBaseProvider.tsx +++ b/packages/client/react-base/src/providers/CrossmintWalletBaseProvider.tsx @@ -125,6 +125,7 @@ export function CrossmintWalletBaseProvider({ owner: args.owner, plugins: args.plugins, delegatedSigners: args.delegatedSigners, + alias: args.alias, options: { clientTEEConnection: clientTEEConnection?.(), experimental_callbacks: { diff --git a/packages/client/react-base/src/types/wallet.ts b/packages/client/react-base/src/types/wallet.ts index ba052f77b..682fe8310 100644 --- a/packages/client/react-base/src/types/wallet.ts +++ b/packages/client/react-base/src/types/wallet.ts @@ -27,6 +27,7 @@ export type CreateOnLogin = owner?: string; plugins?: WalletPlugin[]; delegatedSigners?: Array; + alias?: string; } | { chain: EVMChain; @@ -34,6 +35,7 @@ export type CreateOnLogin = owner?: string; plugins?: WalletPlugin[]; delegatedSigners?: Array; + alias?: string; } | { chain: StellarChain; @@ -41,6 +43,7 @@ export type CreateOnLogin = owner?: string; plugins?: WalletPlugin[]; delegatedSigners?: Array; + alias?: string; }; export type BaseCrossmintWalletProviderProps = { diff --git a/packages/wallets/src/wallets/evm.ts b/packages/wallets/src/wallets/evm.ts index f6a18cf6d..73553fbfa 100644 --- a/packages/wallets/src/wallets/evm.ts +++ b/packages/wallets/src/wallets/evm.ts @@ -25,6 +25,7 @@ export class EVMWallet extends Wallet { owner: wallet.owner, signer: wallet.signer, options: Wallet.getOptions(wallet), + alias: wallet.alias, }, Wallet.getApiClient(wallet) ); diff --git a/packages/wallets/src/wallets/solana.ts b/packages/wallets/src/wallets/solana.ts index 79f884b50..a0f78f8c9 100644 --- a/packages/wallets/src/wallets/solana.ts +++ b/packages/wallets/src/wallets/solana.ts @@ -22,6 +22,7 @@ export class SolanaWallet extends Wallet { owner: wallet.owner, signer: wallet.signer, options: Wallet.getOptions(wallet), + alias: wallet.alias, }, Wallet.getApiClient(wallet) ); diff --git a/packages/wallets/src/wallets/stellar.ts b/packages/wallets/src/wallets/stellar.ts index e7d9d1c55..deafc9c69 100644 --- a/packages/wallets/src/wallets/stellar.ts +++ b/packages/wallets/src/wallets/stellar.ts @@ -20,6 +20,7 @@ export class StellarWallet extends Wallet { owner: wallet.owner, signer: wallet.signer, options: Wallet.getOptions(wallet), + alias: wallet.alias, }, Wallet.getApiClient(wallet) ); diff --git a/packages/wallets/src/wallets/types.ts b/packages/wallets/src/wallets/types.ts index a522a810b..0ddbf10b3 100644 --- a/packages/wallets/src/wallets/types.ts +++ b/packages/wallets/src/wallets/types.ts @@ -121,6 +121,7 @@ export type WalletArgsFor = { plugins?: WalletPlugin[]; options?: WalletOptions; delegatedSigners?: Array; + alias?: string; }; type ChainExtras = { diff --git a/packages/wallets/src/wallets/wallet-factory.ts b/packages/wallets/src/wallets/wallet-factory.ts index bf7d7b7de..07066693f 100644 --- a/packages/wallets/src/wallets/wallet-factory.ts +++ b/packages/wallets/src/wallets/wallet-factory.ts @@ -29,7 +29,9 @@ export class WalletFactory { ); } - const existingWallet = await this.apiClient.getWallet(`me:${this.getChainType(args.chain)}:smart`); + const locator = this.getWalletLocator(args); + + const existingWallet = await this.apiClient.getWallet(locator); if (existingWallet != null && !("error" in existingWallet)) { return this.createWalletInstance(existingWallet, args); @@ -68,6 +70,7 @@ export class WalletFactory { ...(args.delegatedSigners != null ? { delegatedSigners: args.delegatedSigners } : {}), }, owner: args.owner ?? undefined, + alias: args.alias ?? undefined, } as CreateWalletParams); if ("error" in walletResponse) { @@ -91,6 +94,7 @@ export class WalletFactory { owner: walletResponse.owner, signer: assembleSigner(args.chain, signerConfig), options: args.options, + alias: args.alias, }, this.apiClient ); @@ -188,6 +192,10 @@ export class WalletFactory { } } + private getWalletLocator(args: WalletArgsFor): string { + return `me:${this.getChainType(args.chain)}:smart` + (args.alias != null ? `:alias:${args.alias}` : ""); + } + private async createPasskeyAdminSigner( signer: SignerConfigForChain ): Promise { diff --git a/packages/wallets/src/wallets/wallet.ts b/packages/wallets/src/wallets/wallet.ts index c5e81d552..d701f6fb4 100644 --- a/packages/wallets/src/wallets/wallet.ts +++ b/packages/wallets/src/wallets/wallet.ts @@ -50,6 +50,7 @@ type WalletContructorType = { chain: C; address: string; owner?: string; + alias?: string; signer: Signer; options?: WalletOptions; }; @@ -58,18 +59,20 @@ export class Wallet { chain: C; address: string; owner?: string; + alias?: string; signer: Signer; #options?: WalletOptions; #apiClient: ApiClient; constructor(args: WalletContructorType, apiClient: ApiClient) { - const { chain, address, owner, signer, options } = args; + const { chain, address, owner, signer, options, alias } = args; this.#apiClient = apiClient; this.chain = chain; this.address = address; this.owner = owner; this.signer = signer; this.#options = options; + this.alias = alias; } protected static getApiClient(wallet: Wallet): ApiClient { @@ -429,13 +432,20 @@ export class Wallet { if (this.#apiClient.isServerSide) { return this.address; } else { - if (this.chain === "stellar") { - return `me:stellar:smart`; - } else if (this.chain === "solana") { - return `me:solana:smart`; - } else { - return `me:evm:smart`; + let baseLocator: string; + switch (this.chain) { + case "stellar": + baseLocator = `me:stellar:smart`; + break; + case "solana": + baseLocator = `me:solana:smart`; + break; + default: + baseLocator = `me:evm:smart`; + break; } + const aliasLocatorPart = this.alias != null ? `:alias:${this.alias}` : ""; + return baseLocator + aliasLocatorPart; } } From 1b070697e83d6ac89979e155f54b30a1170792a3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 28 Oct 2025 11:09:23 +0100 Subject: [PATCH 02/15] Release packages (#1467) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/fuzzy-panthers-prove.md | 7 ------- apps/auth/nextjs-ssr/CHANGELOG.md | 6 ++++++ apps/auth/nextjs-ssr/package.json | 2 +- apps/payments/nextjs/CHANGELOG.md | 6 ++++++ apps/payments/nextjs/package.json | 2 +- apps/wallets/quickstart-devkit/CHANGELOG.md | 10 ++++++++++ apps/wallets/quickstart-devkit/package.json | 2 +- apps/wallets/smart-wallet/expo/CHANGELOG.md | 8 ++++++++ apps/wallets/smart-wallet/expo/package.json | 2 +- apps/wallets/smart-wallet/next/CHANGELOG.md | 6 ++++++ apps/wallets/smart-wallet/next/package.json | 2 +- packages/client/react-base/CHANGELOG.md | 11 +++++++++++ packages/client/react-base/package.json | 2 +- packages/client/ui/react-native/CHANGELOG.md | 8 ++++++++ packages/client/ui/react-native/package.json | 2 +- packages/client/ui/react-ui/CHANGELOG.md | 8 ++++++++ packages/client/ui/react-ui/package.json | 2 +- packages/wallets/CHANGELOG.md | 6 ++++++ packages/wallets/package.json | 2 +- 19 files changed, 78 insertions(+), 16 deletions(-) delete mode 100644 .changeset/fuzzy-panthers-prove.md diff --git a/.changeset/fuzzy-panthers-prove.md b/.changeset/fuzzy-panthers-prove.md deleted file mode 100644 index 9ea1d0b87..000000000 --- a/.changeset/fuzzy-panthers-prove.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@crossmint/wallets-quickstart-devkit": minor -"@crossmint/client-sdk-react-base": minor -"@crossmint/wallets-sdk": minor ---- - -Add wallet aliasing diff --git a/apps/auth/nextjs-ssr/CHANGELOG.md b/apps/auth/nextjs-ssr/CHANGELOG.md index 322425121..4db051dc3 100644 --- a/apps/auth/nextjs-ssr/CHANGELOG.md +++ b/apps/auth/nextjs-ssr/CHANGELOG.md @@ -1,5 +1,11 @@ # @crossmint/server-sdk-next-starter +## 0.4.130 + +### Patch Changes + +- @crossmint/client-sdk-react-ui@2.5.11 + ## 0.4.129 ### Patch Changes diff --git a/apps/auth/nextjs-ssr/package.json b/apps/auth/nextjs-ssr/package.json index f2dc66b43..f8cfacba6 100644 --- a/apps/auth/nextjs-ssr/package.json +++ b/apps/auth/nextjs-ssr/package.json @@ -1,6 +1,6 @@ { "name": "@crossmint/auth-ssr-nextjs-demo", - "version": "0.4.129", + "version": "0.4.130", "private": true, "scripts": { "dev": "next dev", diff --git a/apps/payments/nextjs/CHANGELOG.md b/apps/payments/nextjs/CHANGELOG.md index 9c683d685..ffae26ee0 100644 --- a/apps/payments/nextjs/CHANGELOG.md +++ b/apps/payments/nextjs/CHANGELOG.md @@ -1,5 +1,11 @@ # @crossmint/client-sdk-nextjs-starter +## 1.5.26 + +### Patch Changes + +- @crossmint/client-sdk-react-ui@2.5.11 + ## 1.5.25 ### Patch Changes diff --git a/apps/payments/nextjs/package.json b/apps/payments/nextjs/package.json index 35f45b8ce..6050bf5da 100644 --- a/apps/payments/nextjs/package.json +++ b/apps/payments/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@crossmint/client-sdk-nextjs-starter", - "version": "1.5.25", + "version": "1.5.26", "private": true, "repository": "https://github.com/Crossmint/crossmint-sdk", "license": "Apache-2.0", diff --git a/apps/wallets/quickstart-devkit/CHANGELOG.md b/apps/wallets/quickstart-devkit/CHANGELOG.md index a9dca9a47..b8403f7f0 100644 --- a/apps/wallets/quickstart-devkit/CHANGELOG.md +++ b/apps/wallets/quickstart-devkit/CHANGELOG.md @@ -1,5 +1,15 @@ # @crossmint/wallets-quickstart-devkit +## 0.2.0 + +### Minor Changes + +- 4ab93e0: Add wallet aliasing + +### Patch Changes + +- @crossmint/client-sdk-react-ui@2.5.11 + ## 0.1.72 ### Patch Changes diff --git a/apps/wallets/quickstart-devkit/package.json b/apps/wallets/quickstart-devkit/package.json index 50c7d32cd..4bcaec327 100644 --- a/apps/wallets/quickstart-devkit/package.json +++ b/apps/wallets/quickstart-devkit/package.json @@ -1,6 +1,6 @@ { "name": "@crossmint/wallets-quickstart-devkit", - "version": "0.1.72", + "version": "0.2.0", "private": true, "scripts": { "dev": "next dev --turbopack", diff --git a/apps/wallets/smart-wallet/expo/CHANGELOG.md b/apps/wallets/smart-wallet/expo/CHANGELOG.md index 111a709cb..48dbc898c 100644 --- a/apps/wallets/smart-wallet/expo/CHANGELOG.md +++ b/apps/wallets/smart-wallet/expo/CHANGELOG.md @@ -1,5 +1,13 @@ # expo-demo +## 1.1.98 + +### Patch Changes + +- Updated dependencies [4ab93e0] + - @crossmint/wallets-sdk@0.17.0 + - @crossmint/client-sdk-react-native-ui@0.11.13 + ## 1.1.97 ### Patch Changes diff --git a/apps/wallets/smart-wallet/expo/package.json b/apps/wallets/smart-wallet/expo/package.json index 175062fbf..30cc808d9 100644 --- a/apps/wallets/smart-wallet/expo/package.json +++ b/apps/wallets/smart-wallet/expo/package.json @@ -1,7 +1,7 @@ { "name": "expo-demo", "main": "expo-router/entry", - "version": "1.1.97", + "version": "1.1.98", "scripts": { "start": "expo start", "reset-project": "node ./scripts/reset-project.js", diff --git a/apps/wallets/smart-wallet/next/CHANGELOG.md b/apps/wallets/smart-wallet/next/CHANGELOG.md index 58a9d36bb..0cc03cdbe 100644 --- a/apps/wallets/smart-wallet/next/CHANGELOG.md +++ b/apps/wallets/smart-wallet/next/CHANGELOG.md @@ -1,5 +1,11 @@ # @crossmint/client-sdk-smart-wallet-next-starter +## 0.1.184 + +### Patch Changes + +- @crossmint/client-sdk-react-ui@2.5.11 + ## 0.1.183 ### Patch Changes diff --git a/apps/wallets/smart-wallet/next/package.json b/apps/wallets/smart-wallet/next/package.json index 1ec493da2..61221478c 100644 --- a/apps/wallets/smart-wallet/next/package.json +++ b/apps/wallets/smart-wallet/next/package.json @@ -1,6 +1,6 @@ { "name": "@crossmint/client-sdk-smart-wallet-next-starter", - "version": "0.1.183", + "version": "0.1.184", "private": true, "scripts": { "build": "next build", diff --git a/packages/client/react-base/CHANGELOG.md b/packages/client/react-base/CHANGELOG.md index 926963541..2ac27317d 100644 --- a/packages/client/react-base/CHANGELOG.md +++ b/packages/client/react-base/CHANGELOG.md @@ -1,5 +1,16 @@ # @crossmint/client-sdk-react-base +## 0.7.0 + +### Minor Changes + +- 4ab93e0: Add wallet aliasing + +### Patch Changes + +- Updated dependencies [4ab93e0] + - @crossmint/wallets-sdk@0.17.0 + ## 0.6.9 ### Patch Changes diff --git a/packages/client/react-base/package.json b/packages/client/react-base/package.json index b20d3cdde..34e2cff65 100644 --- a/packages/client/react-base/package.json +++ b/packages/client/react-base/package.json @@ -1,6 +1,6 @@ { "name": "@crossmint/client-sdk-react-base", - "version": "0.6.9", + "version": "0.7.0", "repository": "https://github.com/Crossmint/crossmint-sdk", "license": "Apache-2.0", "author": "Paella Labs Inc", diff --git a/packages/client/ui/react-native/CHANGELOG.md b/packages/client/ui/react-native/CHANGELOG.md index 6a2e7146c..481a4d32d 100644 --- a/packages/client/ui/react-native/CHANGELOG.md +++ b/packages/client/ui/react-native/CHANGELOG.md @@ -1,5 +1,13 @@ # @crossmint/client-sdk-react-native-ui +## 0.11.13 + +### Patch Changes + +- Updated dependencies [4ab93e0] + - @crossmint/client-sdk-react-base@0.7.0 + - @crossmint/wallets-sdk@0.17.0 + ## 0.11.12 ### Patch Changes diff --git a/packages/client/ui/react-native/package.json b/packages/client/ui/react-native/package.json index 2ba4e90b4..ff68e5043 100644 --- a/packages/client/ui/react-native/package.json +++ b/packages/client/ui/react-native/package.json @@ -1,6 +1,6 @@ { "name": "@crossmint/client-sdk-react-native-ui", - "version": "0.11.12", + "version": "0.11.13", "repository": "https://github.com/Crossmint/crossmint-sdk", "license": "Apache-2.0", "author": "Paella Labs Inc", diff --git a/packages/client/ui/react-ui/CHANGELOG.md b/packages/client/ui/react-ui/CHANGELOG.md index 4668e0cb1..d1d96119e 100644 --- a/packages/client/ui/react-ui/CHANGELOG.md +++ b/packages/client/ui/react-ui/CHANGELOG.md @@ -1,5 +1,13 @@ # @crossmint/client-sdk-react-ui +## 2.5.11 + +### Patch Changes + +- Updated dependencies [4ab93e0] + - @crossmint/client-sdk-react-base@0.7.0 + - @crossmint/wallets-sdk@0.17.0 + ## 2.5.10 ### Patch Changes diff --git a/packages/client/ui/react-ui/package.json b/packages/client/ui/react-ui/package.json index cc0e8675d..7dab9f14e 100644 --- a/packages/client/ui/react-ui/package.json +++ b/packages/client/ui/react-ui/package.json @@ -1,6 +1,6 @@ { "name": "@crossmint/client-sdk-react-ui", - "version": "2.5.10", + "version": "2.5.11", "repository": "https://github.com/Crossmint/crossmint-sdk", "license": "Apache-2.0", "author": "Paella Labs Inc", diff --git a/packages/wallets/CHANGELOG.md b/packages/wallets/CHANGELOG.md index 1d50260c8..8ef62ac29 100644 --- a/packages/wallets/CHANGELOG.md +++ b/packages/wallets/CHANGELOG.md @@ -1,5 +1,11 @@ # @crossmint/wallets-sdk +## 0.17.0 + +### Minor Changes + +- 4ab93e0: Add wallet aliasing + ## 0.16.2 ### Patch Changes diff --git a/packages/wallets/package.json b/packages/wallets/package.json index a06e43a74..1eeaface2 100644 --- a/packages/wallets/package.json +++ b/packages/wallets/package.json @@ -1,6 +1,6 @@ { "name": "@crossmint/wallets-sdk", - "version": "0.16.2", + "version": "0.17.0", "repository": "https://github.com/Crossmint/crossmint-sdk", "license": "Apache-2.0", "author": "Paella Labs Inc", From 7a1f5ca31ecf91549de953096957b57684423f9a Mon Sep 17 00:00:00 2001 From: guilleasz-crossmint <162112912+guilleasz-crossmint@users.noreply.github.com> Date: Tue, 28 Oct 2025 15:53:00 +0100 Subject: [PATCH 03/15] react-ui: remove aspect-ratio from submit button (#1466) * remove aspect-ratio for submit button * add changeset --- .changeset/tiny-badgers-stare.md | 5 +++++ .../src/components/auth/methods/email/EmailSignIn.tsx | 1 - .../ui/react-ui/src/components/signers/BaseCodeInput.tsx | 1 - 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 .changeset/tiny-badgers-stare.md diff --git a/.changeset/tiny-badgers-stare.md b/.changeset/tiny-badgers-stare.md new file mode 100644 index 000000000..bb0ae9344 --- /dev/null +++ b/.changeset/tiny-badgers-stare.md @@ -0,0 +1,5 @@ +--- +"@crossmint/client-sdk-react-ui": patch +--- + +Fix Submit button display for Firefox in Login and Verify OTP diff --git a/packages/client/ui/react-ui/src/components/auth/methods/email/EmailSignIn.tsx b/packages/client/ui/react-ui/src/components/auth/methods/email/EmailSignIn.tsx index 310946636..5479aa800 100644 --- a/packages/client/ui/react-ui/src/components/auth/methods/email/EmailSignIn.tsx +++ b/packages/client/ui/react-ui/src/components/auth/methods/email/EmailSignIn.tsx @@ -89,7 +89,6 @@ const InputActions = styled.div` display: flex; align-items: center; padding-right: 16px; - aspect-ratio: 1/1; `; const SubmitButton = styled.button<{ diff --git a/packages/client/ui/react-ui/src/components/signers/BaseCodeInput.tsx b/packages/client/ui/react-ui/src/components/signers/BaseCodeInput.tsx index 9f5db3f5f..f93259edd 100644 --- a/packages/client/ui/react-ui/src/components/signers/BaseCodeInput.tsx +++ b/packages/client/ui/react-ui/src/components/signers/BaseCodeInput.tsx @@ -106,7 +106,6 @@ const InputActions = styled.div` display: flex; align-items: center; padding-right: 16px; - aspect-ratio: 1/1; `; const SubmitButton = styled.button<{ From 958671fbcb3984ef114f8d19001b1ce6711f53f7 Mon Sep 17 00:00:00 2001 From: mPaella <93682696+mPaella@users.noreply.github.com> Date: Tue, 28 Oct 2025 17:11:51 -0400 Subject: [PATCH 04/15] saved cards: pt 1 (#1471) * save * layout --- apps/payments/nextjs/app/layout.tsx | 16 +++++ .../components/AuthButton.tsx | 26 ++++++++ .../components/ClientProviders.tsx | 12 ++++ .../app/payment-method-management/page.tsx | 24 +++++++ apps/payments/nextjs/next-env.d.ts | 3 +- packages/client/base/src/services/index.ts | 1 + .../payment-method-management/index.ts | 1 + .../paymentMethodManagementService.ts | 40 ++++++++++++ packages/client/base/src/types/index.ts | 1 + .../CrossmintPaymentMethodManagementProps.ts | 3 + .../PaymentMethodManagementIFrameEmitter.ts | 9 +++ .../events/incoming.ts | 8 +++ .../payment-method-management/events/index.ts | 4 ++ .../events/outgoing.ts | 2 + .../types/payment-method-management/index.ts | 3 + .../CrossmintPaymentMethodManagement.tsx | 6 ++ ...CrossmintPaymentMethodManagementIFrame.tsx | 65 +++++++++++++++++++ .../src/components/card-management/index.ts | 1 + .../ui/react-ui/src/components/index.ts | 1 + 19 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 apps/payments/nextjs/app/layout.tsx create mode 100644 apps/payments/nextjs/app/payment-method-management/components/AuthButton.tsx create mode 100644 apps/payments/nextjs/app/payment-method-management/components/ClientProviders.tsx create mode 100644 apps/payments/nextjs/app/payment-method-management/page.tsx create mode 100644 packages/client/base/src/services/payment-method-management/index.ts create mode 100644 packages/client/base/src/services/payment-method-management/paymentMethodManagementService.ts create mode 100644 packages/client/base/src/types/payment-method-management/CrossmintPaymentMethodManagementProps.ts create mode 100644 packages/client/base/src/types/payment-method-management/events/PaymentMethodManagementIFrameEmitter.ts create mode 100644 packages/client/base/src/types/payment-method-management/events/incoming.ts create mode 100644 packages/client/base/src/types/payment-method-management/events/index.ts create mode 100644 packages/client/base/src/types/payment-method-management/events/outgoing.ts create mode 100644 packages/client/base/src/types/payment-method-management/index.ts create mode 100644 packages/client/ui/react-ui/src/components/card-management/CrossmintPaymentMethodManagement.tsx create mode 100644 packages/client/ui/react-ui/src/components/card-management/CrossmintPaymentMethodManagementIFrame.tsx create mode 100644 packages/client/ui/react-ui/src/components/card-management/index.ts diff --git a/apps/payments/nextjs/app/layout.tsx b/apps/payments/nextjs/app/layout.tsx new file mode 100644 index 000000000..aa05c58a1 --- /dev/null +++ b/apps/payments/nextjs/app/layout.tsx @@ -0,0 +1,16 @@ +export const metadata = { + title: "Next.js", + description: "Generated by Next.js", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/apps/payments/nextjs/app/payment-method-management/components/AuthButton.tsx b/apps/payments/nextjs/app/payment-method-management/components/AuthButton.tsx new file mode 100644 index 000000000..0f5a8a812 --- /dev/null +++ b/apps/payments/nextjs/app/payment-method-management/components/AuthButton.tsx @@ -0,0 +1,26 @@ +"use client"; + +import { useAuth } from "@crossmint/client-sdk-react-ui"; + +export function AuthButton() { + const { login, logout, user } = useAuth(); + + return ( +
+ {user == null ? ( + + ) : ( + + )} +

User ID: {user?.id}

+
+ ); +} diff --git a/apps/payments/nextjs/app/payment-method-management/components/ClientProviders.tsx b/apps/payments/nextjs/app/payment-method-management/components/ClientProviders.tsx new file mode 100644 index 000000000..c6cdc6dc3 --- /dev/null +++ b/apps/payments/nextjs/app/payment-method-management/components/ClientProviders.tsx @@ -0,0 +1,12 @@ +"use client"; + +import { CrossmintAuthProvider } from "@crossmint/client-sdk-react-ui"; +import { CrossmintProvider } from "@crossmint/client-sdk-react-ui"; + +export function ClientProviders({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} diff --git a/apps/payments/nextjs/app/payment-method-management/page.tsx b/apps/payments/nextjs/app/payment-method-management/page.tsx new file mode 100644 index 000000000..2ced1cd85 --- /dev/null +++ b/apps/payments/nextjs/app/payment-method-management/page.tsx @@ -0,0 +1,24 @@ +"use client"; + +import { ClientProviders } from "./components/ClientProviders"; +import { AuthButton } from "./components/AuthButton"; +import { useCrossmintAuth, CrossmintPaymentMethodManagement } from "@crossmint/client-sdk-react-ui"; + +export default function PaymentMethodManagementPage() { + return ( + + + + + ); +} + +function PaymentMethodManagementWrapper() { + const { jwt } = useCrossmintAuth(); + + if (jwt == null) { + return
Please login to continue
; + } + + return ; +} diff --git a/apps/payments/nextjs/next-env.d.ts b/apps/payments/nextjs/next-env.d.ts index a4a7b3f5c..725dd6f24 100644 --- a/apps/payments/nextjs/next-env.d.ts +++ b/apps/payments/nextjs/next-env.d.ts @@ -1,5 +1,6 @@ /// /// +/// // NOTE: This file should not be edited -// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/packages/client/base/src/services/index.ts b/packages/client/base/src/services/index.ts index 97479caa4..958442374 100644 --- a/packages/client/base/src/services/index.ts +++ b/packages/client/base/src/services/index.ts @@ -1,5 +1,6 @@ export * from "./embed"; export * from "./hosted"; +export * from "./payment-method-management"; export * from "./api"; export * from "./logging"; diff --git a/packages/client/base/src/services/payment-method-management/index.ts b/packages/client/base/src/services/payment-method-management/index.ts new file mode 100644 index 000000000..9371a42f6 --- /dev/null +++ b/packages/client/base/src/services/payment-method-management/index.ts @@ -0,0 +1 @@ +export * from "./paymentMethodManagementService"; diff --git a/packages/client/base/src/services/payment-method-management/paymentMethodManagementService.ts b/packages/client/base/src/services/payment-method-management/paymentMethodManagementService.ts new file mode 100644 index 000000000..58597c6dc --- /dev/null +++ b/packages/client/base/src/services/payment-method-management/paymentMethodManagementService.ts @@ -0,0 +1,40 @@ +import type { CrossmintPaymentMethodManagementProps } from "@/types/payment-method-management/CrossmintPaymentMethodManagementProps"; +import { + paymentMethodManagementIncomingEvents, + paymentMethodManagementOutgoingEvents, +} from "@/types/payment-method-management/events"; +import { appendObjectToQueryParams } from "@/utils/appendObjectToQueryParams"; +import { IFrameWindow } from "@crossmint/client-sdk-window"; +import type { CrossmintApiClient } from "@crossmint/common-sdk-base"; + +export type PaymentMethodManagementServiceProps = { + apiClient: CrossmintApiClient; +}; + +export function createPaymentMethodManagementService({ apiClient }: PaymentMethodManagementServiceProps) { + function getIFrameUrl(props: CrossmintPaymentMethodManagementProps) { + const urlWithPath = apiClient.buildUrl("/sdk/unstable/payment-method-management"); + const queryParams = new URLSearchParams(); + + appendObjectToQueryParams(queryParams, props); + + queryParams.append("apiKey", apiClient.crossmint.apiKey); + queryParams.append("sdkMetadata", JSON.stringify(apiClient["internalConfig"].sdkMetadata)); + + return `${urlWithPath}?${queryParams.toString()}`; + } + + function createIframeClient(iframe: HTMLIFrameElement) { + return IFrameWindow.initExistingIFrame(iframe, { + incomingEvents: paymentMethodManagementIncomingEvents, + outgoingEvents: paymentMethodManagementOutgoingEvents, + }); + } + + return { + iframe: { + getUrl: getIFrameUrl, + createClient: createIframeClient, + }, + }; +} diff --git a/packages/client/base/src/types/index.ts b/packages/client/base/src/types/index.ts index 9b420d33b..2f0a198f5 100644 --- a/packages/client/base/src/types/index.ts +++ b/packages/client/base/src/types/index.ts @@ -2,6 +2,7 @@ export * from "./events"; export * from "./hosted"; export * from "./embed"; export * from "./system"; +export * from "./payment-method-management"; export * from "./CryptoCurrency"; export const BaseUrls = { diff --git a/packages/client/base/src/types/payment-method-management/CrossmintPaymentMethodManagementProps.ts b/packages/client/base/src/types/payment-method-management/CrossmintPaymentMethodManagementProps.ts new file mode 100644 index 000000000..a7ab93de5 --- /dev/null +++ b/packages/client/base/src/types/payment-method-management/CrossmintPaymentMethodManagementProps.ts @@ -0,0 +1,3 @@ +export interface CrossmintPaymentMethodManagementProps { + jwt: string; +} diff --git a/packages/client/base/src/types/payment-method-management/events/PaymentMethodManagementIFrameEmitter.ts b/packages/client/base/src/types/payment-method-management/events/PaymentMethodManagementIFrameEmitter.ts new file mode 100644 index 000000000..ea2eb0393 --- /dev/null +++ b/packages/client/base/src/types/payment-method-management/events/PaymentMethodManagementIFrameEmitter.ts @@ -0,0 +1,9 @@ +import type { IFrameWindow } from "@crossmint/client-sdk-window"; + +import type { PaymentMethodManagementIncomingEventMap } from "./incoming"; +import type { PaymentMethodManagementOutgoingEventMap } from "./outgoing"; + +export type PaymentMethodManagementIFrameEmitter = IFrameWindow< + PaymentMethodManagementIncomingEventMap, + PaymentMethodManagementOutgoingEventMap +>; diff --git a/packages/client/base/src/types/payment-method-management/events/incoming.ts b/packages/client/base/src/types/payment-method-management/events/incoming.ts new file mode 100644 index 000000000..1611b1642 --- /dev/null +++ b/packages/client/base/src/types/payment-method-management/events/incoming.ts @@ -0,0 +1,8 @@ +import { z } from "zod"; + +export const paymentMethodManagementIncomingEvents = { + "ui:height.changed": z.object({ + height: z.number(), + }), +}; +export type PaymentMethodManagementIncomingEventMap = typeof paymentMethodManagementIncomingEvents; diff --git a/packages/client/base/src/types/payment-method-management/events/index.ts b/packages/client/base/src/types/payment-method-management/events/index.ts new file mode 100644 index 000000000..b753ff665 --- /dev/null +++ b/packages/client/base/src/types/payment-method-management/events/index.ts @@ -0,0 +1,4 @@ +export * from "./incoming"; +export * from "./outgoing"; + +export * from "./PaymentMethodManagementIFrameEmitter"; diff --git a/packages/client/base/src/types/payment-method-management/events/outgoing.ts b/packages/client/base/src/types/payment-method-management/events/outgoing.ts new file mode 100644 index 000000000..e3018fc78 --- /dev/null +++ b/packages/client/base/src/types/payment-method-management/events/outgoing.ts @@ -0,0 +1,2 @@ +export const paymentMethodManagementOutgoingEvents = {}; +export type PaymentMethodManagementOutgoingEventMap = typeof paymentMethodManagementOutgoingEvents; diff --git a/packages/client/base/src/types/payment-method-management/index.ts b/packages/client/base/src/types/payment-method-management/index.ts new file mode 100644 index 000000000..d1165cc8b --- /dev/null +++ b/packages/client/base/src/types/payment-method-management/index.ts @@ -0,0 +1,3 @@ +export * from "./events"; + +export * from "./CrossmintPaymentMethodManagementProps"; diff --git a/packages/client/ui/react-ui/src/components/card-management/CrossmintPaymentMethodManagement.tsx b/packages/client/ui/react-ui/src/components/card-management/CrossmintPaymentMethodManagement.tsx new file mode 100644 index 000000000..62ddad3b2 --- /dev/null +++ b/packages/client/ui/react-ui/src/components/card-management/CrossmintPaymentMethodManagement.tsx @@ -0,0 +1,6 @@ +import { CrossmintPaymentMethodManagementIFrame } from "./CrossmintPaymentMethodManagementIFrame"; +import type { CrossmintPaymentMethodManagementProps } from "@crossmint/client-sdk-base"; + +export function CrossmintPaymentMethodManagement(props: CrossmintPaymentMethodManagementProps) { + return ; +} diff --git a/packages/client/ui/react-ui/src/components/card-management/CrossmintPaymentMethodManagementIFrame.tsx b/packages/client/ui/react-ui/src/components/card-management/CrossmintPaymentMethodManagementIFrame.tsx new file mode 100644 index 000000000..0c1269df1 --- /dev/null +++ b/packages/client/ui/react-ui/src/components/card-management/CrossmintPaymentMethodManagementIFrame.tsx @@ -0,0 +1,65 @@ +import { createCrossmintApiClient } from "@/utils/createCrossmintApiClient"; +import { + createPaymentMethodManagementService, + type PaymentMethodManagementIFrameEmitter, +} from "@crossmint/client-sdk-base"; +import { useCrossmint } from "@crossmint/client-sdk-react-base"; +import { useEffect, useRef, useState } from "react"; +import type { CrossmintPaymentMethodManagementProps } from "@crossmint/client-sdk-base"; + +export function CrossmintPaymentMethodManagementIFrame(props: CrossmintPaymentMethodManagementProps) { + const [iframeClient, setIframeClient] = useState(null); + const [height, setHeight] = useState(0); + + const ref = useRef(null); + + const { crossmint } = useCrossmint(); + const apiClient = createCrossmintApiClient(crossmint, { + usageOrigin: "client", + }); + const paymentMethodManagementService = createPaymentMethodManagementService({ apiClient }); + + useEffect(() => { + const iframe = ref.current; + if (!iframe || iframeClient) { + return; + } + setIframeClient(paymentMethodManagementService.iframe.createClient(iframe)); + }, [ref.current, iframeClient]); + + useEffect(() => { + if (iframeClient == null) { + return; + } + iframeClient.on("ui:height.changed", (data) => setHeight(data.height)); + + return () => { + iframeClient.off("ui:height.changed"); + }; + }, [iframeClient]); + + return ( +