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

Platform Marketplace Laravel Package

enjin/platform-marketplace

Enjin Platform Marketplace is a Laravel package that adds NFT marketplace capabilities to Enjin Platform applications. It includes listings, auctions, offers, sales, and wallet integration, helping developers build blockchain-backed marketplaces with familiar Laravel workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

The marketplace package is an add-on to the Enjin Platform — it assumes you already have a working enjin/platform-core install (Laravel app, GraphQL endpoint via Lighthouse, wallet/daemon services configured). Do that first; the marketplace package will not bootstrap a platform on its own.

composer require enjin/platform-marketplace

Laravel's package auto-discovery should register Enjin\Platform\Marketplace\MarketplaceServiceProvider. Confirm it appears in php artisan about or by checking bootstrap/cache/packages.php. If you're on a platform version that disables discovery, add it manually to config/app.php.

Publish and run the scaffolding:

php artisan vendor:publish --provider="Enjin\Platform\Marketplace\MarketplaceServiceProvider"
php artisan migrate

This typically publishes:

  • config/marketplace.php — feature flags, listing fee/royalty defaults, escrow wallet settings, chain references
  • Migrations for the marketplace tables (marketplace_listings, marketplace_sales, marketplace_bids — names vary by version; inspect the published migration folder)
  • GraphQL schema fragments registered against the platform's Lighthouse schema

Where to look first: config/marketplace.php, then the package's src/Models/ directory. The models tell you what state exists and which relationships your application code will hang off. After that, hit your GraphQL endpoint with an introspection query — the marketplace mutations/queries (CreateListing, CancelListing, FillListing, GetListings etc. — names drift between versions) are the real API surface you'll integrate against.

First use case: list a collection's token for sale and query it back. Authenticate as a wallet (the platform's auth flow), call the CreateListing mutation with the token, price, and currency, then verify the listing appears in a GetListings query and that a corresponding row exists in the database. That single loop exercises escrow, signing, and the persistence layer — if it works, most other flows will.

Implementation Patterns

Wrap GraphQL mutations in a service layer. Don't scatter CreateListing calls through controllers. The marketplace mutations almost always touch an on-chain transaction plus a DB row, and you'll want retries, logging, and transaction boundaries in one place.

final class ListingService
{
    public function __construct(private GraphQLClient $graphql) {}

    public function list(Token $token, string $price, string $currency): Listing
    {
        $response = $this->graphql->mutate(CreateListing::class, [
            'tokenId' => $token->uuid,
            'price'   => $price,
            'currency' => $currency,
        ]);

        return Listing::findOrFail($response->listingId);
    }
}

React to domain events. The package fires events around the listing lifecycle (created, filled, cancelled, expired). Bind listeners in a dedicated MarketplaceEventServiceProvider rather than EventServiceProvider so the wiring stays obvious:

protected $listen = [
    \Enjin\Platform\Marketplace\Events\ListingWasFilled::class => [
        SendSellerPayoutNotification::class,
        SyncOwnershipToCrm::class,
    ],
];

Use jobs for anything that signs or broadcasts. On-chain operations are slow and flaky. Queue the marketplace call, put the listing ID in the job payload, and let the job retry with backoff. Give the job an idempotency_key column on your own table so a retried job doesn't double-list the same token.

Query listings by joining on your own data. The marketplace tables are lean; you'll almost always want to join them against your token/collection tables to render "my listings" pages. A read-side repository (or a dedicated MarketplaceListingResource) keeps the N+1s out of your controllers.

Listing::with(['token.collection'])
    ->where('seller_wallet', $wallet->address)
    ->where('status', 'active')
    ->latest()
    ->paginate(25);

Schedule the reconciliation command. Listings expire, on-chain state drifts from DB state, and webhooks get missed. The package usually exposes a marketplace:sync or similar artisan command — schedule it every few minutes as a safety net:

$schedule->command('marketplace:sync')->everyFiveMinutes()->withoutOverlapping();

Layer your own API on top if you're not a GraphQL shop. Many teams wrap the marketplace mutations with a small REST facade and a resource transformer — it keeps frontend contracts stable when the package's GraphQL schema shifts between minor versions.

Gotchas and Tips

  • Version-lock the platform with the marketplace. composer.json in the marketplace package pins a range of enjin/platform-core. Mismatches produce cryptic Lighthouse schema-merge errors at boot rather than at install time. Run composer why enjin/platform-core when the schema won't compile.
  • Migrations can collide with platform-core tables. If you upgrade and see duplicate column or foreign-key errors, check that your published copy of the marketplace migrations hasn't drifted from the package's database/migrations/. Re-publish into a fresh directory and diff.
  • Publish the GraphQL schema after any upgrade. php artisan vendor:publish --tag=marketplace-schema (or the Lighthouse schema merge directive) needs a re-run when the package version bumps. A stale schema silently hides new mutations and you'll debug your client for an hour.
  • Config cache traps. php artisan config:cache is safe, but if you toggled a marketplace feature flag in config/marketplace.php and forgot to clear, the flag is frozen at bootstrap. config:clear after any config edit.
  • Escrow wallet funding. The default config points at a wallet that must be funded with the chain's native token for gas. A listing that "creates successfully" but never appears on-chain is almost always an underfunded wallet — check the daemon logs, not the Laravel log.
  • Queue workers must be restarted on deploy. Class code shipped in a queued job is snapshotted at worker start. php artisan queue:restart in your deploy script, or you'll run yesterday's CreateListing handler against today's schema.
  • Idempotency on the fill path. If you consume sale-completion events, guard against duplicate delivery — the package may emit an event and a webhook for the same fill. Make your listener check the sale's status column before acting.
  • Test with the fake, not the chain. The package ships a fake or sandbox mode (look for marketplace.fake / a MarketplaceFake binding in the test suite). Bind it in tests/TestCase.php and assert on your service layer, not on the package internals — that gives you upgrade resilience.
  • Extension points are thin. This is an integration package, not a framework. If you need behaviour it doesn't expose (custom fee splitting, bid rules), prefer wrapping the mutation in your own service or extending the published models rather than forking — forks of Enjin platform packages compound badly at upgrade time.
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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package