> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chipipay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# create_wallet

> Creates a new wallet on Starknet. This method deploys the wallet contract and uses Chipi gasless paymaster to sponsor gas fees, resulting in a frictionless onboarding experience.

<Warning>
  **PIN is weak — not recommended for production.**

  A user-typed PIN is a short, low-entropy string. Anyone who shoulder-surfs the PIN, observes a phishing form, or compromises the browser at typing time can decrypt the wallet's private key. PIN remains in the SDK only as a fallback recovery surface for users who lose access to their platform authenticator.

  **Production embedded-wallet apps should default to a platform passkey** (Touch ID, Face ID, Windows Hello, Android biometrics) via the `@chipi-stack/chipi-passkey` package. For SHHH V8.4 wallets, `signerKind: "WEBAUTHN_P256"` keeps the private key inside the platform authenticator — it never leaves the device, never reaches Chipi servers, and is never derived from a user-typed secret.

  Only prompt for a PIN as the encryption key when:

  * The user explicitly opted into a PIN-only flow (e.g. cold-storage / paper-backup recovery), or
  * The platform genuinely has no WebAuthn / biometric support available.

  If you are migrating an existing PIN-based wallet to a passkey, look up `useMigrateWalletToPasskey` in your framework's hook docs.
</Warning>

## Usage

```python theme={null}
from chipi_sdk import CreateWalletParams, WalletType, Chain

wallet_response = sdk.create_wallet(
    params=CreateWalletParams(
        encrypt_key="user-secure-pin",
        external_user_id="your-user-id-123",
        wallet_type=WalletType.CHIPI,  # Optional, defaults to CHIPI
    )
)
```

### Parameters

* `encrypt_key` (str): A user-defined code or password used to encrypt the wallet's private key
* `external_user_id` (str): Your application's unique identifier for the user
* `user_id` (str, optional): Internal user ID (optional)
* `wallet_type` (WalletType, optional): Type of wallet to create (`CHIPI` or `READY`). Defaults to `CHIPI`
* `use_passkey` (bool, optional): Whether to use passkey authentication. Defaults to `False`

### Return Value

Returns a `CreateWalletResponse` (same shape as `GetWalletResponse`) — a flat object with:

* `public_key`: Wallet's public address
* `encrypted_private_key`: AES encrypted private key
* `wallet_type`: Type of wallet created
* `normalized_public_key`: Normalized public key
* `chain`: Blockchain network
* `is_deployed`: Whether the wallet contract is deployed
* `id`, `external_user_id`, `organization_id`, `api_public_key`, `created_at`, `updated_at`

## Example Implementation

```python theme={null}
from chipi_sdk import ChipiSDK, ChipiSDKConfig, CreateWalletParams, WalletType, Chain

# Initialize SDK
sdk = ChipiSDK(
    config=ChipiSDKConfig(
        api_public_key="pk_prod_your_public_key",
        api_secret_key="sk_prod_your_secret_key",
    )
)

def create_user_wallet(user_id: str, user_pin: str):
    """Create a new wallet for a user."""
    try:
        wallet_response = sdk.create_wallet(
            params=CreateWalletParams(
                encrypt_key=user_pin,
                external_user_id=user_id,
    
                wallet_type=WalletType.CHIPI,
            )
        )

        print(f"✅ Wallet created successfully!")
        print(f"   Address: {wallet_response.public_key}")
        print(f"   View on Starkscan: https://starkscan.co/contract/{wallet_response.public_key}")

        # Store wallet data securely in your database
        save_wallet_to_database(
            user_id=user_id,
            public_key=wallet_response.public_key,
            encrypted_private_key=wallet_response.encrypted_private_key,
        )

        return wallet_response

    except Exception as error:
        print(f"❌ Wallet creation failed: {error}")
        raise

# Usage
def onboard_new_user(user_id: str, pin: str):
    """Onboard a new user by creating their wallet."""
    wallet = create_user_wallet(user_id, pin)
    
    # Verify deployment on StarkScan
    contract_url = f"https://starkscan.co/contract/{wallet.public_key}"
    print(f"View contract: {contract_url}")
    
    return wallet

# Create wallet
wallet = onboard_new_user("user-123", "secure-pin-1234")
```

