<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>OpenSea for Developers</title>
        <link>https://paragraph.com/@sea-2</link>
        <description>Announcements and updates from the OpenSea Developer Platform.  Stay in the loop on launches, updates, best practices, and more.</description>
        <lastBuildDate>Fri, 03 Apr 2026 17:53:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>OpenSea for Developers</title>
            <url>https://storage.googleapis.com/papyrus_images/73aa8bea8de2d0711ca1d426ea6e0a069e3b74a2a61581f643d9f68d526bf090.png</url>
            <link>https://paragraph.com/@sea-2</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Next steps on Seaport migration]]></title>
            <link>https://paragraph.com/@sea-2/next-steps-on-seaport-migration</link>
            <guid>SL3vermXOhXYcWqUAAxS</guid>
            <pubDate>Tue, 14 Jun 2022 21:16:02 GMT</pubDate>
            <description><![CDATA[Earlier today, we announced that we’ve started to migrate to Seaport, a new web3 marketplace protocol designed for safely and efficiently buying and selling NFTs. Following up on our detailed migration guide for developers that we had shared a few weeks ago, we’re highlighting the implications for developers at this milestone. To recap, here’s what developers can expect from today (June 14) forward: June 14 ✅ API: Begin using the new Seaport offers and listings endpoints on Mainnet ✅ API: Beg...]]></description>
            <content:encoded><![CDATA[<p>Earlier today, we <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/blog/announcements/launching-seaport-saving-the-community-millions-in-fees/">announced</a> that we’ve started to migrate to <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/blog/announcements/introducing-seaport-protocol/">Seaport</a>, a new web3 marketplace protocol designed for safely and efficiently buying and selling NFTs.  Following up on our <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://nft.mirror.xyz/Bi_UbdXOi4AU3LtHT3WoLAN0a9YIWE2gYQmkyZ5whVM">detailed migration guide for developers</a> that we had shared a few weeks ago, we’re highlighting the implications for developers at this milestone.</p><p>To recap, here’s what developers can expect from today (June 14) forward:</p><p><strong>June 14</strong></p><p>✅ <strong>API:</strong> Begin using the new Seaport <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/v2.0/reference/retrieve-offers">offers</a> and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/v2.0/reference/retrieve-listings">listings</a> endpoints on Mainnet</p><p>✅ <strong>API:</strong> Begin parsing new Seaport offers and listings from <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/getting-assets">/assets</a> and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/retrieving-bundles">/bundles</a> endpoints on Testnets</p><p>✅ <strong>SDK:</strong> Begin using new Seaport-ready functions in <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.npmjs.com/package/opensea-js">SDK v4.0.0</a> on Mainnet</p><p><strong>June 21</strong></p><p>✅ <strong>API+ SDK:</strong> Offers and listings can no longer be posted to <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/address/0x7f268357a8c2552623316e2562d90e642bb538e5">Wyvern v2.3 contract</a> using OpenSea</p><p><strong>July 13</strong></p><p>✅ <strong>API + SDK:</strong> Offers and listings can no longer be fetched from <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/address/0x7f268357a8c2552623316e2562d90e642bb538e5">Wyvern v2.3 contract</a> using OpenSea</p><p>For more details on each of these updates, please refer back to our <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://nft.mirror.xyz/Bi_UbdXOi4AU3LtHT3WoLAN0a9YIWE2gYQmkyZ5whVM">detailed Seaport migration guide</a>.  If you have any questions, please <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/channels/397566282729390110/434175585745633280">reach out on Discord</a> as we’re here to help.</p>]]></content:encoded>
            <author>sea-2@newsletter.paragraph.com (OpenSea for Developers)</author>
        </item>
        <item>
            <title><![CDATA[Open-sourcing Seaport data abstraction
]]></title>
            <link>https://paragraph.com/@sea-2/open-sourcing-seaport-data-abstraction</link>
            <guid>MShUDRSeI0UFKyeIu3dQ</guid>
            <pubDate>Tue, 14 Jun 2022 05:09:17 GMT</pubDate>
            <description><![CDATA[Over the next few days, OpenSea will be migrating to Seaport, a brand new web3 marketplace protocol designed for safely and efficiently buying and selling NFTs. We’re going to be one of the first marketplaces using the core Seaport smart contract to build new features for the OpenSea community. Seaport as a protocol is decentralized and open source - anyone can use it, with no contract owner, upgradeability, or other special privileges. In that spirit, we’re also sharing the Seaport Dune abst...]]></description>
            <content:encoded><![CDATA[<p>Over the next few days, OpenSea will be migrating to <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/blog/announcements/introducing-seaport-protocol/">Seaport</a>, a brand new web3 marketplace protocol designed for safely and efficiently buying and selling NFTs. We’re going to be one of the first marketplaces using the core Seaport smart contract to build new features for the OpenSea community. </p><p>Seaport as a protocol is decentralized and open source - anyone can use it, with no contract owner, upgradeability, or other special privileges. <strong>In that spirit, we’re also sharing the Seaport Dune abstraction table that will allow anyone to easily and quickly query transactions made on Seaport.</strong> </p><p>While it’s most directly useful for Dune wizards, we believe this query structure and explanation could also be useful for any on-chain sleuths, and any services utilizing blockchain data. The query structure should help you understand how the on-chain data maps into transaction data -- including variables such as purchase types (e.g. if transaction was a standard offer, collection offer or attribute offer) and number of NFTs transacted.</p><h3 id="h-calls-and-successful-transactions" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Calls and successful transactions</h3><p>Similar to Wyvern, Seaport broadly has two types of tables: calls and completed transactions tables. </p><p><strong>The calls tables</strong>, e.g. seaport.&quot;Seaport_call_fulfillAdvancedOrder&quot; (where collection and trait offer calls live), include all attempted transactions that are submitted on chain, including failed transactions. These tables are where we get the data we need to categorize transactions into different purchase types (e.g. buy now or collection offer).</p><p><strong>The transaction completed tables</strong>, most notably seaport.&quot;Seaport_evt_OrderFulfilled&quot;, is where we find successful transactions through Seaport. This is where we get data on the final purchase amount and fees.</p><h3 id="h-offers-and-considerations" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Offers and considerations</h3><p>Seaport is very different from Wyvern in its usage of offers and considerations. As we shared in our <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/blog/announcements/introducing-seaport-protocol/">last blog post</a>, offerers can agree to supply a number of ETH / ERC20 / ERC721 / ERC1155 items — this is the “offer.” In order for that offer to be accepted, a number of items must be received by the recipients indicated by the offerer — this is the “consideration.” </p><p>The call and transaction tables include data on both offers and considerations in json arrays. In the abstraction, we turn this data into an easily query-able unique transaction-level table that is formatted similarly to Dune’s current nft.trades table - with some additions (e.g., fees, number of NFTs transacted).</p><p>Currently, the query supports offers, auctions, private sales, bundles, bulk purchase and buy now transactions involving transfers of ERC-721 and ERC-1155 NFTs for ERC-20 tokens like Ether. We will continue to update this abstraction and documentation as the community begins to more fully explore Seaport. </p><h3 id="h-zones" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Zones</h3><p> We also separate out “zone” as a variable. A zone is an account (usually a contract) that performs additional validation prior to fulfillment, and that can cancel the listing on behalf of the offerer. OpenSea’s current zones are 0xf397619df7bfd4d1657ea9bdd9df7ff888731a11, 0x9b814233894cd227f561b78cc65891aa55c62ad2, and 0x004c00500000ad104d7dbd00e3ae0a5c00560c00.</p><p>But Seaport is a flexible, open protocol, and we look forward to seeing many more “zones” pop up and use the contract. You can use this abstraction to query data for different zones as well -- just change the zone you’re selecting for 😎</p><h3 id="h-how-do-i-use-it" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">How do I use it?</h3><p>The fully-commented query is available <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/duneanalytics/abstractions/pull/1157/commits/3b35e22d0fcfeefe813f32d1339d1b449128b913">here</a> if you want to dig into how it works. You can also simply query the abstraction table from Dune: the table name is <strong>seaport.view_transactions</strong>. Many thanks to <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dune.com/sohwak">@sohwak</a>, our amazing Dune wizard who wrote this super efficient query! Also special shout out to our frens at Dune, who have been amazing to work with throughout this process.</p><p>We will release a larger OpenSea Dune abstraction soon, that will make it even easier to query OpenSea data across Wyvern and Seaport. We’ll also work with Dune on making Seaport part of nft.trades. These are all part of our larger efforts to engage more with our community through data -- including through our recent community analytics bounty program.</p><p>This is just the beginning. We look forward to bringing the community more new features -- and more data! -- much faster. LFG! 💪</p>]]></content:encoded>
            <author>sea-2@newsletter.paragraph.com (OpenSea for Developers)</author>
        </item>
        <item>
            <title><![CDATA[Horton Hears A Who!]]></title>
            <link>https://paragraph.com/@sea-2/horton-hears-a-who</link>
            <guid>PlDDfGZvOwq2BnLPkSkG</guid>
            <pubDate>Fri, 10 Jun 2022 18:51:38 GMT</pubDate>
            <description><![CDATA[Horton Hears A Who!Neutralizing a critical vulnerability in Wyvern Protocol — TL;DR — In Q1 of 2022, a security researcher reported a critical vulnerability in the Wyvern 2.2 smart contracts that powered OpenSea. The vulnerability was neutralized before it could be exploited, and users are no longer at risk. We awarded the vulnerability reporter a bug bounty. Historical blockchain logs provide no indication that the vulnerability was ever exploited in the wild. — The “Horton Principle” is a m...]]></description>
            <content:encoded><![CDATA[<h1 id="h-horton-hears-a-who" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Horton Hears A Who!</h1><p>Neutralizing a critical vulnerability in Wyvern Protocol</p><p>—</p><p><strong>TL;DR</strong> — In Q1 of 2022, a security researcher reported a critical vulnerability in the Wyvern 2.2 smart contracts that powered OpenSea. The vulnerability was neutralized before it could be exploited, and users are no longer at risk. We awarded the vulnerability reporter a bug bounty. Historical blockchain logs provide no indication that the vulnerability was ever exploited in the wild.</p><p>—</p><p>The “Horton Principle” is a maxim in designing cryptographic systems that says “mean what you sign and sign what you mean.” Earlier this year, a security researcher pseudonymously named Gus reached out to OpenSea to disclose a violation of this rule uncovered in Wyvern 2.2 — the core smart contract that powered OpenSea’s marketplace.</p><p>The researcher, in cooperation with the OpenSea security team, Wyvern protocol developers, and @samczsun, discovered that the vulnerability could be leveraged to steal offered WETH from the wallets of a subset of users with active offers on the OpenSea marketplace. The vulnerability required no action on the part of the user to exploit — certain users who had signed legitimate listings or offers in the past were at risk even if they took no further action.</p><p>This is the story of how the community – including Wyvern core developers, security researchers, and OpenSea – neutralized the vulnerability before it could impact users.</p><h2 id="h-the-vulnerability" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">The Vulnerability</h2><p>In the architecture of the Wyvern protocol, users author listings or offers off-chain by signing over commitments to the specifics of the listing or offer — most typically, parameters indicating an intent such as &quot;I want to sell Bored Ape #312 for 100 WETH.&quot; These off-chain listings or offers can then be accepted by a counterparty using the Wyvern contracts on the Ethereum blockchain. For example, someone might elect to buy your listed NFT, in which case they would submit the signature you provided along with the listing or offer data in a call to the Wyvern contracts, and provide the payment required (which would go to you, less any fees).</p><p>Wyvern listings contain many different parameters used to indicate listing or offer information and authenticate other involved smart contract calls, which are aggregated together into a single commitment that the user signs and the contract checks –thus ensuring that items are only transferred if the user actually approves the listing or offer. Several of these parameters are variable-length, and the Wyvern 2.2 contracts (written before later standards in ABI encoding) concatenated them together without proper domain separation:</p><pre data-type="codeBlock" text="index = ArrayUtils.unsafeWriteAddress(index, order.target);
index = ArrayUtils.unsafeWriteUint8(index, uint8(order.howToCall));
index = ArrayUtils.unsafeWriteBytes(index, order.calldata);
index = ArrayUtils.unsafeWriteBytes(index, order.replacementPattern);
index = ArrayUtils.unsafeWriteAddress(index, order.staticTarget);
index = ArrayUtils.unsafeWriteBytes(index, order.staticExtradata);
index = ArrayUtils.unsafeWriteAddress(index, order.paymentToken);
"><code>index <span class="hljs-operator">=</span> ArrayUtils.unsafeWriteAddress(index, order.target);
index <span class="hljs-operator">=</span> ArrayUtils.unsafeWriteUint8(index, <span class="hljs-keyword">uint8</span>(order.howToCall));
index <span class="hljs-operator">=</span> ArrayUtils.unsafeWriteBytes(index, order.calldata);
index <span class="hljs-operator">=</span> ArrayUtils.unsafeWriteBytes(index, order.replacementPattern);
index <span class="hljs-operator">=</span> ArrayUtils.unsafeWriteAddress(index, order.staticTarget);
index <span class="hljs-operator">=</span> ArrayUtils.unsafeWriteBytes(index, order.staticExtradata);
index <span class="hljs-operator">=</span> ArrayUtils.unsafeWriteAddress(index, order.paymentToken);
</code></pre><p>Note particularly the three lines appending variable length byte arrays to the temporary array (which is hashed afterwards). In this implementation, orders with different parameters - say <code>calldata = 0x01</code> and <code>replacementPattern = 0x0101</code> and <code>calldata = 0x0101</code> and <code>replacementPattern = 0x01</code> - would have resulted in the same computed commitment. Due to this sort of collision, a clever adversary could have taken a signature from one listing or offer and come up with a different listing or offer - not signed by the user but resulting in the same commitment - that would have been considered by the smart contract to be valid. More specifically, bytes could be &quot;shifted&quot; by an attacker between <code>order.calldata</code>, <code>order.replacementPattern</code>, and <code>order.staticExtradata</code>, to create an offer or listing with different semantics that would result in the same commitment.</p><p>In order to understand the particular way by which this can be exploited, it&apos;s important to understand how Wyvern works under the hood.</p><h3 id="h-calldata-and-replacement-pattern" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Calldata and Replacement Pattern</h3><p>In the Wyvern system, digital items (such as NFTs) can be effectively &quot;swapped&quot; for other digital items via arbitrarily complex smart contract transactions. To allow this, listings or offers specify <code>calldata</code> with which the Wyvern contracts will call a given <code>target</code> contract in exchange for the listing or offer amount. In many cases, it is desirable for the <code>calldata</code> to be mutated at time of fulfillment (in a highly constrained way).</p><p>This is accomplished generically through the concept of a <code>replacementPattern</code> — a bitmask that the listing or offer maker commits to that specifies the portions of the <code>calldata</code> the listing or offer maker is willing to have mutated by the taker. When the listing or offer is filled, the taker passes in <code>calldata</code> that is mutated to their liking, and the Wyvern contracts apply the bitmask from the <code>replacementPattern</code> in order to determine the bits in the final <code>calldata</code> that the taker is allowed to submit mutated.</p><p>Why exactly is this clever machinery needed? Consider the following example:</p><p>In OpenSea <em>offers</em>, the offer specifies that Wyvern must successfully call the <code>transferFrom</code> function on an ERC721 on the Ethereum blockchain in order for payment to be transferred to the offer taker. However, since the address of the taker is not known at the time of offer creation (offers are made specific to NFTs, not their holders), the offer must allow the taker to specify their address as the <code>from</code> in the <code>transferFrom</code> call at time of order fulfillment. Thus, the above mechanism is used to let the offer taker specifically mutate the portions of the <code>transferFrom</code> calldata that specify the transfer&apos;s <code>from</code> value.</p><p>This capability, in tandem with the Horton principle violation, is the crux of how this exploit could have materialized.</p><h3 id="h-the-exploit" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">The Exploit</h3><p>The first 4 bytes of <code>calldata</code> specify which function should be called on a target contract. These bytes are called the <em>function selector</em> and are the first 4 bytes of the SHA3 hash of the function signature. In the above example, the function selector is <code>0x23b872dd</code> and corresponds to the signature <code>transferFrom(address,address,uint256)</code>. This function inputs 3 parameters: <code>address from, address to, uint tokenId</code>.</p><p>Violating Horton&apos;s principle allows for several potential exploits. The most potent of these was that, in certain clever cases, the attacker could &quot;shift bytes&quot; between the <code>callData</code> and <code>replacementPattern</code> in a manner that modified the resultant function selector that was called.</p><p>The function whose selector is &quot;closest&quot; (fewest bits differ) to <code>transferFrom</code> is the function <code>getApproved(uint)</code> with the selector <code>0x081812fc</code>. Only 10 bits differ between it and the function selector for <code>transferFrom</code>.</p><p>There is a 1 in 1024 chance that a random, 4 byte bitmask has ones in the correct places such that, when applied through the <code>replacementPattern</code> mechanism, the function selector would change from <code>0x23b872dd</code> to <code>0x081812fc</code>. Conveniently, an ETH address is effectively 20 random bytes.</p><p>Recall that, because of the Horton principle violation, an attacker can effectively shift adjacent bytes between the <code>calldata</code>, <code>replacementPattern</code>, <code>staticTarget</code> and <code>staticExtradata</code> values while arriving at the same order hash. Notably, an attacker could convince the Wyvern contracts that the order maker signed the former of these two payloads, when they in fact signed the latter:</p><pre data-type="codeBlock" text="// Malicious payload
...
&apos;calldata&apos;: &apos;0x23b872dd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6005af36&apos;, 
&apos;replacementPattern&apos;: &apos;0x6bfa60bbdba5966b9209e81567dedb00000000000000000000000000000000000000000000000000000000000002b300000000ffff&apos;, 
&apos;staticTarget&apos;: &apos;0xffffffffffffffffffffffffffffffffffffffff&apos;, 
&apos;staticExtradata&apos;: &apos;0xffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
...

// True payload
...
&apos;calldata&apos;: &apos;0x23b872dd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6005af366bfa60bbdba5966b9209e81567dedb00000000000000000000000000000000000000000000000000000000000002b3&apos;, 
&apos;replacementPattern&apos;: &apos;0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&apos;, 
&apos;staticTarget&apos;: &apos;0x0000000000000000000000000000000000000000&apos;, 
&apos;staticExtradata&apos;: &apos;0x&apos;,
...
"><code><span class="hljs-comment">// Malicious payload</span>
...
<span class="hljs-string">'calldata'</span>: <span class="hljs-string">'0x23b872dd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6005af36'</span>, 
<span class="hljs-string">'replacementPattern'</span>: <span class="hljs-string">'0x6bfa60bbdba5966b9209e81567dedb00000000000000000000000000000000000000000000000000000000000002b300000000ffff'</span>, 
<span class="hljs-string">'staticTarget'</span>: <span class="hljs-string">'0xffffffffffffffffffffffffffffffffffffffff'</span>, 
<span class="hljs-string">'staticExtradata'</span>: <span class="hljs-string">'0xffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
...

// True payload
...
'</span><span class="hljs-keyword">calldata</span><span class="hljs-string">': '</span><span class="hljs-number">0x23b872dd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6005af366bfa60bbdba5966b9209e81567dedb00000000000000000000000000000000000000000000000000000000000002b3</span><span class="hljs-string">', 
'</span>replacementPattern<span class="hljs-string">': '</span><span class="hljs-number">0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><span class="hljs-string">', 
'</span>staticTarget<span class="hljs-string">': '</span><span class="hljs-number">0x0000000000000000000000000000000000000000</span><span class="hljs-string">', 
'</span>staticExtradata<span class="hljs-string">': '</span>0x<span class="hljs-string">',
...
</span></code></pre><p>We can see that, in this example, our hypothetical attacker has shifted the last 15 bytes of the maker&apos;s address (which, in the true payload, is part of their specified &quot;fixed&quot; calldata) into the start of the <code>replacementPattern</code>.</p><p>The 4 bytes <code>0x6bfa60bb</code> in the maker&apos;s address, coincidentally, have 1 bits in the places corresponding to the bitwise difference between <code>transferFrom</code> and <code>getApproved</code>. In turn, the attacker would be able to fulfill the order with calldata specifying a call to <code>getApproved(0)</code> instead of <code>transferFrom</code>:</p><pre data-type="codeBlock" text="...
&apos;calldata&apos; &apos;0x081812fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6005af36&apos;
...
"><code>...
<span class="hljs-string">'calldata'</span> <span class="hljs-string">'0x081812fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6005af36'</span>
...
</code></pre><p>The function call <code>getApproved(0)</code> does not revert for 0-indexed ERC721 contracts and is also a view function, which does not update the state of the contract. <strong>If this exploit had been carried out, this would have allowed an attacker to fulfill an offer without sending or even owning the NFT the buyer wanted, while still being paid the victim&apos;s WETH</strong>.</p><p>Given that the attacker could shift the <code>replacementPattern</code> to start at any point in the address, the attacker could extract 16 different 4 byte starts to the replacementPattern. <strong>This means approximately 1 in 64 offers could have been exploitable.</strong></p><h2 id="h-the-remediation" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">The Remediation</h2><p>The OpenSea team was immediately compelled to action by the report of the vulnerability — the only way to protect our users was to migrate OpenSea’s listings and offers to a new version of Wyvern and disable Wyvern 2.2. The Wyvern governance contracts, however, mandate an upgrade timelock period of at least 14 days — meaning that, if we were not careful, we would incidentally alert potential attackers to the presence of the vulnerability before it had been neutralized.</p><p>Coincidentally, at this same time, OpenSea’s users were facing a persistent but unrelated issue: “hidden” listings. We have <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/blog/safety-security/important-updates-for-listing-and-delisting-your-nfts/">written extensively</a> about the hidden listings issue, as well as the steps OpenSea has taken to help prevent similar attacks in the future.</p><p>It was clear that our best option was to “kill two birds with one stone” by initiating an upgrade that would solve both issues. We did this by including a new feature in the Wyvern 2.3 upgrade — <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-712">EIP712</a> support, which implements a signature protocol that is not vulnerable to the Horton principle violation described above.</p><p>Our security &amp; protocol teams raced to implement the Wyvern 2.3 contracts, and were fortunate to have Trail of Bits conduct an audit of the new contracts before their submission to the Wyvern DAO.</p><p>On February 18th, in partnership with the Wyvern governance community, we <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/tx/0x86d2f2ed1dba451e0a1bc769aba907406e9fb61ba19ed1068195a584c73b2db2">commenced the upgrade to Wyvern 2.3</a> and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/blog/announcements/announcing-a-contract-upgrade/">announced the migration publicly</a>. Wyvern DAO stakeholders approved the upgrade proposal promptly and the two-week new version upgrade timer began its countdown.</p><p>Wyvern 2.3 was successfully migrated to on Feb. 25th and Wyvern 2.2 (the vulnerable smart contract) was <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/tx/0xad3cb068050c2233663d00423a7d3dbb7701d9df5a8975c31b0ce1a3f303cbe3">disabled through Wyvern governance</a> at the same time.</p><p>Our reviews of on-chain logs indicate that the vulnerability was fortunately never exploited in the wild.</p><p><strong>For his responsible participation in the OpenSea bug bounty program, security researcher Gus was awarded a $3m bounty. We are thrilled to have seen the bug bounty program accomplish its stated goal in securing our users, and encourage other security professionals to submit any vulnerability reports through</strong> <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://hackerone.com/opensea">our Hacker One page</a><strong>.</strong></p><h1 id="h-acknowledgements" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Acknowledgements</h1><p>Wyvern 2.3 is, at time of writing, the most used smart contract on Ethereum. Neutralizing a vulnerability in it was an incredibly delicate and high-stakes operation, and we at OpenSea are enormously grateful to everyone who lent time to this effort.</p><p>First and foremost — thank you to Gus for his responsible and productive participation in the OpenSea bug bounty program.</p><p>Second — we thank members of the broader community: the Wyvern core developers &amp; community, @samczsun, and Trail of Bits.</p><p>Lastly — we want to acknowledge the tireless work of individual contributors on our team who lent countless nights and weekends to this effort.</p><h2 id="h-faq" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">FAQ</h2><p><strong>There was a lot of talk on Twitter about OpenSea users getting phished in late February — was that related to this vunerability?</strong></p><p>No — at the tail-end of the Wyvern 2.3 migration, approximately 10 OpenSea users were subjected to phishing attacks that occurred off of the OpenSea website. The phishing transactions did not leverage the above vulnerability in any capacity. Thankfully, the EIP712 standard that was launched in Wyvern 2.3 makes it much more difficult for attackers to dupe users into signing malicious payloads.</p><p><strong>Was Wyvern 2.2 ever audited by third parties?</strong></p><p>Yes — an audit was conducted by <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ProjectWyvern/wyvern-ethereum/blob/master/audits/v2/solidified_v2_audit_report.pdf">Solidified</a>. Audits — though critical as a backstop for security — are not a silver bullet, and sometimes miss critical vulnerabilities, as illustrated by this case. This underscores the importance of bug bounty programs in the smart contract security space.</p><p><strong>Where can I learn more about OpenSea&apos;s bug bounty program?</strong></p><p>Information on OpenSea&apos;s bug bounty program can be found on <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://hackerone.com/opensea">HackerOne</a>. Notably, we&apos;ve recently updated our HackerOne to reflect the higher tier with which we pay out disclosures for critical vulnerabilities on the smart contracts we leverage.</p>]]></content:encoded>
            <author>sea-2@newsletter.paragraph.com (OpenSea for Developers)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/e92d0be61587e42e678d52645cc827da95dc1b5fc525c5fe93eb85985a5831d2.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Migrating to the Seaport protocol]]></title>
            <link>https://paragraph.com/@sea-2/migrating-to-the-seaport-protocol</link>
            <guid>zpcO5IToKvghI9u3rEBz</guid>
            <pubDate>Wed, 25 May 2022 20:54:05 GMT</pubDate>
            <description><![CDATA[Last week, we unpacked the early details of OpenSea’s new open-source protocol – Seaport – for the developer community. Seaport will become the foundation for OpenSea’s core products, unlocking a range of new use cases for creators, collectors, and the broader developer ecosystem. The protocol is non-custodial, non-upgradeable, and decentralized at its core — it belongs to the community first & foremost. And in that spirit, we’re inviting the community to join us in early testing via a $1M Co...]]></description>
            <content:encoded><![CDATA[<p>Last week, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/blog/announcements/introducing-seaport-protocol/">we unpacked the early details</a> of OpenSea’s new open-source protocol – Seaport – for the developer community. Seaport will become the foundation for OpenSea’s core products, unlocking a range of new use cases for creators, collectors, and the broader developer ecosystem. The protocol is non-custodial, non-upgradeable, and decentralized at its core — it belongs to the community first &amp; foremost. And in that spirit, we’re inviting the community to join us in early testing via a $1M <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://code4rena.com/contests/2022-05-opensea-seaport-contest">Code4rena contest</a>.</p><p>The new Seaport protocol will open up a range of new paths for OpenSea and the developer ecosystem more broadly:</p><ul><li><p>A composable, open-source contract on top of which developers can build their own marketplaces</p></li><li><p>The ability to create custom rulesets for the fulfillment of a listing or offer, using a concept called “zones”</p></li><li><p>Support for multiple fees and custom creator fees</p></li><li><p>Potential for new types of transactions: collection offers and batch fulfillment (including floor sweeping), batch listing, and more</p></li></ul><h2 id="h-required-changes-for-developers" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Required changes for developers</h2><p>As we migrate the OpenSea marketplace over to Seaport, there are a few implications to our APIs and SDK that will affect our existing developers.  When we initially launch the new protocol, we will operate Wyvern and Seaport in parallel for a period of one week following the launch - and this means that you’ll need to update your project in order to fetch and interact with orders from both contracts.</p><p>We’ve summarized the set of changes that are required in order for projects to be compatible with the new Seaport protocol when it launches on OpenSea in the coming weeks. If your project does not incorporate these updates, it will not be able to fetch or interact with offers or listings on OpenSea that use the Seaport contract as we deploy it to our marketplace.</p><p>Here’s an overview of what to expect, with more details about each step in the sections that follow:</p><p><strong>Today (May 25)</strong></p><p>✅ <strong>API:</strong> Begin using new Seaport offers and listings endpoints on Testnets</p><p>✅ <strong>API:</strong> Begin parsing new Seaport orders from /assets and /bundles endpoints on Testnets</p><p><strong>Tomorrow (May 26)</strong></p><p>✅ <strong>SDK:</strong> Begin using new Seaport-ready functions in SDK v.4.0.0-beta on Testnets (May 26)</p><p><strong>Seaport live on OpenSea</strong></p><p>✅ <strong>API:</strong> Begin using new Seaport offers and listings endpoints on Mainnet</p><p>✅ <strong>API:</strong> Begin parsing new Seaport offers and listings from /assets and /bundles endpoints on Testnets</p><p>✅ <strong>SDK:</strong> Begin using new Seaport-ready functions in SDK v.4.0.0 on Mainnet</p><p><strong>Seaport live + 7 days</strong></p><p>✅ <strong>API+ SDK:</strong> Offers and listings can no longer be posted to <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/address/0x7f268357a8c2552623316e2562d90e642bb538e5">Wyvern v2.3 contract</a> using OpenSea</p><p><strong>Seaport live + 30 days</strong></p><p>✅ <strong>API + SDK:</strong> Offers and listings can no longer be fetched from <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/address/0x7f268357a8c2552623316e2562d90e642bb538e5">Wyvern v2.3 contract</a> using OpenSea</p><h3 id="h-opensea-api" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">OpenSea API</h3><p>When we begin to use the new contract, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/api-overview">our API</a> will enable developers to fetch and post offers and listings from both the Wyvern and Seaport contracts. Since offers and listings from the new contract will differ from those on the Wyvern contract, developers will need to update their OpenSea API integrations to account for these differences. Current API implementations will continue to function against the Wyvern contract, however changes are required to fetch and post offers and listings from the new contract.</p><p>In order to be compatible with the Seaport contract, developers will need to make the following changes to their projects:</p><ul><li><p>Developers using the existing <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/retrieving-orders">/wyvern</a> endpoints will need to migrate to the new endpoint that supports offers and listings on the Seaport contract.</p></li><li><p>Developers using the existing <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/getting-assets">/assets</a> and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/retrieving-bundles">/bundles</a> endpoints will need to begin parsing orders from the Seaport contract that are returned from these endpoints.</p></li></ul><p><strong>Migrating from /wyvern endpoints to new Seaport orders endpoints</strong></p><p>With the launch of the Seaport contract, we will be deprecating the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/retrieving-orders">/wyvern</a> endpoints - at this point, POST requests will no longer be supported and GET requests will only continue to function for 30 days post-launch.</p><p>The new Seaport offers and listings endpoints enable developers to create and fetch both listings and offers on the new contract.  Developers will need to begin using these new endpoints to interact with the Seaport contract via the OpenSea API.</p><p>Starting today, we have enabled support for these new endpoints on our Testnets API (Rinkeby) so that developers can begin to prepare for the migration. More details on these new endpoints can be found in our developer documentation:</p><ul><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/v2.0/reference/retrieve-listings-testnets">Retrieve listings</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/v2.0/reference/retrieve-offers-testnets">Retrieve offers</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/v2.0/reference/create-an-order-testnets">Create a listing</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/v2.0/reference/create-an-offer-testnets">Create an offer</a></p></li></ul><p><strong>Parsing Seaport orders from /assets and /bundles endpoints</strong></p><p>Since the format of Seaport orders differs from those on the Wyvern contract, we’re adding a new field to the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/getting-assets">/assets</a> and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/retrieving-bundles">/bundles</a> endpoints through which Seaport orders will be returned separately from Wyvern offers and listings.</p><p>Developers using these endpoints will need to update any parsing logic on the responses from these endpoints in order to specifically handle orders returned from the Seaport contract.  Each item in these responses will now include the <code>seaport_sell_orders</code> field, which will contain an array of listings from the Seaport contract on the NFT.</p><p>This new field matches the way in which Wyvern listings are currently returned through the existing <code>sell_orders</code> field:</p><pre data-type="codeBlock" text="&quot;asset&quot;: {
  ...
  &quot;sell_orders&quot;: [],
  &quot;seaport_sell_orders&quot;: [],
  ...
}
"><code><span class="hljs-string">"asset"</span>: {
  ...
  <span class="hljs-string">"sell_orders"</span>: [],
  <span class="hljs-string">"seaport_sell_orders"</span>: [],
  ...
}
</code></pre><p>Once the Seaport contract integration is live on OpenSea, all new offers and listings that are created will be returned in the new <code>seaport_sell_orders</code> array.  As liquidity moves over to the new contract, you will see fewer and fewer listings being returned in the legacy <code>sell_orders</code> array, so we recommend that you cease to rely on this field after our forthcoming launch of Seaport on OpenSea.</p><h3 id="h-opensea-sdk" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">OpenSea SDK</h3><p>Similar to the OpenSea API,<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://projectopensea.github.io/opensea-js/"> our JavaScript SDK</a> has been updated to support the fetching and posting of offers and listings on the new contract. Developers should plan to adopt Version 4.0.0 of our SDK when we begin using Seaport on OpenSea and begin to use our new methods that have been updated to support orders on the new contract.</p><p>With this SDK update to support the new Seaport contract, there are notable changes that developers will need to address within their projects:</p><ul><li><p>All Wyvern-specific models will be deprecated in the new version of the SDK.  Wyvern support will be maintained through a legacy set of functions that developers can continue to use while the contract is still enabled on OpenSea.</p></li><li><p>For each of these deprecated functions, we’re providing a new function that is compatible with orders on the new Seaport protocol.</p></li></ul><p>With this upgrade to Version 4.0.0, the function names from Version 3.0.4 are now connected to the Seaport contract and will only begin to function when Seaport launches on OpenSea. In order to preserve support for Wyvern, developers can use the following functions to maintain support for offers and listings on the Wyvern contract:</p><ul><li><p><code>isOrderFulfillableLegacyWyvern</code></p></li><li><p><code>cancelOrderLegacyWyvern</code></p></li><li><p><code>fulfillOrderLegacyWyvern</code></p></li><li><p><code>createBuyOrderLegacyWyvern</code></p></li><li><p><code>createBundleBuyOrderLegacyWyvern</code></p></li><li><p><code>createSellOrderLegacyWyvern</code></p></li><li><p><code>createBundleSellOrderLegacyWyvern</code></p></li><li><p><code>getCurrentPriceLegacyWyvern</code></p></li><li><p><code>getOrderLegacyWyvern</code></p></li></ul><p>Starting on May 26, developers can begin testing against Version 4.0.0-beta on Rinkeby in order to prepare for the migration.</p><h2 id="h-using-the-new-contract" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Using the new contract</h2><p>While our API and SDK provide helpful abstraction layers on top of the underlying contracts that we use here at OpenSea, we also realize that a growing part of the developer ecosystem is interested in building directly off of these contracts themselves. With the release of this new contract, we’re excited to expand our developer stack by opening up this contract for the entire ecosystem to build around and participate in its ongoing development.</p><p>If you’re interested in getting started, we’ve released a<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/v2.0/reference/seaport-overview"> set of reference documentation</a> that you can use to learn more and begin building.</p><p>We also currently have a <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://code4rena.com/contests/2022-05-opensea-seaport-contest">two-week audit contest</a> running with code4rena with a $1 million prize pool, where we’d love participation from the community in reviewing the Seaport contracts. Please join us for the largest pool size in code4rena’s history!</p>]]></content:encoded>
            <author>sea-2@newsletter.paragraph.com (OpenSea for Developers)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/ae80be2d7939ced91848a73a6c3056f7843356e6eb5eff74c5e954b8a62db475.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[OpenSea Developer Newsletter: Edition 1]]></title>
            <link>https://paragraph.com/@sea-2/opensea-developer-newsletter-edition-1</link>
            <guid>8b3P0MoGu8gtBo94AScb</guid>
            <pubDate>Mon, 16 May 2022 19:31:35 GMT</pubDate>
            <description><![CDATA[Hello Devs, Welcome to the inaugural OpenSea Developer Newsletter! In this first edition, we’re sharing a recap of recent news and updates to the OpenSea Developer platform - including our API, SDK and developer events. Let’s dive in!Product UpdatesStream API now in betaOn May 5th, we launched a beta version of the Stream API, a new websocket-based service that enables developers to receive events as they occur across our marketplace. We’ve built the Stream API to better support a range of us...]]></description>
            <content:encoded><![CDATA[<p>Hello Devs, Welcome to the inaugural OpenSea Developer Newsletter!</p><p>In this first edition, we’re sharing a recap of recent news and updates to the OpenSea Developer platform - including our API, SDK and developer events.</p><p>Let’s dive in!</p><h2 id="h-product-updates" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Product Updates</h2><h3 id="h-stream-api-now-in-beta" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Stream API now in beta</h3><p>On May 5th, we launched a <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/stream-api-overview">beta version of the Stream API</a>, a new websocket-based service that enables developers to receive events as they occur across our marketplace.</p><p>We’ve built the Stream API to better support a range of use cases that rely on dynamic data, such as price fluctuation, listings, bids, and ownership changes. Instead of polling for updates, you can subscribe to receive events as they occur - whether for specific collections or globally across the entire OpenSea marketplace.</p><p>The Stream API makes it easier to build many new features, such as:</p><ul><li><p>A push notifications service that alerts people when they receive new bids on their listing.</p></li><li><p>An activity feed that provides a timeline of sales of NFTs from a specific collection.</p></li><li><p>A real-time dashboard that enables people to visualize and track key trends and metrics.</p></li><li><p>A display of NFTs that have recently had their metadata updated.</p></li></ul><p>With this beta launch, we’ve provided a JavaScript SDK that provides a simple way to manage connections and individual subscribers to the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/stream-api-event-schemas">Stream API and its various events</a>. And as an example of what’s possible, we’ve also built a new tool that leverages the Stream API to automatically post updates to Discord which you can <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ProjectOpenSea/opensea-stream-discord-webhook">clone on GitHub</a>.</p><p>To get started, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/stream-api-overview">check out our Stream API developer documentation</a> which will walk through setup and how to use our <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ProjectOpenSea/stream-js">JavaScript SDK</a>.</p><h3 id="h-update-to-orders-endpoint" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Update to orders endpoint</h3><p>On April 26, 2022, we began to require the <code>side</code> parameter to be included in all requests to the <code>/wyvern/v1/orders</code> endpoint. This parameter is used to filter the response to either buy or sell orders and was previously optional. Moving forward, requests will fail if they don’t include this parameter. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/changelog/requiring-side-parameter-on-wyvernv1orders">Learn more here.</a></p><h3 id="h-solana-update" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Solana update</h3><p>Our <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/explore-solana">Solana Beta</a> is now live! Using our Solana marketplace is similar to using Ethereum and Polygon, but there are a few differences. Solana is a separate blockchain from Ethereum, so a Solana-compatible wallet is required to be able to purchase Solana-based items using OpenSea. Check out <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://support.opensea.io/hc/en-us/articles/5252906283027">our guide</a> to learn more about how Solana works on OpenSea.</p><h2 id="h-developer-events" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Developer Events</h2><p>OpenSea recently teamed up with Replit to host the Hello NFT World Hackathon. Check out the BUIDLs and winners in the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://nft.mirror.xyz/Qu8apR8kQdijcPXC2vaVJOXGdu2GuatpJoO4_zci7AU">Hello NFT World Hackathon Recap</a>.</p><h2 id="h-developer-resources" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Developer Resources</h2><p>Just getting started? Here’s a set of helpful tools and links to help you get up and running:</p><ul><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/api-overview">NFT API Developer Docs</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/stream-api-overview">Stream API Developer Docs</a> <strong>[New!]</strong></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.npmjs.com/package/opensea-js">JavaScript SDK</a> <em>- don’t forget to update to the most recent version!</em></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://nft.mirror.xyz/">OpenSea Developer Blog</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/changelog">Changelog</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/apiopensea">OpenSea Developers on Twitter</a> <em>- real-time updates on our API, SDK</em></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discordapp.com/channels/397566282729390110/434175585745633280">OpenSea Developers on Discord</a> <em>- join our community of builders</em></p></li></ul><h2 id="h-tutorials" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Tutorials</h2><p>Looking to create your first NFT smart contract?</p><p>Dive into <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/docs/creating-an-nft-contract">this step-by-step tutorial</a> which will walk you through everything needed to create an NFT contract that you can trade on OpenSea. This tutorial includes many different components of building, deploying, and selling a non-fungible contract on Ethereum&apos;s Testnet that can be bought on OpenSea.</p><p>That’s a wrap for our first newsletter! As part of our ongoing efforts to improve developer tools, we welcome any feedback from the community. Please complete <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://airtable.com/shrvYIjP6Rt6p2jS6">this form</a> and include any blockers or wish list items.</p><p>Thanks for reading! We look forward to seeing you on the next one!</p>]]></content:encoded>
            <author>sea-2@newsletter.paragraph.com (OpenSea for Developers)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/678750207e7c057627800a770d0f3ceff8452d52e1855928bfa6555dcc532e02.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[“Hello NFT World” Hackathon Recap]]></title>
            <link>https://paragraph.com/@sea-2/hello-nft-world-hackathon-recap</link>
            <guid>fF8IeXHU1mxYGevL9OaC</guid>
            <pubDate>Mon, 16 May 2022 19:31:14 GMT</pubDate>
            <description><![CDATA[That’s a wrap! The Replit and OpenSea virtual hackathon “Hello NFT World” has ended! We’d also like to give a shoutout to our partners, DoraHacks, and Buildspace.Hello World meets web3 🖥️The Hello NFT World Hackathon encouraged the advancement of web3 by bringing together creators, artists, developers, and entrepreneurs as “BUIDLers” to create innovative web3 NFT Projects. Together, they pushed the boundaries of NFTs and surfaced new types of utility. Over the course of eight days, projects ...]]></description>
            <content:encoded><![CDATA[<p>That’s a wrap! The <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://replit.com/@openseaofficial/OpenSea-NFT-Tutorial?v=1">Replit</a> and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/">OpenSea</a> virtual hackathon “<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://nft.replit.com/">Hello NFT World</a>” has ended! We’d also like to give a shoutout to our partners, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/">DoraHacks</a>, and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://buildspace.so/">Buildspace</a>.</p><h3 id="h-hello-world-meets-web3" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Hello World meets web3 🖥️</h3><p>The <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://nft.replit.com/"><strong>Hello NFT World Hackathon</strong></a> encouraged the advancement of web3 by bringing together creators, artists, developers, and entrepreneurs as “BUIDLers” to create innovative web3 NFT Projects.</p><p>Together, they pushed the boundaries of NFTs and surfaced new types of utility. Over the course of eight days, projects explored various concepts ranging from web3 education, NFT DeFi, and even blockchain dating!</p><p>In summary, a total of 73 teams submitted BUIDLs to the four <strong>Hello NFT World</strong> tracks:</p><ul><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/hackathon/19/?track=Gaming%20and%20Metaverse">Gaming and Metaverse</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/hackathon/19/?track=Most%20Hilarious">Most Hilarious</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/hackathon/19/?track=Onboarding%20for%20All">Onboarding for All</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/hackathon/19/?track=Most%20Creative">Most Creative</a></p></li></ul><h3 id="h-how-winners-were-chosen" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">How winners were chosen</h3><p>Each BUIDL track had a $5K first place prize, but it didn’t stop there. The top three BUIDLs in each track advanced to the $25K Quadratic Voting round. A total of 12 teams battled it out in the Quadratic Voting round.</p><p>What is Quadratic Voting, you ask?</p><p>A voting scheme introduced and often discussed in the Radical Markets community. It is often considered an innovative improvement of the traditional 1-person-1-vote or 1-dollar-1-vote voting schemes. The simplified formula on how quadratic voting functions is cost to the voter = (number of votes)².</p><p>To learn more about on-chain MACI Quadratic Voting, you can dive into the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/grant/opensea/detail">DoraHacks explainer here</a>.</p><p>To view the top 12 BUIDLs and the Quadratic Voting results, head over to DoraHacks and check out the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/grant/opensea/top">leaderboard</a>. You can also jump to the bottom of this post to watch the Hackathon Kickoff, and the two Demo Days hosted by DoraHacks.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/21bad45328ed30e59968d9731ca5fb8445756108149e96daa5217dbf2f8fea50.png" alt=" https://dorahacks.io/grant/opensea/top" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">https://dorahacks.io/grant/opensea/top</figcaption></figure><h2 id="h-the-first-place-track-winners" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">The First Place Track Winners</h2><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/hackathon/19/?track=Gaming%20and%20Metaverse"><strong>Gaming and Metaverse</strong></a></p><p><strong>Belly NFT</strong></p><p>A collectible, craftable NFT experience!</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://belly.io/">Belly.io</a> rewards loyal fans with NFTs. As <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.youtube.com/channel/UCAEcsNtVULAF0S756r_ZP7A/videos">content creators</a>, Belly wanted to BUIDL a way to reward their loyal fans. As developers, they wanted to do something fun and creative, and since so much of their <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.youtube.com/SushiDayTV">content in the past</a> revolved around food, a collectible, craftable NFT experience seemed like the perfect way to do all of that! Check out the demo, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/buidl/2661">visit the Belly NFT BUIDL</a>.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/buidl/2661">https://dorahacks.io/buidl/2661</a></p><div data-type="youtube" videoId="dOCu5rHvUNQ">
      <div class="youtube-player" data-id="dOCu5rHvUNQ" style="background-image: url('https://i.ytimg.com/vi/dOCu5rHvUNQ/hqdefault.jpg'); background-size: cover; background-position: center">
        <a href="https://www.youtube.com/watch?v=dOCu5rHvUNQ">
          <img src="{{DOMAIN}}/editor/youtube/play.png" class="play"/>
        </a>
      </div></div><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/hackathon/19/?track=Most%20Hilarious"><strong>Most Hilarious</strong></a></p><p><strong>Spamazon</strong></p><p>Buy anything with anything.</p><p>Have you ever wanted to trade your 10 ETH NFT for a $20 book? Well, Spamazon has the place for you! Spamazon gives NFTs a new purpose: payment for a purchase, on or off the blockchain. If your local food or furniture store has a risk appetite, they can accept NFTs as payment or collateral until payments are made using all Spamazon. Buyers can benefit from bartering with their NFTs or posting them as collateral until they daytrade for enough money to repay. A store that adopts this concept can reach a new market that doesn&apos;t require an intermediary trade for currency. Ready to LOL? To learn more, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/buidl/2677">visit the Spamazon BUIDL.</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.loom.com/share/71e4ad2da2c9408ba468b716f2ceafa0">Watch the demo here</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/buidl/2677">https://dorahacks.io/buidl/2677</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/hackathon/19/?track=Onboarding%20for%20All"><strong>Onboarding for All</strong></a></p><p><strong>NEWFRENZ</strong></p><p>Onboard your frenz in web3 with a simple link.</p><p>NEWFRENZ is an interactive onboarding into web3 for beginners. The user is invited to navigate through different sections to learn essential information about blockchain, NFT, etc., and complete a series of tasks (connect wallet, switch to testnet, use a faucet, and finally minting an NFT). To learn more and start your web3 onboarding, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/buidl/2658">visit the NEWFRENZ BUIDL.</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/buidl/2658">https://dorahacks.io/buidl/2658</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/hackathon/19/?track=Most%20Creative"><strong>Most Creative</strong></a></p><p><strong>ShaadiOnChain</strong></p><p>The one-stop destination for all your blockchain love life needs.</p><p>Weddings in India are regarded to be an everlasting love relationship. ShaadiOnChain now allows you to record your love for the rest of your life. Many Indian couples have begun to celebrate and register their weddings on the blockchain, although this can be difficult for those unfamiliar with web3. ShaadiOnChain provides a simple interface for couples to enjoy a fully loaded love journey on the blockchain. To learn more, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/buidl/2624">visit the ShaadiOnChain BUIDL.</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/buidl/2624">https://dorahacks.io/buidl/2624</a></p><p>All Hello NFT World BUIDLers received this exclusive POAP. What’s a POAP? More cool web3 stuff, learn more at <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://poap.xyz/">https://poap.xyz/</a></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/0dee472ad593be4b2bb80b1438005dd89caf382b58c42fe8efaf41af3eca6ee1.png" alt="Hello NFT World POAP" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Hello NFT World POAP</figcaption></figure><p>Thank you again to all of our BUIDLers, Judges, and Partners.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discordapp.com/channels/397566282729390110/434175585745633280">Join us in our Discord</a> and help us BUIDL and advance web3.</p><p>If you are interested in learning more about web3 and NFTs, check out the following resources:</p><ol><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blockgeeks.com/guides/what-is-blockchain-technology/"><strong>What is Blockchain?</strong></a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/@preethikasireddy/how-does-ethereum-work-anyway-22d1df506369"><strong>How does Ethereum work anyways?</strong></a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.ethhub.io/"><strong>ETHhub Reading &amp; Community Resources</strong></a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blog.opensea.io/guides/non-fungible-tokens/"><strong>NFT intro guide</strong></a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.youtube.com/watch?v=St1yi_J-CqI&amp;t=1s"><strong>How to Start Coding in Web3</strong></a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://obront.substack.com/p/hands-on-ethereum-day?s=r&amp;utm_campaign=post&amp;utm_medium=web"><strong>Hands-on Ethereum Day</strong></a></p></li></ol><p><em>📣 Orca size THANK YOU to DoraHacks for their guidance, support, and helping ensure the voting mechanism worked without a glitch over the weekend.</em></p><h1 id="h-hello-nft-world-videos" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Hello NFT World Videos</h1><p><strong>How to Create an NFT on Replit</strong> (you can follow along with the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://replit.com/@openseaofficial/OpenSea-NFT-Tutorial?v=1">replit here</a>)</p><div data-type="youtube" videoId="6DEFqhC1g5o">
      <div class="youtube-player" data-id="6DEFqhC1g5o" style="background-image: url('https://i.ytimg.com/vi/6DEFqhC1g5o/hqdefault.jpg'); background-size: cover; background-position: center">
        <a href="https://www.youtube.com/watch?v=6DEFqhC1g5o">
          <img src="{{DOMAIN}}/editor/youtube/play.png" class="play"/>
        </a>
      </div></div><p><strong>Demo Day One with DoraHacks</strong></p><div data-type="youtube" videoId="ge2iTTC1M_8">
      <div class="youtube-player" data-id="ge2iTTC1M_8" style="background-image: url('https://i.ytimg.com/vi/ge2iTTC1M_8/hqdefault.jpg'); background-size: cover; background-position: center">
        <a href="https://www.youtube.com/watch?v=ge2iTTC1M_8">
          <img src="{{DOMAIN}}/editor/youtube/play.png" class="play"/>
        </a>
      </div></div><p><strong>Demo Day Two with DoraHacks</strong></p><div data-type="youtube" videoId="3yEwJPE6q6Y">
      <div class="youtube-player" data-id="3yEwJPE6q6Y" style="background-image: url('https://i.ytimg.com/vi/3yEwJPE6q6Y/hqdefault.jpg'); background-size: cover; background-position: center">
        <a href="https://www.youtube.com/watch?v=3yEwJPE6q6Y">
          <img src="{{DOMAIN}}/editor/youtube/play.png" class="play"/>
        </a>
      </div></div><p><strong>Hello NFT World LIVE!! Kickoff</strong></p><div data-type="youtube" videoId="wqK2-gIlJCU">
      <div class="youtube-player" data-id="wqK2-gIlJCU" style="background-image: url('https://i.ytimg.com/vi/wqK2-gIlJCU/hqdefault.jpg'); background-size: cover; background-position: center">
        <a href="https://www.youtube.com/watch?v=wqK2-gIlJCU">
          <img src="{{DOMAIN}}/editor/youtube/play.png" class="play"/>
        </a>
      </div></div>]]></content:encoded>
            <author>sea-2@newsletter.paragraph.com (OpenSea for Developers)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/45c46c9cb302a533cceedb712895581412bb76651935731a5e84737e61192444.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Streaming the OpenSea]]></title>
            <link>https://paragraph.com/@sea-2/streaming-the-opensea</link>
            <guid>QINoutiW01qQWCkhX8vA</guid>
            <pubDate>Fri, 06 May 2022 00:46:32 GMT</pubDate>
            <description><![CDATA[Today we’re launching a beta version the OpenSea Stream API, a new websocket-based service that enables developers to receive events as they occur across our marketplace. With the massive growth in the NFT ecosystem, we know that it’s becoming increasingly challenging to rely solely on our REST APIs to stay up-to-date across a growing number of items and collections. The need to continuously poll these endpoints to refresh the data in your service can be resource-intensive and inefficient. We...]]></description>
            <content:encoded><![CDATA[<p>Today we’re launching a beta version the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/stream-api-overview">OpenSea Stream API</a>, a new websocket-based service that enables developers to receive events as they occur across our marketplace.</p><p>With the massive growth in the NFT ecosystem, we know that it’s becoming increasingly challenging to rely solely on our REST APIs to stay up-to-date across a growing number of items and collections. The need to continuously poll these endpoints to refresh the data in your service can be resource-intensive and inefficient.</p><p>We’ve built the Stream API to better support a range of use cases that rely on dynamic data, such as price fluctuation, listings, bids, and ownership changes. Instead of polling for updates, you can subscribe to receive events as they occur - whether for specific collections or globally across the entire OpenSea marketplace.</p><p>The Stream API makes it easier to build many new features, such as:</p><ul><li><p>A push notifications service that alerts people when they receive new bids on their listing</p></li><li><p>An activity feed that provides a timeline of sales of NFTs from a specific collection</p></li><li><p>A real-time dashboard that enables people to visualize and track key trends and metrics</p></li><li><p>A display of NFTs that have recently had their metadata updated. Examples of metadata updates include changes to title, description, and image.</p></li></ul><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/ef81d069aa3e42882ee76c56c440c843464978f0a4a6860ee21cc1aef688b49e.png" alt="Discord server using Stream API" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Discord server using Stream API</figcaption></figure><p>With this beta launch, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ProjectOpenSea/opensea-stream-js-sdk">we’re providing a JavaScript SDK</a> that provides a simple way to manage connections and individual subscribers to the Stream API and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/stream-api-event-schemas">its various events</a>. And as an example of what’s possible, we’ve also built a new tool that leverages the Stream API to automatically post updates to Discord which you can <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ProjectOpenSea/opensea-stream-discord-webhook">clone on GitHub</a>.</p><p>We’re excited to get this beta version in the hands of the ecosystem and we’ll continue to iterate and improve upon the Stream API during beta period. To get started, check out our <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.opensea.io/reference/stream-api-overview">Stream API developer documentation</a> which will walk through setup and using our SDK. Please let us know what you think and share your feedback, questions, and issues in our <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/channels/397566282729390110/434175585745633280">Developers channel in Discord</a>.</p><p>We can’t wait to see what you build!</p><h2 id="h-faqs" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">FAQs</h2><p><strong>Do the events received from my subscriptions count towards any rate limits on my API key?</strong></p><p>No, events are not counted towards any API rate limits.</p><p><strong>What is the typical streaming rate that I should expect from the Stream API?</strong></p><p>The streaming rate depends on a range of factors - from the amount of collections that you’re monitoring to the type and amount of events that you’re subscribed to. For instance, if you’re subscribed to receive bid events across all collections on OpenSea, you’ll be receiving messages at a significantly higher rate than you will for a subscription to order cancellations on a small collection.</p><p><strong>Should I expect that some events can be received out of order?</strong></p><p>You should be prepared to handle receipt of events out of order as we don’t guarantee delivery of events in the order that they occur. Payloads include the <code>event_timestamp</code> field, which represents the time at which the event occurred and is the most definitive resource in determining order. We also include a <code>sent_at</code> field that refers to the time at which we sent the message out through the websocket.</p><p><strong>Is it possible for some events to be missing?</strong></p><p>The Stream API is a best-effort delivery messaging system and messages that are not received due to connection errors will not be re-sent. So it’s possible that there can be missing messages if the socket connection is unstable.</p><p><strong>What blockchains does the Stream API support?</strong></p><p>The following blockchains are supported on Mainnet networks:</p><ul><li><p>Ethereum</p></li><li><p>Polygon mainnet</p></li><li><p>Klaytn mainnet</p></li><li><p>Solana mainnet</p></li></ul><p>The following blockchains are supported on Testnet networks:</p><ul><li><p>Rinkeby</p></li><li><p>Polygon testnet (Mumbai)</p></li><li><p>Klaytn testnet (Baobab)</p></li></ul>]]></content:encoded>
            <author>sea-2@newsletter.paragraph.com (OpenSea for Developers)</author>
        </item>
    </channel>
</rss>