create-sbc-app 0.1.2 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -105,6 +105,8 @@ The template includes comprehensive environment configuration:
105
105
  ```bash
106
106
  # Your SBC API key (get from SBC dashboard)
107
107
  VITE_SBC_API_KEY=your_api_key_here
108
+ # "base" or "baseSepolia"
109
+ VITE_CHAIN="baseSepolia"
108
110
  ```
109
111
 
110
112
  ## 📱 UI Components
@@ -132,8 +134,14 @@ cd my-sbc-app
132
134
  # Copy environment template
133
135
  cp .env.template .env
134
136
 
135
- # Add your API key
136
- echo "VITE_SBC_API_KEY=your_actual_api_key" >> .env
137
+ # then ensure your .env has the environment variables set up
138
+
139
+ # "base" or "baseSepolia"
140
+ VITE_CHAIN="baseSepolia"
141
+ # Custom RPC URL (optional) - e.g. get one from Alchemey at https://dashboard.alchemy.com/apps
142
+ VITE_RPC_URL=
143
+ # Get your SBC API Key at https://dashboard.stablecoin.xyz
144
+ VITE_SBC_API_KEY=
137
145
  ```
138
146
 
139
147
  ### 3. Start Development
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-sbc-app",
3
- "version": "0.1.2",
3
+ "version": "0.1.5",
4
4
  "description": "Scaffold a new SBC App Kit project with one command.",
5
5
  "bin": {
6
6
  "create-sbc-app": "bin/cli.js"
@@ -9,7 +9,14 @@
9
9
  "build": "tsc",
10
10
  "dev": "tsc --watch",
11
11
  "start": "node bin/cli.js",
12
- "prepublishOnly": "npm run build"
12
+ "prepublishOnly": "npm run build",
13
+ "preversion": "npm run build && npm run test-pack",
14
+ "test-pack": "npm pack --dry-run",
15
+ "test-cli": "mkdir -p test-cli && cd test-cli && node ../bin/cli.js test-app --template react && rm -rf test-cli",
16
+ "prepare-publish": "npm run build && npm run test-pack && npm run test-cli",
17
+ "publish-patch": "npm run prepare-publish && npm version patch && npm publish",
18
+ "publish-minor": "npm run prepare-publish && npm version minor && npm publish",
19
+ "publish-major": "npm run prepare-publish && npm version major && npm publish"
13
20
  },
14
21
  "type": "module",
15
22
  "dependencies": {
@@ -1,2 +1,6 @@
1
1
  # SBC App Kit Configuration
2
+ VITE_CHAIN="baseSepolia"
3
+ # Custom RPC URL (optional) - e.g. get one from Alchemey at https://dashboard.alchemy.com/apps
4
+ VITE_RPC_URL=
5
+ # Get your SBC API Key at https://dashboard.stablecoin.xyz
2
6
  VITE_SBC_API_KEY={{apiKey}}
@@ -16,11 +16,14 @@ Copy the example environment file and add your SBC API key:
16
16
  cp .env.example .env # Optional: for local overrides
17
17
  ```
18
18
 
19
- Edit `.env` and add your SBC API key:
19
+ Edit `.env` and add your SBC API key and Chain, with the optional for a custom RPC:
20
20
  ```bash
21
- VITE_SBC_API_KEY=your_api_key_here
22
- VITE_SBC_CHAIN={{chain}}
23
- VITE_SBC_DEBUG=true
21
+ # "base" or "baseSepolia"
22
+ VITE_CHAIN="baseSepolia"
23
+ # Custom RPC URL (optional) - e.g. get one from Alchemey at https://dashboard.alchemy.com/apps
24
+ VITE_RPC_URL=
25
+ # Get your SBC API Key at https://dashboard.stablecoin.xyz
26
+ VITE_SBC_API_KEY=
24
27
  ```
25
28
 