## Async Version

For async applications, use `acreate_wallet`:

```python theme={null}
import asyncio

async def create_user_wallet_async(user_id: str, user_pin: str):
    """Create a new wallet asynchronously."""
    wallet_response = await sdk.acreate_wallet(
        params=CreateWalletParams(
            encrypt_key=user_pin,
            external_user_id=user_id,

            wallet_type=WalletType.CHIPI,
        )
    )
    return wallet_response

# Run async
wallet = asyncio.run(create_user_wallet_async("user-123", "secure-pin-1234"))
```

## Wallet Types

The SDK supports two wallet types:

<Tabs>
  <Tab title="CHIPI (Recommended)">
    **OpenZeppelin account with SNIP-9 session keys support**

    * Full session key support for delegated transactions
    * Compatible with Chipi session management
    * Recommended for most applications

    ```python theme={null}
    wallet_type=WalletType.CHIPI  # Default
    ```
  </Tab>

  <Tab title="READY">
    **Argent X Account v0.4.0**

    * Compatible with Argent X wallet standard
    * Use when Argent X compatibility is required

    ```python theme={null}
    wallet_type=WalletType.READY
    ```
  </Tab>
</Tabs>

## Security Considerations

<Warning>
  **Encryption Key Security**

  The `encrypt_key` is critical for wallet security:

  * Never store it in plaintext
  * Use a secure method to derive it (e.g., from user password with PBKDF2)
  * Consider using hardware security modules (HSM) for production
</Warning>

<Info>
  **External User ID**

  The `external_user_id` should be:

  * Unique per user in your system
  * Stable (doesn't change over time)
  * Not personally identifiable information (use a UUID instead of email)
</Info>

## Error Handling

```python theme={null}
from chipi_sdk import ChipiTransactionError, ChipiApiError

try:
    wallet = sdk.create_wallet(
        params=CreateWalletParams(
            encrypt_key="user-pin",
            external_user_id="user-123",

        )
    )
except ChipiTransactionError as e:
    # Handle transaction-specific errors
    print(f"Transaction error: {e.message}")
    print(f"Error code: {e.code}")
except ChipiApiError as e:
    # Handle API errors
    print(f"API error: {e.message}")
    print(f"Status: {e.status}")
except Exception as e:
    # Handle other errors
    print(f"Unexpected error: {e}")
```

## Complete Example with Database Integration

```python theme={null}
from chipi_sdk import ChipiSDK, ChipiSDKConfig, CreateWalletParams, WalletType
import sqlite3
from datetime import datetime

# Initialize SDK
sdk = ChipiSDK(
    config=ChipiSDKConfig(
        api_public_key="pk_prod_your_public_key",
        api_secret_key="sk_prod_your_secret_key",
    )
)

def save_wallet_to_db(user_id: str, wallet_data: dict):
    """Save wallet data to database."""
    conn = sqlite3.connect('app.db')
    cursor = conn.cursor()
    
    cursor.execute('''
        INSERT INTO wallets (user_id, public_key, encrypted_private_key, created_at)
        VALUES (?, ?, ?, ?)
    ''', (
        user_id,
        wallet_data['public_key'],
        wallet_data['encrypted_private_key'],
        datetime.now().isoformat()
    ))
    
    conn.commit()
    conn.close()

def create_and_save_wallet(user_id: str, user_pin: str):
    """Create wallet and save to database."""
    # Create wallet
    wallet_response = sdk.create_wallet(
        params=CreateWalletParams(
            encrypt_key=user_pin,
            external_user_id=user_id,

            wallet_type=WalletType.CHIPI,
        )
    )
    
    # Save to database
    save_wallet_to_db(user_id, {
        'public_key': wallet_response.public_key,
        'encrypted_private_key': wallet_response.encrypted_private_key,
    })

    print(f"✅ Wallet created and saved for user: {user_id}")
    print(f"   Address: {wallet_response.public_key}")
    
    return wallet_response

# Usage
wallet = create_and_save_wallet("user-123", "secure-pin-1234")
```

## Related Methods

* [get\_wallet](/sdk/python/methods/get-wallet) - Retrieve existing wallet information
* [transfer](/sdk/python/methods/transfer) - Send tokens from the created wallet
