Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Bundles & variants · Boson Protocol
Skip to content

Bundles & variants

A bundle ships multiple items together under a single offer; the buyer commits once and receives the whole set. A variant is one of several offers for the same product (e.g. small / medium / large t-shirt) grouped under a shared productUuid.

Bundles

Use the BUNDLE metadata schema (@bosonprotocol/metadata). The bundle metadata lists each item with its own productV1 payload plus an aggregate description. Reference: The metadata pipeline and Reference → Metadata schemas.

SDK
// Build a BUNDLE metadata object directly per the schemathere is no
// bundleMetadataFactory export. See ReferenceMetadata schemas for the
// complete shape (required: schemaUrl, type: "BUNDLE", uuid, name,
// description, externalUrl, licenseUrl, image, attributes, items, seller).
const uuid = crypto.randomUUID()
const metadata = {
  schemaUrl: "https://schema.org/Product",
  type: "BUNDLE" as const,
  uuid,
  name: "Hoodie + access pass",
  description: "Bundle: hoodie + 1-year Discord access",
  externalUrl: `https://example.com/${uuid}`,
  licenseUrl: `https://example.com/${uuid}/license`,
  image: "https://cdn.example.com/bundle.jpg",
  attributes: [
    { traitType: "Type", value: "Bundle" },
    { traitType: "Items", value: "2" },
  ],
  items: [
    { type: "ITEM_PRODUCT_V1", productV1: { title: "Hoodie", /* …product fields… */ } },
    { type: "ITEM_NFT", nft: { name: "Discord access pass", /* …nft fields… */ } },
  ],
  seller: { defaultVersion: 1, name: "Your brand", contactLinks: [{ tag: "email", url: "mailto:hi@example.com" }] },
}
const metadataUri = await sdk.storeMetadata(metadata)
await sdk.createOffer({ metadataUri, /* …rest */ })

Variants

There's no special API for variants — you publish multiple offers that share the same productUuid in their metadata. The subgraph's get_all_products_with_not_voided_variants (MCP) / getAllProductsWithNotVoidedVariants (SDK) groups them for you.

// query all variant offers for a product
const products = await sdk.getAllProductsWithNotVoidedVariants({
  where: { productUuid: "<uuid>" },
})

Common gotchas

  • Bundles are one offer, one exchange. The buyer can't redeem one item from a bundle and dispute the other.
  • Variants are separate exchanges. A buyer who wants two sizes commits twice.

Next