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

# Create wallets via API

> Create and manage MPC wallets programmatically using the Dfns API, including delegation, tagging, multichain keys, and webhook notifications.

This guide covers how to create wallets, add networks, and manage wallet metadata using the Dfns API and SDK.

## Prerequisites

* Service account or authenticated user with `Wallets:Create` permission
* Dfns SDK installed and configured
* Understanding of [wallets and keys](/core-concepts/wallets-and-keys)

## Creating a wallet

Create a wallet on a specific network using the SDK:

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { DfnsApiClient } from '@dfns/sdk'

  const dfns = new DfnsApiClient({
    baseUrl: 'https://api.dfns.io',
    // Your signer configuration
  })

  const wallet = await dfns.wallets.createWallet({
    body: {
      network: 'EthereumSepolia', // or 'Ethereum', 'Polygon', etc.
      name: 'My Wallet'
    }
  })

  console.log('Wallet ID:', wallet.id)
  console.log('Address:', wallet.address)
  console.log('Network:', wallet.network)
  ```

  ```go Go theme={null}
  import (
      dfns "github.com/dfns/dfns-sdk-go/v2"
      "github.com/dfns/dfns-sdk-go/v2/wallets"
  )

  // client, _ := dfns.NewClient(dfns.Options{...})

  name := "My Wallet"
  wallet, err := client.Wallets.CreateWallet(ctx, wallets.CreateWalletRequest{
      Network: "EthereumSepolia", // or "Ethereum", "Polygon", etc.
      Name:    &name,
  })

  fmt.Printf("Wallet ID: %s\n", wallet.ID)
  fmt.Printf("Address: %s\n", *wallet.Address)
  fmt.Printf("Network: %s\n", wallet.Network)
  ```

  ```python Python theme={null}
  from dfns_sdk import DfnsClient, DfnsClientConfig

  # config = DfnsClientConfig(auth_token="...", signer=signer)

  with DfnsClient(config) as client:
      wallet = client.wallets.create_wallet({
          "network": "EthereumSepolia",  # or "Ethereum", "Polygon", etc.
          "name": "My Wallet"
      })

      print(f"Wallet ID: {wallet['id']}")
      print(f"Address: {wallet['address']}")
      print(f"Network: {wallet['network']}")
  ```

  ```java Java theme={null}
  import co.dfns.sdk.*;
  import co.dfns.sdk.wallets.model.*;

  // DfnsClient client = new DfnsClient(config);

  Wallet wallet = client.wallets.createWallet(new CreateWalletRequest(
      Network.EthereumSepolia, // or Network.Ethereum, Network.Polygon, etc.
      "My Wallet",             // name
      null, null, null, null, null
  ));

  System.out.printf("Wallet ID: %s%n", wallet.id());
  System.out.printf("Address: %s%n", wallet.address());
  System.out.printf("Network: %s%n", wallet.network());
  ```
</CodeGroup>

### Request parameters

| Parameter | Required | Description                                                        |
| --------- | -------- | ------------------------------------------------------------------ |
| `network` | Yes      | The blockchain network (see [supported networks](/networks/index)) |
| `name`    | No       | Human-readable name for the wallet                                 |
| `tags`    | No       | Array of tags for organization                                     |

### Response

The response includes:

```typescript theme={null}
{
  id: 'wa-xxx-xxx',
  network: 'EthereumSepolia',
  address: '0x...',
  signingKey: {
    id: 'ke-xxx-xxx',
    scheme: 'ECDSA',
    curve: 'secp256k1'
  },
  status: 'Active',
  dateCreated: '2024-01-15T10:30:00Z',
  name: 'My Wallet',
  tags: []
}
```

## Adding a network to an existing wallet

For keys that support multiple networks (e.g., EVM chains), add additional networks to an existing wallet's key:

```typescript theme={null}
// First, get the key ID from an existing wallet
const existingWallet = await dfns.wallets.getWallet({
  walletId: 'wa-xxx-xxx'
})

const keyId = existingWallet.signingKey.id