26
29
  > **Get your API key:** Visit the [SBC Dashboard](https://dashboard.stablecoin.xyz) to create an account and get your API key.
@@ -1,15 +1,42 @@
1
1
  import { useState, useEffect, useRef, createContext, useContext } from 'react';
2
2
  import { SbcProvider, WalletButton, useSbcApp, useUserOperation } from '@stablecoin.xyz/react';
3
- import { {{chain}} } from 'viem/chains';
3
+ import { base, baseSepolia } from 'viem/chains';
4
4
  import { createPublicClient, http, getAddress, parseSignature, WalletClient, PublicClient } from 'viem';
5
5
  import { parseUnits, encodeFunctionData, erc20Abi } from 'viem';
6
6
  import './App.css';
7
7
 
8
- // SBC Token Configuration
9
- const SBC_TOKEN_ADDRESS = '0xf9FB20B8E097904f0aB7d12e9DbeE88f2dcd0F16';
10
- const SBC_DECIMALS = 6;
8
+ // Chain selection helpers
9
+ const chain = (import.meta.env.VITE_CHAIN === 'base') ? base : baseSepolia;
10
+ const rpcUrl = import.meta.env.VITE_RPC_URL;
11
11
 
12
- const publicClient = createPublicClient({ chain: {{chain}}, transport: http() });
12
+ const SBC_TOKEN_ADDRESS = (chain) => {
13
+ if (chain.id === baseSepolia.id) {
14
+ return '0xf9FB20B8E097904f0aB7d12e9DbeE88f2dcd0F16';
15
+ } else if (chain.id === base.id) {
16
+ return '0xfdcC3dd6671eaB0709A4C0f3F53De9a333d80798';
17
+ }
18
+ throw new Error('Unsupported chain');
19
+ };
20
+
21
+ const SBC_DECIMALS = (chain) => {
22
+ if (chain.id === baseSepolia.id) {
23
+ return 6;
24
+ } else if (chain.id === base.id) {
25
+ return 18;
26
+ }
27
+ throw new Error('Unsupported chain');
28
+ };
29
+
30
+ const chainExplorer = (chain) => {
31
+ if (chain.id === baseSepolia.id) {
32
+ return 'https://sepolia.basescan.org';
33
+ } else if (chain.id === base.id) {
34
+ return 'https://basescan.org';
35
+ }
36
+ throw new Error('Unsupported chain');
37
+ };
38
+
39
+ const publicClient = createPublicClient({ chain, transport: http() });
13
40
 
14
41
  const erc20PermitAbi = [
15
42
  ...erc20Abi,
@@ -63,6 +90,10 @@ function WalletStatus({ onDisconnect }: { onDisconnect: () => void }) {
63
90
  <label>Connection:</label>
64
91
  <div className="value">Connected via wallet extension</div>
65
92
  </div>
93
+ <div className="info-row">
94
+ <label>Chain:</label>
95
+ <div className="value">{chain.name}</div>
96
+ </div>
66
97
  </div>
67
98
  );
68
99
  }
@@ -81,7 +112,7 @@ function SmartAccountInfo() {
81
112
  setIsLoadingBalance(true);
82
113
  try {
83
114
  const balance = await publicClient.readContract({
84
- address: SBC_TOKEN_ADDRESS as `0x${string}`,
115
+ address: SBC_TOKEN_ADDRESS(chain) as `0x${string}`,
85
116
  abi: erc20Abi,
86
117
  functionName: 'balanceOf',
87
118
  args: [account.address as `0x${string}`],
@@ -107,7 +138,7 @@ function SmartAccountInfo() {
107
138
  setIsLoadingBalance(true);
108
139
  try {
109
140
  const balance = await publicClient.readContract({
110
- address: SBC_TOKEN_ADDRESS as `0x${string}`,
141
+ address: SBC_TOKEN_ADDRESS(chain) as `0x${string}`,
111
142
  abi: erc20Abi,
112
143
  functionName: 'balanceOf',
113
144
  args: [account.address as `0x${string}`],
@@ -138,7 +169,7 @@ function SmartAccountInfo() {
138
169
  const formatSbcBalance = (balance: string | null): string => {
139
170
  if (!balance) return '0.00';
140
171
  try {
141
- return (Number(balance) / Math.pow(10, SBC_DECIMALS)).toFixed(2);
172
+ return (Number(balance) / Math.pow(10, SBC_DECIMALS(chain))).toFixed(2);
142
173
  } catch {
143
174
  return '0.00';
144
175
  }
@@ -198,7 +229,7 @@ function SendSBCForm() {
198
229
  try {
199
230
  const ownerChecksum = getAddress(ownerAddress);
200
231
  const spenderChecksum = getAddress(account.address);
201
- const value = parseUnits('1', SBC_DECIMALS); // Send 1 SBC
232
+ const value = parseUnits('1', SBC_DECIMALS(chain)); // Send 1 SBC
202
233
  const deadline = Math.floor(Date.now() / 1000) + 60 * 30; // 30 min
203
234
 
204
235
  const signature = await getPermitSignature({
@@ -207,8 +238,8 @@ function SendSBCForm() {
207
238
  owner: ownerChecksum,
208
239
  spender: spenderChecksum,
209
240
  value,
210
- tokenAddress: SBC_TOKEN_ADDRESS,
211
- chainId: {{chain}}.id,
241
+ tokenAddress: SBC_TOKEN_ADDRESS(chain),
242
+ chainId: chain.id,
212
243
  deadline,
213
244
  });
214
245
 
@@ -231,8 +262,8 @@ function SendSBCForm() {
231
262
 
232
263
  await sendUserOperation({
233
264
  calls: [
234
- { to: SBC_TOKEN_ADDRESS as `0x${string}`, data: permitCallData },
235
- { to: SBC_TOKEN_ADDRESS as `0x${string}`, data: transferFromCallData },
265
+ { to: SBC_TOKEN_ADDRESS(chain) as `0x${string}`, data: permitCallData },
266
+ { to: SBC_TOKEN_ADDRESS(chain) as `0x${string}`, data: transferFromCallData },
236
267
  ],
237
268
  });
238
269
  } catch (err) {
@@ -286,7 +317,7 @@ function SendSBCForm() {
286
317
  <div className="success-message">
287
318
  <p>✅ Transaction Successful!</p>
288
319
  <a
289
- href={`https://sepolia.basescan.org/tx/${data.transactionHash}`}
320
+ href={`${chainExplorer(chain)}/tx/${data.transactionHash}`}
290
321
  target="_blank"
291
322
  rel="noopener noreferrer"
292
323
  >
@@ -369,7 +400,8 @@ function ThemeToggle() {
369
400
  export default function App() {
370
401
  const sbcConfig = {
371
402
  apiKey: import.meta.env.VITE_SBC_API_KEY || '{{apiKey}}',
372
- chain: {{chain}},
403
+ chain,
404
+ rpcUrl,
373
405
  wallet: 'auto' as const,
374
406
  debug: true,
375
407
  walletOptions: { autoConnect: false },
@@ -462,7 +494,7 @@ async function getPermitSignature({
462
494
  name: tokenName as string,
463
495
  version: '1',
464
496
  chainId: BigInt(chainId),
465
- verifyingContract: SBC_TOKEN_ADDRESS as `0x${string}`,
497
+ verifyingContract: tokenAddress as `0x${string}`,
466
498
  };
467
499
 
468
500
  const types = {