npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@muralpay/browser-sdk

v2.0.1

Published

End-User Custodial Browser SDK for Mural

Downloads

24

Readme

End-User Custodial Browser SDK Documentation

Overview

The End-User Custodial Browser SDK is a TypeScript/JavaScript library that enables secure wallet functionality for browser-based applications. It provides secure key management and transaction signing capabilities.

This guide walks you through the full end-user custodial payout flow:

  1. Initializing the SDK
  2. Triggering a user challenge
  3. Initializing the SDK with a verification code
  4. Signing the payout
  5. Executing the payout

Installation

npm install @muralpay/browser-sdk

1. Create the SDK Instance

Before using the SDK, mount the authentication iframe in your app.

Configuration

| Field | Type | Description | | ------------------- | ------------- | ----------------------------------------------------------- | | iframeContainerId | string | The ID of the HTML element where the iframe will be mounted | | iframeElement | HTMLElement | The actual HTML element (must match the ID above) |

HTML:

<div id="auth-iframe-container-id"></div>

JavaScript:

import { EndUserCustodialSDK } from '@muralpay/browser-sdk';

const sdk = await EndUserCustodialSDK.createInstance({
  iframeContainerId: 'auth-iframe-container-id',
  iframeElement: document.getElementById('auth-iframe-container-id'),
});

2. Trigger Challenge

Trigger an authentication challenge for the user by calling your backend API:

POST /approvers/end-user-custodial/initiate-challenge

Payload:

  • publicKey — Use sdk.getPublicKey()
  • approverId — The end-user custodial user's ID
const publicKey = sdk.getPublicKey();

Response: Contains authorizationId for use in next step.


3. Initialize Session with Verification Code

Once the user receives their email verification code, collect it and call:

await sdk.startSession({
  code: 'code-from-user-email',
  authenticatorId: 'authorization-id-from-initiate-challenge',
});

This creates a secure, authenticated session.


4. Sign the Payout

First, retrieve the payload to sign:

GET /payout/end-user-custodial/body-to-sign/:id
  • :id is the payout request ID

Then sign it:

const signature = await sdk.signPayoutPayload(body); // use the exact body as returned

⚠️ Important: Do not alter the body returned by the API. Modifications will invalidate the signature.


5. Execute the Payout

Send the signature to your backend to execute the payout:

POST /payout/end-user-custodial/execute/:id

Body:

{
  "signature": "<signature-from-sdk>"
}

SDK API Reference

Static Methods

createInstance(config: EndUserCustodialSDKConfig): Promise<EndUserCustodialSDK>

Creates and initializes the SDK instance.

const sdk = await EndUserCustodialSDK.createInstance(config);

Instance Methods

startSession(payload: { code: string, authenticatorId: string }): Promise<void>

Initializes the SDK session using the verification code and authorizationId.

await sdk.startSession({
  code: 'email-code',
  authenticatorId: 'auth-id',
});

getPublicKey(): string

Returns the iframe public key to use in the challenge.

const publicKey = sdk.getPublicKey();

signPayoutPayload(payload: any): Promise<string>

Signs a payout transaction.

const signature = await sdk.signPayoutPayload(body);

isSessionActive(): boolean

Checks if a session is currently active.

if (sdk.isSessionActive()) {
  // Safe to proceed
}

clearSession(): void

Clears the session state.

sdk.clearSession();

getClientSessionExpiry(): Date | null

Returns the session's expiration time.

const expiry = sdk.getClientSessionExpiry();

Full Usage Flow

// 1. Create SDK instance
const sdk = await EndUserCustodialSDK.createInstance({
  iframeContainerId: 'auth-iframe-container-id',
  iframeElement: document.getElementById('auth-iframe-container-id'),
});

// 2. Get public key
const publicKey = sdk.getPublicKey();

// 3. Backend: trigger challenge with publicKey + user ID

// 4. User inputs email code → initialize session
await sdk.startSession({
  code: codeFromUser,
  authenticatorId: authIdFromBackend,
});

// 5. Backend: fetch /body-to-sign/:id
const signature = await sdk.signPayoutPayload(body);

// 6. Backend: send signature to /execute/:id

Type Definitions

interface EndUserCustodialSDKConfig {
  iframeContainerId: string;
  iframeElement: HTMLElement;
}

interface TransactionBodyData {
  to: string;
  value: string;
}

Integration with Mural API

This SDK is designed to work seamlessly with the Mural API to enable complete end-user custodial payment solutions for your customers.

What You Can Build:

  • Customer Management: Create and manage customer accounts
  • End-User Custodial Payments: Enable secure, self-custody transactions
  • Payout Systems: Automated or manual payout workflows
  • Multi-signature Wallets: Enterprise-grade security features

Getting Started:

  1. SDK Integration: Use this browser SDK for frontend wallet functionality
  2. API Integration: Connect your backend to our Mural API for customer management
  3. Complete Flow: Customers can securely sign transactions without you holding their keys

For API documentation, integration examples, and technical support, contact us at [email protected]


Error Handling

The SDK throws clear errors for:

  • Missing config or parameters
  • Invalid or expired sessions
  • Incorrect or altered payloads
  • Network or signing failures

Wrap all SDK interactions in try/catch:

try {
  const sdk = await EndUserCustodialSDK.createInstance(...);
} catch (err) {
  console.error('SDK error:', err);
}

Support & Contact

Questions about integration? We're here to help!

  • 📧 Email: [email protected]
  • 🔧 Technical Support: API documentation, integration examples, and troubleshooting
  • 💼 Business Inquiries: Custom solutions and enterprise features

License

MIT © Mural Pay Inc.