// Create a new wallet on a different network using the same key
const polygonWallet = await dfns.wallets.createWallet({
  body: {
    network: 'Polygon',
    name: 'My Polygon Wallet',
    keyId: keyId // Use existing key
  }
})
```

<Note>
  Not all key types support all networks. EVM chains share the same key type (secp256k1), so a single key can be used across Ethereum, Polygon, Arbitrum, etc.
</Note>

## Deriving wallets from a master key (HD)

<Note>
  The recommended pattern is independent keys (the default in [Creating a wallet](#creating-a-wallet)) or shared-key reuse (see [Adding a network to an existing wallet](#adding-a-network-to-an-existing-wallet)). HD derivation is intended for cases where you need BIP-32 path semantics, for example to integrate with systems or tooling that assume hierarchical derivation. Each key share is generated independently by the MPC network, with stronger isolation than HD: compromising one key share reveals nothing about another.
</Note>

Derive a child wallet from an existing master key by passing `signingKey.deriveFrom` with a `keyId` and an optional `path`. If `path` is omitted, Dfns auto-generates one.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const wallet = await dfns.wallets.createWallet({
    body: {
      network: 'Ethereum',
      name: 'Customer 0001',
      signingKey: {
        deriveFrom: {
          keyId: 'key-xxx-xxx',
          path: 'm/0/1' // optional, auto-generated if omitted
        }
      }
    }
  })
  ```

  ```go Go theme={null}
  signingKey := map[string]interface{}{
      "deriveFrom": map[string]interface{}{
          "keyId": "key-xxx-xxx",
          "path":  "m/0/1", // optional, auto-generated if omitted
      },
  }
  name := "Customer 0001"
  wallet, err := client.Wallets.CreateWallet(ctx, wallets.CreateWalletRequest{
      Network:    "Ethereum",
      Name:       &name,
      SigningKey: &signingKey,
  })
  ```

  ```python Python theme={null}
  wallet = client.wallets.create_wallet({
      "network": "Ethereum",
      "name": "Customer 0001",
      "signingKey": {
          "deriveFrom": {
              "keyId": "key-xxx-xxx",
              "path": "m/0/1"  # optional, auto-generated if omitted
          }
      }
  })
  ```

  ```java Java theme={null}
  Map<String, Object> signingKey = Map.of(
      "deriveFrom", Map.of(
          "keyId", "key-xxx-xxx",
          "path", "m/0/1" // optional, auto-generated if omitted
      )
  );

  Wallet wallet = client.wallets.createWallet(new CreateWalletRequest(
      Network.Ethereum,
      "Customer 0001",
      signingKey,
      null, null, null, null
  ));
  ```
</CodeGroup>

### Path format

The `path` follows BIP-32 syntax: `m/<index>(/<index>)*`, with non-negative integer indices (e.g., `m/0`, `m/0/1/2`). Hardened paths (with `'`) are not supported.

Each unique path under the same master key derives a distinct wallet with its own address.

## Creating wallets with tags

Use tags to organize wallets and target them with policies:

```typescript theme={null}
const wallet = await dfns.wallets.createWallet({
  body: {
    network: 'Ethereum',
    name: 'Treasury Wallet',
    tags: ['treasury', 'cold-storage', 'eth-mainnet']
  }
})
```

## Managing wallet tags

### Adding tags

```typescript theme={null}
await dfns.wallets.tagWallet({
  walletId: 'wa-xxx-xxx',
  body: {
    tags: ['operations', 'high-volume']
  }
})
```

### Removing tags

```typescript theme={null}
await dfns.wallets.untagWallet({
  walletId: 'wa-xxx-xxx',
  body: {
    tags: ['high-volume'] // Tags to remove
  }
})
```

## Updating wallet metadata

Update the wallet name:

```typescript theme={null}
await dfns.wallets.updateWallet({
  walletId: 'wa-xxx-xxx',
  body: {
    name: 'Updated Wallet Name'
  }
})
```

## Listing wallets

List all wallets in your organization:

```typescript theme={null}
const wallets = await dfns.wallets.listWallets()

for (const wallet of wallets.items) {
  console.log(`${wallet.name}: ${wallet.address} (${wallet.network})`)
}
```

### Filtering by tags

Filter wallets by tags:

```typescript theme={null}
const wallets = await dfns.wallets.listWallets({
  query: {
    tags: 'treasury' // Wallets with this tag
  }
})
```

## Getting wallet details

Get details for a specific wallet:

```typescript theme={null}
const wallet = await dfns.wallets.getWallet({
  walletId: 'wa-xxx-xxx'
})

console.log('Wallet:', wallet)
```

## Getting wallet assets

Retrieve token balances:

```typescript theme={null}
const assets = await dfns.wallets.getWalletAssets({
  walletId: 'wa-xxx-xxx'
})

for (const asset of assets.assets) {
  console.log(`${asset.symbol}: ${asset.balance}`)
}
```

See [displaying balances](/guides/developers/displaying-balances) for more details on working with balances.

## Error handling

Handle common errors:

```typescript theme={null}
try {
  const wallet = await dfns.wallets.createWallet({
    body: {
      network: 'Ethereum',
      name: 'My Wallet'
    }
  })
} catch (error) {
  if (error.status === 403) {
    console.error('Permission denied - check Wallets:Create permission')
  } else if (error.status === 400) {
    console.error('Invalid request:', error.message)
  } else {
    console.error('Error creating wallet:', error)
  }
}
```

## Webhooks

Subscribe to wallet events:

* `wallet.created` - New wallet created
* `wallet.activated` - Wallet activated
* `wallet.tags.modified` - Wallet tags changed

See [webhooks guide](/guides/developers/webhooks) for configuration.

## Related documentation

<CardGroup cols={2}>
  <Card title="Wallets API" icon="book" href="/api-reference/wallets/index">
    Complete API reference
  </Card>

  <Card title="Wallets and keys" icon="key" href="/core-concepts/wallets-and-keys">
    Understand the wallet model
  </Card>

  <Card title="Create transfers via API" icon="paper-plane" href="/guides/developers/create-transfers">
    Send transfers from wallets
  </Card>

  <Card title="Display balances" icon="wallet" href="/guides/developers/displaying-balances">
    Query wallet assets
  </Card>
</CardGroup>
