Skip to content
This repository has been archived by the owner on Aug 16, 2024. It is now read-only.

CLI refactor - 1 #135

Merged
merged 29 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
ca44f92
Merge pull request #3 from magiclabs/master
PBillingsby Jun 27, 2024
01747e7
remove universal reference from template mappings
PBillingsby Jun 23, 2024
07ac7ec
remove universal from dev-data
PBillingsby Jun 23, 2024
a3b7d94
bump magic versions
PBillingsby Jun 23, 2024
91b1aa2
remove flow universal template
PBillingsby Jun 23, 2024
b5b7097
remove universal wallet template
PBillingsby Jun 23, 2024
b42607f
update imports
PBillingsby Jun 23, 2024
4770c76
remove askProduct
PBillingsby Jun 25, 2024
5d6e5f1
default to dedicated
PBillingsby Jun 25, 2024
23e17a5
update file paths
PBillingsby Jun 25, 2024
f0a2e10
update file paths
PBillingsby Jun 25, 2024
39c8747
add file structure to readme
PBillingsby Jun 25, 2024
946dbaf
add components to ui directory
PBillingsby Jun 25, 2024
d9d8430
move providers to hooks directory
PBillingsby Jun 25, 2024
0856a55
add smart contract card and functions
PBillingsby Jul 5, 2024
396324d
remove unused imports from smart contract card
PBillingsby Jul 5, 2024
595a31a
add smart contract card to dashboard
PBillingsby Jul 5, 2024
58e2ec5
update send transaction card to account for maxFeePerGas and maxPrior…
PBillingsby Jul 5, 2024
c0fc672
add txnParams type
PBillingsby Jul 5, 2024
14a17aa
move polygon to unsupported for Eip1559
PBillingsby Jul 5, 2024
50cd5bd
add readme link to header. update forminput
PBillingsby Jul 5, 2024
79df703
remove product from mapping
PBillingsby Jul 8, 2024
f4c3137
add comment about session rehydration
PBillingsby Jul 22, 2024
a1b8ac2
add dependency resolutions
PBillingsby Jul 30, 2024
1c3a093
add dependency resolutions
PBillingsby Jul 30, 2024
ac765a8
bump ejs version
PBillingsby Jul 30, 2024
307e193
bump ejs
PBillingsby Jul 30, 2024
7616563
Fix linting, update package version to 5.0.0
jamesrp13 Jul 30, 2024
6077284
Merge pull request #4 from PBillingsby/cli-updates
PBillingsby Jul 30, 2024
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# v5.0.0 (Mon Jul 29 2024)

#### 💥 Breaking Change

- Removes Universal support with associated flags, prompts, and templates
- Adds architectural updates to EVM templates

#### Authors: 1

