Embed widget.

One script tag and a button. The flow opens in a modal on your page, the user signs in their own wallet, and the tokens never touch your site or ours.

Updated 2026-07-29 · HoodLock Team

Install#

Include the script once, then mark any button with data-hoodlock. Everything except that attribute is optional — a lock-only integration is a button with nothing else on it.

html
<script src="https://hoodlock.tech/embed.js" data-key="pk_YOUR_KEY"></script>

<!-- lock is the default mode, so this is the whole integration -->
<button data-hoodlock>Lock tokens</button>

<!-- pre-fill the token so the user cannot pick a different one -->
<button data-hoodlock data-token="0xYourTokenAddress">Lock tokens</button>

<button data-hoodlock data-mode="burn" data-token="0xYourTokenAddress">Burn tokens</button>

<button data-hoodlock data-mode="vesting"
        data-token="0xYourTokenAddress"
        data-beneficiary="0xTeamWallet">Create vesting</button>
Note

0xYourTokenAddress is a placeholder. Insert the real address from your own data when you render the page. It is different on every token page, so it is not a literal string to paste.

Your button keeps your styling#

The widget never touches how your button looks. It attaches a click handler and marks the element as wired; it sets no classes, no inline styles and no attributes that affect appearance. Style the button however you like — Tailwind, CSS modules, a design system component, anything.

This is worth stating plainly because it is the usual objection to embedded widgets: most teams want the functionality and their own design. Here you get both, because the only thing we render is the modal.

Attributes#

On the script tag#

AttributeRequiredWhat it does
data-keyyesYour public API key. Without it the widget logs an error and does nothing.
data-attributionnoSet to off to leave out the “Secured by HoodLock” line.

On a button#

AttributeRequiredWhat it does
data-hoodlockyesMarks the button. Nothing else is needed for a lock.
data-modenolock (default), burn or vesting. An unrecognised value falls back to lock.
data-tokennoPre-fills the token and makes the field read-only. Leave it out and the user picks from their own wallet.
data-beneficiarynoVesting only. Pre-fills the recipient; the user can still edit it.
data-unlocknoLock only. Pre-fills the unlock date as Unix seconds.

JavaScript API#

window.HoodLock is available once the script has loaded.

javascript
// open programmatically
HoodLock.open({ token: "0x…", unlockTime: 1790000000 });
HoodLock.open({ mode: "burn", token: "0x…" });
HoodLock.open({ mode: "vesting", token: "0x…", beneficiary: "0x…" });

// one handler for every product
HoodLock.on("done", ({ type, txHash, id, token, amount }) => {
  console.log(type, id, txHash);   // type: "locked" | "burned" | "vested"
});

// or listen per product
HoodLock.on("locked", ({ txHash, id }) => refreshMyUi(id));

HoodLock.close();   // close the modal
HoodLock.wire();    // re-scan the DOM after rendering new buttons
Note

Call HoodLock.wire() after any client-side render that adds buttons. It only picks up elements it has not already wired, so calling it more than once is safe.

Events#

EventPayloadWhen
readyThe modal has loaded.
connected{ account }The user connected a wallet.
locked / burned / vested{ txHash, id, token, amount }The action succeeded.
donethe same payload plus typeFires alongside each of the three above.
error{ message }Something failed. The message is already human-readable.
closeThe modal was dismissed.
Careful

A payload can carry unconfirmed: true. That means the transaction was broadcast but the receipt could not be fetched. It has most likely landed. Treat it as provisional and confirm against the chain rather than telling the user it failed.

id is the on-chain record id and may be null if it could not be read back. lockId is an alias kept for older integrations.

The attribution line#

The widget adds one small line after the last HoodLock button on the page:

html
<div class="hoodlock-attribution">
  <a href="https://hoodlock.tech" rel="noopener">Secured by HoodLock</a>
</div>

It inherits your text colour, appears once per page regardless of how many buttons you have, and is a plain followable link. Turn it off with data-attribution="off" on the script tag if it does not suit the design.

Framing and CSP#

The modal is an iframe from hoodlock.tech/embed. If your site sends a Content-Security-Policy, allow it:

text
frame-src https://hoodlock.tech;
script-src https://hoodlock.tech;

When the user has no wallet#

In-app browsers sometimes block wallet access inside an iframe. The widget detects that and offers a link that opens the same flow in a new tab, with your key carried through so the action still counts as yours. You do not need to handle it.

Earnings#

You earn 50% of the fee on every lock, burn and vesting schedule created by a wallet you introduced. Only genuinely new wallets count, first touch is permanent, and only actions after attribution qualify. Claim to your wallet from the developer dashboard once the balance passes $10.

Prefer to build the interface yourself? The REST API exposes the same three products as prepared transactions.