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

# initialize

> Create or restore a SparkWallet instance from mnemonic or seed.

Creates and initializes a new `SparkWallet` instance.

## Method Signature

```typescript theme={null}
interface SparkWalletProps {
  mnemonicOrSeed?: Uint8Array | string;
  accountNumber?: number;
  signer?: SparkSigner;
  options?: ConfigOptions;
}

static async initialize(props: SparkWalletProps): Promise<{
  wallet: SparkWallet;
  mnemonic?: string;
}>
```

## Parameters

<ResponseField name="mnemonicOrSeed" type="Uint8Array | string">
  BIP-39 mnemonic phrase or raw seed
</ResponseField>

<ResponseField name="accountNumber" type="number">
  Number used to generate multiple identity keys from the same mnemonic
</ResponseField>

<ResponseField name="signer" type="SparkSigner">
  Custom signer implementation for advanced use cases
</ResponseField>

<ResponseField name="options" type="ConfigOptions">
  Wallet configuration options including network selection
</ResponseField>

<Expandable title="ConfigOptions Details">
  ```typescript theme={null}
  interface ConfigOptions {
    // e.g. "MAINNET" | "TESTNET" | "SIGNET" | "REGTEST" | "LOCAL"
    network?: NetworkType; // Required for most use cases

    // Advanced options (rarely needed):
    signingOperators?: Readonly<Record<string, SigningOperator>>;
    coordinatorIdentifier?: string;
    frostSignerAddress?: string;
    threshold?: number;

    tokenSignatures?: "ECDSA" | "SCHNORR";
    tokenValidityDurationSeconds?: number;
    tokenOutputLockExpiryMs?: number;
    tokenTransactionVersion?: "V2" | "V3";

    electrsUrl?: string;
    sspClientOptions?: SspClientOptions;
    expectedWithdrawBondSats?: number;
    expectedWithdrawRelativeBlockLocktime?: number;
    signerWithPreExistingKeys?: boolean;
    console?: { otel?: boolean };

    optimizationOptions?: {
      auto?: boolean;        // Auto-optimize leaves on sync (default: true)
      multiplicity?: number; // Optimization level 0-5 (default: 1)
    };
    tokenOptimizationOptions?: {
      enabled?: boolean;           // Enable token output consolidation (default: true)
      intervalMs?: number;         // Optimization interval (default: 300000 = 5 min)
      minOutputsThreshold?: number; // Min outputs before optimizing (default: 50)
    };
    events?: Partial<SparkWalletEvents>; // Pre-register event handlers at init
  }

  type NetworkType = "MAINNET" | "TESTNET" | "SIGNET" | "REGTEST" | "LOCAL";

  type SigningOperator = {
    id: number;
    identifier: string;
    address: string;
    identityPublicKey: string;
  };

  type SspClientOptions = {
    baseUrl: string;
    identityPublicKey: string;
    schemaEndpoint?: string;
  };
  ```
</Expandable>

## Leaf Optimization

Leaf optimization pre-arranges your wallet's internal structure to enable faster transfers. Without optimization, transfers may require a swap with the SSP (Spark Service Provider), adding latency. With optimization, transfers complete in \~5 seconds.

### How It Works

Spark creates **power-of-2 denomination leaves** (1, 2, 4, 8, 16... sats). With one leaf of each denomination, you can transfer any amount without needing an SSP swap. With multiple leaves of each denomination, you can make multiple transfers without swapping.

### Multiplicity Levels

The `multiplicity` setting controls how aggressively to optimize:

| Level   | Behavior                         | Use Case                                     |
| ------- | -------------------------------- | -------------------------------------------- |
| **0**   | No optimization                  | Testing only                                 |
| **1**   | 1 leaf per denomination          | Likely 1 fast transfer before needing a swap |
| **2-4** | Multiple leaves per denomination | Multiple fast transfers                      |
| **5**   | Maximum optimization             | Likely 5+ fast transfers without any swaps   |

### The Tradeoff

<Warning>
  Higher multiplicity = faster transfers, but smaller individual leaves. Leaves under **16,348 sats cannot be unilaterally exited** (fees would exceed value). If unilateral exit capability is critical for your users, use a lower multiplicity or larger balances.
</Warning>

For most consumer wallets, fast transfer speeds for 100% of users outweighs unilateral exit costs for a small fraction of users.

### Auto vs Manual Mode

**Auto mode** (`auto: true`, default):

* Optimization runs automatically in the background after sync
* Swaps with SSP when leaves are too far from optimal
* Transfers wait for optimization to complete before sending
* Best for most applications

**Manual mode** (`auto: false`):

* You control exactly when optimization runs via [`optimizeLeaves()`](/api-reference/wallet/optimize-leaves)
* More aggressive optimization (skips the "is it needed?" check)
* Use when you want maximum optimization regardless of current state

### Configuration Examples

```typescript theme={null}
// Default behavior - auto optimization with multiplicity 1
const { wallet } = await SparkWallet.initialize({
  options: { network: "MAINNET" }
});

// Fast transfers for consumer wallet
const { wallet } = await SparkWallet.initialize({
  options: {
    network: "MAINNET",
    optimizationOptions: {
      auto: true,
      multiplicity: 5
    }
  }
});

// Manual control for maximum optimization
const { wallet } = await SparkWallet.initialize({
  options: {
    network: "MAINNET",
    optimizationOptions: {
      auto: false,
      multiplicity: 5
    }
  }
});
// Then call wallet.optimizeLeaves() explicitly when needed
```

<Info>
  **Safe to pass on every init.** Pass `optimizationOptions` every time you initialize (e.g., on app reopen). The SDK only runs optimization if needed and does nothing on wallets with no balance.
</Info>

## Returns

<ResponseField name="wallet" type="SparkWallet" required>
  The initialized SparkWallet instance
</ResponseField>

<ResponseField name="mnemonic" type="string">
  The mnemonic if one was generated (undefined for raw seed)
</ResponseField>

## Example

<CodeGroup>
  ```typescript Create New Wallet theme={null}
  import { SparkWallet } from "@buildonspark/spark-sdk";

  // Create a new wallet
  const { wallet, mnemonic } = await SparkWallet.initialize({
    options: { network: "REGTEST" } // or "MAINNET"
  });

  console.log("Wallet initialized:", wallet);
  console.log("Generated mnemonic:", mnemonic);
  ```

  ```typescript Import Existing Wallet theme={null}
  import { SparkWallet } from "@buildonspark/spark-sdk";

  // Import wallet from existing mnemonic
  const { wallet } = await SparkWallet.initialize({
    mnemonicOrSeed: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
    accountNumber: 0, // Optional: specify account index
    options: { network: "REGTEST" }
  });

  console.log("Wallet restored from mnemonic");
  ```
</CodeGroup>

## Multiple SDK Instances

When running multiple wallet instances (e.g., service worker + popup in a browser extension):

<Info>
  Multiple instances are **safe** but may cause temporary claim failures. The SDK handles this automatically—failed claims retry and succeed on subsequent attempts.
</Info>

**Best practices:**

* Avoid calling `getStaticDepositAddress()` concurrently—this can create duplicate addresses
* Let one instance handle background claiming if possible
* Failed claims due to concurrent access are automatically recoverable

## System Time Requirements

The SDK uses your device's system time for expiry calculations.

<Warning>
  **Your device clock must be within 2 minutes of actual time**, or operations will fail with "invalid expiry\_time" errors. If users report this error, ask them to sync their device clock.
</Warning>