- pbillingsby ([@PBillingsby](https://github.com/PBillingsby))

# v4.13.0 (Fri Apr 12 2024)

#### 🚀 Enhancement
Expand Down
1 change: 0 additions & 1 deletion core/create-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ export async function createApp(config: CreateMagicAppConfig) {
...(await buildTemplate({
...config,
chain: undefined,
product: undefined,
configuration: undefined,
isChosenTemplateValid: false,
isQuickstart: false,
Expand Down
126 changes: 39 additions & 87 deletions core/utils/templateMappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
AuthTypePrompt,
BlockchainNetworkPrompt,
ConfigurationPrompt,
ProductPrompt,
ProjectNamePrompt,
PublishableApiKeyPrompt,
} from 'scaffolds/prompts';
Expand All @@ -14,27 +13,16 @@ import DedicatedScaffold, { flags as dedicatedFlags } from '../../scaffolds/next
import FlowDedicatedScaffold, {
flags as flowDedicatedFlags,
} from '../../scaffolds/nextjs-flow-dedicated-wallet/scaffold';
import FlowUniversalScaffold, {
flags as flowUniversalFlags,
} from '../../scaffolds/nextjs-flow-universal-wallet/scaffold';
import SolanaDedicatedScaffold, {
flags as solanaDedicatedFlags,
} from '../../scaffolds/nextjs-solana-dedicated-wallet/scaffold';
import UniversalScaffold, { flags as universalFlags } from '../../scaffolds/nextjs-universal-wallet/scaffold';
import { Timer } from './timer';

export type Chain = 'evm' | 'solana' | 'flow';
export type Template =
| 'nextjs-dedicated-wallet'
| 'nextjs-universal-wallet'
| 'nextjs-solana-dedicated-wallet'
| 'nextjs-flow-universal-wallet'
| 'nextjs-flow-dedicated-wallet';

export type Product = 'universal' | 'dedicated';
export type Template = 'nextjs-dedicated-wallet' | 'nextjs-solana-dedicated-wallet' | 'nextjs-flow-dedicated-wallet';

type ConfigType = CreateMagicAppConfig & {
chain: Chain | undefined;
product: Product | undefined;
configuration: string | undefined;
isChosenTemplateValid: boolean;
isQuickstart: boolean;
Expand All @@ -43,32 +31,16 @@ type ConfigType = CreateMagicAppConfig & {
function mapTemplateToChain(template: string): Chain | undefined {
switch (template) {
case 'nextjs-dedicated-wallet':
case 'nextjs-universal-wallet':
return 'evm';
case 'nextjs-solana-dedicated-wallet':
return 'solana';
case 'nextjs-flow-universal-wallet':
case 'nextjs-flow-dedicated-wallet':
return 'flow';
default:
return undefined;
}
}

function mapTemplateToProduct(template: string): Product | undefined {
switch (template) {
case 'nextjs-dedicated-wallet':
case 'nextjs-solana-dedicated-wallet':
case 'nextjs-flow-dedicated-wallet':
return 'dedicated';
case 'nextjs-universal-wallet':
case 'nextjs-flow-universal-wallet':
return 'universal';
default:
return undefined;
}
}

export async function mapTemplateToScaffold(
template: string,
appData: any,
Expand All @@ -93,11 +65,6 @@ export async function mapTemplateToScaffold(
data.loginMethods = await AuthTypePrompt.loginMethodsPrompt();
}
return new DedicatedScaffold(data);
case 'nextjs-universal-wallet':
if (!data.network) {
data.network = await BlockchainNetworkPrompt.evmNetworkPrompt();
}
return new UniversalScaffold(data);
case 'nextjs-solana-dedicated-wallet':
if (!data.network) {
data.network = await BlockchainNetworkPrompt.solanaNetworkPrompt();
Expand All @@ -106,11 +73,6 @@ export async function mapTemplateToScaffold(
data.loginMethods = await AuthTypePrompt.loginMethodsPrompt();
}
return new SolanaDedicatedScaffold(data);
case 'nextjs-flow-universal-wallet':
if (!data.network) {
data.network = await BlockchainNetworkPrompt.flowNetworkPrompt();
}
return new FlowUniversalScaffold(data);
case 'nextjs-flow-dedicated-wallet':
if (!data.network) {
data.network = await BlockchainNetworkPrompt.flowNetworkPrompt();
Expand All @@ -128,12 +90,8 @@ export function mapTemplateToFlags(template: string): any {
switch (template) {
case 'nextjs-dedicated-wallet':
return dedicatedFlags;
case 'nextjs-universal-wallet':
return universalFlags;
case 'nextjs-solana-dedicated-wallet':
return solanaDedicatedFlags;
case 'nextjs-flow-universal-wallet':
return flowUniversalFlags;
case 'nextjs-flow-dedicated-wallet':
return flowDedicatedFlags;
default:
Expand All @@ -145,7 +103,6 @@ const quickstartConfig = (config: ConfigType): ConfigType => ({
...config,
template: 'nextjs-dedicated-wallet',
network: 'polygon-amoy',
product: 'dedicated',
chain: 'evm',
isChosenTemplateValid: true,
isQuickstart: true,
Expand All @@ -155,14 +112,14 @@ const solanaConfig = async (config: ConfigType): Promise<ConfigType> => ({
...config,
template: 'nextjs-solana-dedicated-wallet',
network: await BlockchainNetworkPrompt.solanaNetworkPrompt(),
product: 'dedicated',
chain: 'solana',
isChosenTemplateValid: true,
isQuickstart: false,
});

export const buildTemplate = async (appConfig: ConfigType): Promise<ConfigType> => {
let config = appConfig;
let config = { ...appConfig };

if (!config.projectName) {
config.projectName = await ProjectNamePrompt.askProjectName();
}
Expand All @@ -171,59 +128,54 @@ export const buildTemplate = async (appConfig: ConfigType): Promise<ConfigType>
config.configuration = await ConfigurationPrompt.askConfiguration();

if (config.configuration === 'quickstart') {
config = quickstartConfig(config);
return config;
return quickstartConfig(config);
}
} else {
config = {
...config,
product: mapTemplateToProduct(config.template),
chain: mapTemplateToChain(config.template),
};
config.chain = mapTemplateToChain(config.template);
}

if (!config.chain && !config.network) {
if (!config.chain) {
config.chain = await BlockchainNetworkPrompt.chainPrompt();
}

if (!config.network) {
if (config.chain === 'solana') {
config = await solanaConfig(config);
} else if (config.chain === 'flow') {
config.network = await BlockchainNetworkPrompt.flowNetworkPrompt();
} else if (config.chain === 'evm') {
config.network = await BlockchainNetworkPrompt.evmNetworkPrompt();
switch (config.chain) {
case 'solana':
config = await solanaConfig(config);
break;
case 'flow':
config.network = await BlockchainNetworkPrompt.flowNetworkPrompt();
break;
case 'evm':
config.network = await BlockchainNetworkPrompt.evmNetworkPrompt();
break;
default:
config.network = await BlockchainNetworkPrompt.evmNetworkPrompt();
break;
}
} else if (
config.network === 'ethereum' ||
config.network === 'ethereum-sepolia' ||
config.network === 'polygon' ||
config.network === 'polygon-amoy' ||
config.network === 'etherlink-testnet'
) {
config.chain = 'evm';
} else if (config.network === 'solana-devnet' || config.network === 'solana-mainnet') {
config.chain = 'solana';
} else {
config.chain = 'flow';
}

if (!config.product) {
config.product = await ProductPrompt.askProduct();

if (config.product === 'universal') {
if (config.chain === 'flow') {
config.template = 'nextjs-flow-universal-wallet';
} else {
config.template = 'nextjs-universal-wallet';
}
} else if (config.chain === 'flow') {
config.template = 'nextjs-flow-dedicated-wallet';
const evmNetworks = [
'ethereum',
'ethereum-sepolia',
'polygon',
'polygon-amoy',
'etherlink-testnet',
'zksync',
'zksync-sepolia',
];
const solanaNetworks = ['solana-devnet', 'solana-mainnet'];

if (evmNetworks.includes(config.network)) {
config.chain = 'evm';
} else if (solanaNetworks.includes(config.network)) {
config.chain = 'solana';
} else {
config.template = 'nextjs-dedicated-wallet';
config.chain = 'flow';
}
config.isChosenTemplateValid = true;
}

config.template = config.chain === 'flow' ? 'nextjs-flow-dedicated-wallet' : 'nextjs-dedicated-wallet';
config.isChosenTemplateValid = true;

return config;
};
12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "make-magic",
"version": "4.13.0",
"version": "5.0.0",
"description": "A tool for quickly scaffolding an app with Magic authentication baked-in!",
"repository": "magiclabs/create-magic-app",
"license": "MIT",
Expand Down Expand Up @@ -81,11 +81,17 @@
"dependencies": {
"@segment/analytics-node": "^1.1.0",
"binaryextensions": "^4.18.0",
"ejs": "^3.1.9",
"ejs": "^3.1.10",
"enquirer": "^2.4.0",
"fs-extra": "^11.1.1",
"ora": "^5.1.0",
"pretty-time": "^1.1.0",
"textextensions": "^5.16.0"
},
"resolutions": {
"ejs": "^3.1.10",
"tar": "^6.2.1",
"braces": "^3.0.3",
"merge": "^2.1.1"
}
}
}
10 changes: 0 additions & 10 deletions scaffolds/dev-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,10 @@ export const templateDevData = {
loginMethods: ['EmailOTP', 'SMSOTP'],
projectName: 'My Flow Dedicated Wallet',
},
'nextjs-flow-universal-wallet': {
network: 'flow-testnet',
publishableApiKey: 'pk_live_8D6C562ABCA3140A',
projectName: 'My Flow Universal Wallet',
},
'nextjs-solana-dedicated-wallet': {
network: 'solana-devnet',
publishableApiKey: 'pk_live_FD2D70B32ABE11BD',
loginMethods: ['EmailOTP', 'SMSOTP'],
projectName: 'My Solana Dedicated Wallet',
},
'nextjs-universal-wallet': {
network: 'ethereum-sepolia',
publishableApiKey: 'pk_live_8D6C562ABCA3140A',
projectName: 'My Universal Wallet',
},
};
13 changes: 7 additions & 6 deletions scaffolds/nextjs-dedicated-wallet/scaffold.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Flags } from '../../core/flags';
import BaseScaffold, { ExecaCommand } from '../../core/types/BaseScaffold';
import { AuthTypePrompt, BlockchainNetworkPrompt, PublishableApiKeyPrompt } from '../../scaffolds/prompts';
import { AuthTypePrompt, BlockchainNetworkPrompt, PublishableApiKeyPrompt } from '../prompts';

export type Data = BlockchainNetworkPrompt.Data & PublishableApiKeyPrompt.Data & AuthTypePrompt.Data;

Expand Down Expand Up @@ -41,12 +41,13 @@ export default class DedicatedScaffold extends BaseScaffold {
'./src/components/magic/wallet-methods/Disconnect.tsx',
'./src/components/magic/wallet-methods/GetIdToken.tsx',
'./src/components/magic/wallet-methods/GetMetadata.tsx',
'./src/components/magic/Dashboard.tsx',
'./src/components/magic/DevLinks.tsx',
'./src/components/magic/Header.tsx',
'./src/components/ui/Dashboard.tsx',
'./src/components/ui/DevLinks.tsx',
'./src/components/ui/Header.tsx',
'./src/components/magic/Login.tsx',
'./src/components/magic/MagicProvider.tsx',
'./src/components/magic/MagicDashboardRedirect.tsx',
'./src/hooks/MagicProvider.tsx',
'./src/hooks/Web3.tsx',
'./src/components/ui/MagicDashboardRedirect.tsx',
'./src/pages',
'./src/styles',
'./src/utils',
Expand Down
47 changes: 47 additions & 0 deletions scaffolds/nextjs-dedicated-wallet/template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,53 @@ This scaffold is meant to help you bootstrap your own projects with Magic's [Ded

The folder structure of this scaffold is designed to encapsulate all things Magic into one place so you can easily add or remove components and functionality. For example, all Magic-specific components are in the `src/components/magic` directory while generic UI components are in the `src/components/ui` directory.

## Usage

This project uses Next.js but relies on fairly standard React components and hooks. Magic-related components are in the `/src/components/magic` directory, all other UI components are in the `/src/components/ui` directory, utility functions are in `/src/utils` and hooks are in the `/src/hooks` directory.

Use this project as a reference for how to use this template or implement Magic in your own project. Key areas to look at include:

### Custom Hooks
In the `/src/hooks` directory, the `MagicProvider` hook sets up and provides a Magic instance for using the Magic SDK and OAuth extension. Additionally, the `Web3.tsx` hook initializes and provides a Web3 instance using the Magic provider.

### Login Functionality
The `Login.tsx` component, located in `/src/components/magic`, manages the display and functionality of various login methods on the login page. It is a central piece for handling user authentication.

One thing to note is that whenever `getInfo` is called from any of the authentication providers, the user session is rehydrated.

Here is a list of the available authentication methods:
- `Discord.tsx` - Handles authentication using Discord OAuth.
- `Facebook.tsx` - Handles authentication using Facebook OAuth.
- `Google.tsx` - Handles authentication using Google OAuth.
- `Twitch.tsx` - Handles authentication using Twitch OAuth.
- `EmailOTP.tsx` - Handles authentication using email one-time password (OTP).
- `Github.tsx` - Handles authentication using GitHub OAuth.
- `SMSOTP.tsx` - Handles authentication using SMS one-time password (OTP).
- `Twitter.tsx` - Handles authentication using Twitter OAuth.

### User Interaction Components

- `/src/components/magic/auth`: This contains all of the authentication methods.

- `/src/components/magic/cards`: The `SendTransactionCard.tsx` component facilitate transaction processes, `UserInfoCard.tsx` displays user information, `WalletMethodsCard.tsx` manages authentication tokens and user metadata and `SmartContract.tsx` interacts with a basic storage contract.

- `/src/components/magic/wallet-methods`: This directory includes several components that provide specific functionalities:
- `Disconnect.tsx` handles the disconnection of the user's session from the application.
- `GetIdToken.tsx` retrieves the ID token for the authenticated user.
- `GetMetadata.tsx` retrieves metadata information about the authenticated user. This will rehydrate the user session every time it is rendered. It does this when calling the `getInfo` function. The user session is rehydrated whenever `getInfo` is invoked
- `UpdateEmail.tsx` allows the user to update their email address.

### Utility Functions
The `/src/utils` directory includes utility files that support various aspects of the application:
- `common.ts` manages user authentication processes. The `logout` function handle the process of logging out a user and clearing their authentication data, while `saveUserInfo` saves the user's token, login method, and address to local storage.
- `network.ts` defines network configurations and utilities, such as URLs, chain IDs, tokens, and block explorer links.
- `showToast.ts` handles customizable toast notifications.
- `smartContract.ts` contains functions and configurations for interacting with smart contracts, such as retrieving contract IDs, determining testnet status, generating hash links, and defining contract ABIs.

These utilities are essential for supporting various aspects of the application.

### UI Components
The `/src/components/ui` directory contains reusable UI components for building the user interface. This includes components for creating and styling cards (`Card`, `CardHeader`, `CardLabel`), layout elements for the dashboard (`Dashboard`), separators (`Divider`), error messages (`ErrorText`), form elements (`FormButton`, `FormInput`), redirection handling within the Magic dashboard (`MagicDashboardRedirect`), spacing elements (`Spacer`), loading indicators (`Spinner`), and displaying transaction history (`TransactionHistory`).
## Next.js

This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
Expand Down
Loading
Loading