Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Yoclib Multibase Laravel Package

yocto/yoclib-multibase

A PHP library for Multibase encoding and decoding, enabling self-describing base-encoded strings with prefix handling. Suitable for IPFS, CID, and decentralized identifier tooling that needs consistent support across multiple base encodings.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the library with Composer — there is no Laravel service provider or config file shipped, so you wire it up yourself:

composer require yocto/yoclib-multibase

The entry point is a static Multibase class under the YocLib\Multibase namespace. Open vendor/yocto/yoclib-multibase/src/ first — confirm the exact method signatures before you build on them, because the package ships no docs and the API surface is small enough to read in one sitting. The typical shape is:

use YocLib\Multibase\Multibase;

// Encode raw bytes, prefixed with the multibase indicator ('z' = base58btc, 'f' = base16, 'b' = base32, 'm' = base64)
$encoded = Multibase::encode('base58btc', $binary);

// Decode back to raw bytes — the prefix character tells the library which base to use
$binary = Multibase::decode($encoded);

As of v1.2.0 the supported set now includes Base45, Proquint, and Base256emoji alongside the original base16/32/32hex/58btc/64 variants. Prefix detection is now UTF-8 aware, which matters because Base256emoji uses a multi-byte emoji as the multibase prefix (see Gotchas).

A realistic first use case in a Laravel app is handling DID keys, CIDs, or IPFS-style identifiers coming from an external API. You receive a string like z6Mk... and need to validate it and pull out the raw bytes:

public function show(string $did)
{
    try {
        $decoded = Multibase::decode($did);
    } catch (\Throwable $e) {
        abort(422, 'Invalid multibase string');
    }
    return response()->json(['bytes' => bin2hex($decoded)]);
}

Start small: one decode path, wrapped in a try/catch, before you build abstractions around it.

Implementation Patterns

Wrap it in a dedicated service. Because the library is a static utility with no Laravel integration, hide it behind a small injectable class so you can mock it in tests and swap it later:

// app/Services/MultibaseCodec.php
namespace App\Services;

use YocLib\Multibase\Multibase;

class MultibaseCodec
{
    public function encode(string $base, string $bytes): string
    {
        return Multibase::encode($base, $bytes);
    }

    public function decode(string $value): string
    {
        return Multibase::decode($value);
    }

    public function isMultibase(string $value): bool
    {
        try { Multibase::decode($value); return true; }
        catch (\Throwable) { return false; }
    }
}

Bind it as a singleton in a ServiceProvider if you prefer that (stateless, so it barely matters).

Custom validation rule. This is the highest-leverage integration — validate multibase input at the request boundary so a malformed DID/CID never reaches your domain logic:

// app/Rules/ValidMultibase.php
public function passes($attribute, $value): bool
{
    return is_string($value) && app(MultibaseCodec::class)->isMultibase($value);
}

Store as string, decode on demand. Multibase strings are UTF-8 text (the prefix + base-encoded payload), so a normal varchar/text column is correct. Keep the raw string in the DB, not the decoded bytes, unless you need byte-level queries. Add an index if you look records up by DID/CID. Ensure the column is utf8mb4 if you accept Base256emoji-prefixed values (they contain 4-byte emoji).

API resources. When returning a multibase identifier to a client, return the string as-is. Don't re-encode for transport; the prefix is part of the contract.

Picking a base for new data. For opaque keys/CIDs, base58btc (z) remains the conventional default. Reach for the new encodings only when the spec you're integrating with requires them — base45 for EU Digital COVID Certificate-style payloads, proquint where you want human-readable/memorable identifiers, base256emoji where the wire format expects emoji.

Debugging command. Multibase bugs are almost always "wrong prefix" — and since v1.2.0 the prefix can be a multi-byte UTF-8 emoji, so read it with mb_substr, not $value[0]:

php artisan multibase:inspect z6Mk...
// prefix: z -> base58btc, bytes: 0x...

php artisan multibase:inspect 🚀...
// prefix: 🚀 -> base256emoji, bytes: 0x...

Use mb_substr($value, 0, 1, 'UTF-8') when surfacing the prefix to a human.

Testing. Because the library is pure and static, write a Pest test that round-trips representative strings across every base you actually consume and asserts exceptions on garbage input. Add cases for the new encodings (base45, proquint, base256emoji) if you accept them, and include at least one emoji-prefixed string to exercise the UTF-8-aware detection path. That pins behavior if the vendor upgrades.

Gotchas and Tips

  • GPL-3.0 license. This is the biggest practical issue. GPL is copyleft and, depending on how you link it, can impose obligations on distributed software. For a closed-source commercial Laravel SaaS this needs a legal review before shipping — or a permissive alternative (a multiformats implementation, or hand-rolled prefix + paragonie/constant_time_encoding/base58 lib). Don't skip this.
  • Maintenance risk. Still a small, single-maintainer package with limited adoption, though v1.2.0 shows it's actively evolving. Treat it as vendored code: pin the exact version in composer.json and be ready to fork. It's tiny enough to copy into app/Support/ if you want to eliminate the dependency and sidestep the license.
  • Prefix detection is now UTF-8 aware (v1.2.0) — but your own code must be too. Before this release the prefix was a single ASCII byte, so $value[0] was safe. With Base256emoji in the mix, a prefix can be a multi-byte emoji, and $value[0] returns just the first byte of it. Any of your own tooling that inspects prefixes (loggers, debug commands, validation shims) must switch to mb_substr($value, 0, 1, 'UTF-8'). Verify any pre-existing code that used $value[0].
  • Decoded output is raw bytes, not UTF-8. Don't echo or json_encode a decoded value and expect readable text. Use bin2hex(), base64_encode(), or a dedicated byte-handling path. Conversely, when encoding, the input must be binary — encoding a PHP string works but encodes its bytes, not "the text".
  • Prefix drives everything. Known prefixes: z (base58btc), f (base16/hex), b/B (base32/base32upper), m/M/u (base64 variants), plus the new base45, proquint, and base256emoji indicators. If decode fails, dump the first character with mb_substr($value, 0, 1, 'UTF-8') — the library picks the algorithm from that character and will error on an unknown one.
  • Emoji input, emoji storage. Base256emoji payloads are 4-byte UTF-8 code points. Store them in utf8mb4 columns, JSON-encode with JSON_UNESCAPED_UNICODE so they survive transport, and be mindful of request size/post_max_size only if payloads are large (they won't be for typical keys, but they're longer per character than base58btc).
  • Empty vs null input. Guard against null/empty strings before calling decode; you'll usually get an exception rather than a sensible default. Cast and check in a form request.
  • Exceptions are generic. Catch broadly (\Throwable) at the boundary and translate to a 422/ValidationException. Don't leak vendor exception messages to API consumers.
  • No config, no facade, no auto-discovery. Any "default base" concept is yours to define — put it in config/multibase.php and inject it, rather than hardcoding 'base58btc' across controllers.
  • Multibase is encoding, not encryption or signing. Reviewers sometimes see z6Mk... and assume it's secure. It's a self-describing base encoding; combine with the relevant crypto library (multihash/signature verification) for actual integrity guarantees.
  • Extension points are essentially nil. The package has no events, hooks, or drivers. v1.2.0 widened coverage (Base45/Proquint/Base256emoji) but the model is still a closed set of statics — if you need extra behaviour or a different base, you'll fork it. Another reason to wrap it behind your own service so a fork is a one-file swap.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log