# lithic-embed

This library provides convenient access to the Lithic Embed API to easily create a modern card experience.

## Installation

```bash
# npm
npm install lithic-embed

# bun
bun add lithic-embed

# pnpm
pnpm add lithic-embed
```

## Getting Started

### Create a Card Embed
```ts
import LithicEmbed, {
    EmbedMountError,
    Environment,
} from "lithic-embed";


// Using your api-key generate a session token from your backend
// See https://docs.lithic.com/reference/createcardembedsession for more information.
const sessionToken = await fetchSessionToken();
const lithicEmbed = new LithicEmbed(Environment.PRODUCTION);

const cardEmbed = lithicEmbed.card(sessionToken);

try {
    await cardEmbed.mountPan("#pan");
} catch (error) {
    if (error instanceof EmbedMountError) {
        // The iframe did not complete its render handshake in time.
    }
}
```

### Using callbacks
You can configure callbacks to handle asynchronous notifications from the embeds.

```ts
import LithicEmbed, {
    CardDetailsRequestError,
    Environment,
    PinSubmissionError,
    EmbedUpdateState,
} from "lithic-embed";

// Using your api-key generate a session token from your backend
const sessionToken = await fetchSessionToken();
const lithicEmbed = new LithicEmbed(Environment.PRODUCTION);

// Individual callbacks are optional and are not required
const cardEmbed = lithicEmbed.card(sessionToken, {
    onCopy: (cardEmbedType: CardEmbedType, success: boolean) => {
        // Handle the whether the copy was successful or not
    },
    onUpdate: (state: EmbedUpdateState) => {
        if (state === EmbedUpdateState.EmbedRendered) {
            // Handle the embed rendered state
        }

        if (state === EmbedUpdateState.EmbedCardDetailsLoaded) {
            // Handle the embed card details loaded state
        }
    },
});
```

### Revealing card details
By default, Lithic embeds are masked with only the pan showing the last 4 digits. To reveal the card details, call `toggleMasking`. `toggleMasking` will fetch and reveal the card details for all mounted card embeds.
```ts
await cardEmbed.mount({
    pan: { selector: "#pan" },
    cvv: { selector: "#cvv" },
    expMonth: { selector: "#expMonth" },
    expYear: { selector: "#expYear" },
});

try {
    await cardEmbed.toggleMasking();
} catch (error) {
    if (error instanceof CardDetailsRequestError) {
        // Handle a card-details request failure or SDK timeout. Locally
        // generated timeout errors do not include a code or request ID.
        console.error(error.code);
        console.error(error.requestId);
    }
}
```

### Automatic style capture and syncing
By default, the `lithic-embed` SDK will sync the styles applied to the mount target.

```ts
const cardEmbed = lithicEmbed.card(sessionToken, {
    syncStyles: true // Default true. Set to false to disable auto syncing of styles.
});

// Any styles applied #pan will be applied to the embed
await cardEmbed.mountPan("#pan");

// Explicit styles take precedence over computed values
await cardEmbed.mountPan("#pan", {
    "color": "white",
    "letter-spacing": "2px"
});
```

Sync updates are debounced (by 100ms) so rapid changes (e.g. an animating theme)
don't flood the iframe with messages.

### Create a PIN-setting Embed

```ts
const pinSettingEmbed = lithicEmbed.pinSetting(sessionToken, {});
await pinSettingEmbed.mount("#pin");

try {
    await pinSettingEmbed.submit();
} catch (error) {
    if (error instanceof PinSubmissionError) {
        // Handle a PIN submission failure or SDK timeout. Locally generated
        // timeout errors do not include a code or request ID.
        console.error(error.code);
        console.error(error.requestId);
    }
}
```
