You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@layerzerolabs/devtools-move@2.0.0
Major Changes
128b697: update initia.js version and object creation seed derivation
Patch Changes
6afd57b: Reject an omitted requiredDVNs in buildConfig with a clear error. requiredDVNs is now
optional on the shared Uln302UlnUserConfig type, but this encoder maps an empty required set
to the NIL sentinel (pin "no required DVNs") and cannot express "inherit the on-chain default".
Defaulting an omitted value to [] would silently pin the least-secure shape, so it now throws
instead — callers must pass the required DVNs explicitly, or [] to pin "no required DVNs".
@layerzerolabs/protocol-devtools@4.0.0
Major Changes
6afd57b: Treat explicitly-empty ULN302 config values as NIL sentinels instead of defaults
This lets a team pin a literal "none"/"zero" so their security configuration is exactly
what their config file says, rather than silently inheriting a default that LayerZero
controls. Being able to opt out of defaults is the point: a pinned config cannot change
underneath a team when a default is updated.
When serializing an OApp ULN302 / Read config, requiredDVNs and optionalDVNs now
behave identically — omitted, explicitly-empty, and concrete each map to a distinct
on-chain meaning:
Omitting a DVN field (leaving it undefined) inherits the on-chain default.
An explicitly-empty array ([]) pins "no DVNs" via NIL_DVN_COUNT (0xff).
A concrete array pins those DVNs.
Likewise confirmations: 0n now serializes to NIL_CONFIRMATIONS
(type(uint64).max), while omitting it inherits the default.
To make requiredDVNs express "inherit" the same way optionalDVNs already could, it
is now OPTIONAL on Uln302UlnUserConfig and UlnReadUlnUserConfig (previously
mandatory). This removes the need for any count override — the count is always derived
from the array, so the three serializers (EVM ULN302, EVM Read, Solana ULN302) share a
single resolveDVNCount helper.
The read types Uln302UlnConfig/UlnReadUlnConfig carry optionalDVNCount (and UlnReadUlnConfig also requiredDVNCount) so the stored sentinel round-trips through
the configuration diff, and the on-chain read path normalizes rather than re-applying
the empty→NIL mapping, keeping hasAppUlnConfig idempotent on both paths. The
library-wide DEFAULT config continues to serialize literal values (it rejects NIL
sentinels on-chain). On Solana, confirmations is now encoded as a BN so the u64
NIL sentinel survives without precision loss.
MIGRATION:
If you wrote confirmations: 0, requiredDVNs: [], or optionalDVNs: [] expecting
the config to inherit the protocol default, OMIT the field instead. An explicit empty
value now pins literal zero/none — for confirmations this means zero block
confirmations, and for requiredDVNs it means no required DVNs, both
security-relevant. Re-wiring an existing OApp whose config used these empty values
will emit a setConfig that flips it from inherit to pinned.
The read types Uln302UlnConfig (gains optionalDVNCount) and UlnReadUlnConfig
(gains requiredDVNCount and optionalDVNCount) have new required fields. Any code
that hand-constructs one of these (e.g. mocking an SDK read) must supply the new
fields.
requiredDVNs is no longer required on the user config. Code that always set it
keeps working unchanged; you may now omit it to inherit the on-chain default.
@layerzerolabs/protocol-devtools-evm@6.0.0
Major Changes
6afd57b: Treat explicitly-empty ULN302 config values as NIL sentinels instead of defaults
This lets a team pin a literal "none"/"zero" so their security configuration is exactly
what their config file says, rather than silently inheriting a default that LayerZero
controls. Being able to opt out of defaults is the point: a pinned config cannot change
underneath a team when a default is updated.
When serializing an OApp ULN302 / Read config, requiredDVNs and optionalDVNs now
behave identically — omitted, explicitly-empty, and concrete each map to a distinct
on-chain meaning:
Omitting a DVN field (leaving it undefined) inherits the on-chain default.
An explicitly-empty array ([]) pins "no DVNs" via NIL_DVN_COUNT (0xff).
A concrete array pins those DVNs.
Likewise confirmations: 0n now serializes to NIL_CONFIRMATIONS
(type(uint64).max), while omitting it inherits the default.
To make requiredDVNs express "inherit" the same way optionalDVNs already could, it
is now OPTIONAL on Uln302UlnUserConfig and UlnReadUlnUserConfig (previously
mandatory). This removes the need for any count override — the count is always derived
from the array, so the three serializers (EVM ULN302, EVM Read, Solana ULN302) share a
single resolveDVNCount helper.
The read types Uln302UlnConfig/UlnReadUlnConfig carry optionalDVNCount (and UlnReadUlnConfig also requiredDVNCount) so the stored sentinel round-trips through
the configuration diff, and the on-chain read path normalizes rather than re-applying
the empty→NIL mapping, keeping hasAppUlnConfig idempotent on both paths. The
library-wide DEFAULT config continues to serialize literal values (it rejects NIL
sentinels on-chain). On Solana, confirmations is now encoded as a BN so the u64
NIL sentinel survives without precision loss.
MIGRATION:
If you wrote confirmations: 0, requiredDVNs: [], or optionalDVNs: [] expecting
the config to inherit the protocol default, OMIT the field instead. An explicit empty
value now pins literal zero/none — for confirmations this means zero block
confirmations, and for requiredDVNs it means no required DVNs, both
security-relevant. Re-wiring an existing OApp whose config used these empty values
will emit a setConfig that flips it from inherit to pinned.
The read types Uln302UlnConfig (gains optionalDVNCount) and UlnReadUlnConfig
(gains requiredDVNCount and optionalDVNCount) have new required fields. Any code
that hand-constructs one of these (e.g. mocking an SDK read) must supply the new
fields.
requiredDVNs is no longer required on the user config. Code that always set it
keeps working unchanged; you may now omit it to inherit the on-chain default.
6afd57b: Treat explicitly-empty ULN302 config values as NIL sentinels instead of defaults
This lets a team pin a literal "none"/"zero" so their security configuration is exactly
what their config file says, rather than silently inheriting a default that LayerZero
controls. Being able to opt out of defaults is the point: a pinned config cannot change
underneath a team when a default is updated.
When serializing an OApp ULN302 / Read config, requiredDVNs and optionalDVNs now
behave identically — omitted, explicitly-empty, and concrete each map to a distinct
on-chain meaning:
Omitting a DVN field (leaving it undefined) inherits the on-chain default.
An explicitly-empty array ([]) pins "no DVNs" via NIL_DVN_COUNT (0xff).
A concrete array pins those DVNs.
Likewise confirmations: 0n now serializes to NIL_CONFIRMATIONS
(type(uint64).max), while omitting it inherits the default.
To make requiredDVNs express "inherit" the same way optionalDVNs already could, it
is now OPTIONAL on Uln302UlnUserConfig and UlnReadUlnUserConfig (previously
mandatory). This removes the need for any count override — the count is always derived
from the array, so the three serializers (EVM ULN302, EVM Read, Solana ULN302) share a
single resolveDVNCount helper.
The read types Uln302UlnConfig/UlnReadUlnConfig carry optionalDVNCount (and UlnReadUlnConfig also requiredDVNCount) so the stored sentinel round-trips through
the configuration diff, and the on-chain read path normalizes rather than re-applying
the empty→NIL mapping, keeping hasAppUlnConfig idempotent on both paths. The
library-wide DEFAULT config continues to serialize literal values (it rejects NIL
sentinels on-chain). On Solana, confirmations is now encoded as a BN so the u64
NIL sentinel survives without precision loss.
MIGRATION:
If you wrote confirmations: 0, requiredDVNs: [], or optionalDVNs: [] expecting
the config to inherit the protocol default, OMIT the field instead. An explicit empty
value now pins literal zero/none — for confirmations this means zero block
confirmations, and for requiredDVNs it means no required DVNs, both
security-relevant. Re-wiring an existing OApp whose config used these empty values
will emit a setConfig that flips it from inherit to pinned.
The read types Uln302UlnConfig (gains optionalDVNCount) and UlnReadUlnConfig
(gains requiredDVNCount and optionalDVNCount) have new required fields. Any code
that hand-constructs one of these (e.g. mocking an SDK read) must supply the new
fields.
requiredDVNs is no longer required on the user config. Code that always set it
keeps working unchanged; you may now omit it to inherit the on-chain default.
6afd57b: Add bigIntToBN helper (and Bignum type) for converting a bigint to the BN type
the Solana program instruction builders expect, preserving full precision for u64
values that overflow a JS number.
@layerzerolabs/metadata-tools@4.0.0
Minor Changes
6afd57b: generateConnectionsConfig now treats a pathway with no optional DVNs as an explicit
"no optional DVNs" (pinned via the NIL sentinel) instead of a value that inherits the
on-chain default.
The emitted config still carries optionalDVNs: [], but under the new ULN302 sentinel
semantics that empty array now pins "no optional DVNs" on-chain rather than falling back
to the chain default. This is deliberate: the metadata config is the primary way a config
is consumed, and an empty optional-DVN set should be visible in the file rather than
silently inheriting the default.
Re-wiring a pathway that previously inherited the on-chain default will now pin its
optional-DVN set explicitly. If that default carried optional DVNs (a non-zero threshold),
pinning an empty set drops them — this is intended. The goal is that a team's verification
config is exactly what their config file says, not something that can change underneath them
when a LayerZero-controlled default is updated. An empty optional-DVN set means "no optional
DVNs"; teams that want an optional quorum should list those DVNs explicitly. Required DVNs
are unaffected by this change.
6afd57b: Generate ULN configs (both the ULN302 send/receive and the Read library generators) that
round-trip the new NIL-sentinel semantics: a field inheriting the on-chain default is
OMITTED (for both requiredDVNs and optionalDVNs, which now behave identically) rather
than emitted as an explicit empty value that would pin zero/none on re-apply. Pinned-none
configs continue to emit []/0n.
High Risk
Major bumps change how ULN302 configs serialize and re-wire on-chain (DVNs, confirmations, metadata pathways)—security-relevant and can flip inherit vs pinned for existing configs; Move/Initia major may break object-creation flows.
Overview
This is a Changesets release PR: it removes consumed .changeset files and bumps package versions, changelogs, example/test dependency ranges, and pnpm-lock.yaml so the monorepo can publish to npm.
The release bundles major updates to @layerzerolabs/protocol-devtools (4.0.0), protocol-devtools-evm / protocol-devtools-solana (6.0.0 / 9.0.0), and downstream ua-devtools* / metadata-tools (4.0.0). The headline behavior change is ULN302 NIL-sentinel semantics: omitted DVN/confirmation fields inherit on-chain defaults, while explicit [] / 0n now pin “no DVNs” / zero confirmations instead of inheriting. requiredDVNs becomes optional on user configs; generators omit inherit fields rather than emitting empty arrays that would pin on re-apply.
Also shipped: metadata-tools treats pathways with no optional DVNs as pinned empty (not inherit); devtools-move 2.0.0 (Initia.js / seed derivation) plus throwing when requiredDVNs is omitted in buildConfig; devtools-solana 3.1.0 (bigIntToBN); verify-contract 1.5.2 (duplicate sourcemaps fix). Examples and toolbox-hardhat pick up the new dependency versions only.
Reviewed by Cursor Bugbot for commit 7583c90. Bugbot is set up for automated code reviews on this repo. Configure here.
E2E tests are non-blocking and validate real blockchain interactions. Failures may occur due to network issues, RPC rate limits, or external service downtime.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@layerzerolabs/devtools-move@2.0.0
Major Changes
Patch Changes
requiredDVNsinbuildConfigwith a clear error.requiredDVNsis nowoptional on the shared
Uln302UlnUserConfigtype, but this encoder maps an empty required setto the NIL sentinel (pin "no required DVNs") and cannot express "inherit the on-chain default".
Defaulting an omitted value to
[]would silently pin the least-secure shape, so it now throwsinstead — callers must pass the required DVNs explicitly, or
[]to pin "no required DVNs".@layerzerolabs/protocol-devtools@4.0.0
Major Changes
6afd57b: Treat explicitly-empty ULN302 config values as NIL sentinels instead of defaults
This lets a team pin a literal "none"/"zero" so their security configuration is exactly
what their config file says, rather than silently inheriting a default that LayerZero
controls. Being able to opt out of defaults is the point: a pinned config cannot change
underneath a team when a default is updated.
When serializing an OApp ULN302 / Read config,
requiredDVNsandoptionalDVNsnowbehave identically — omitted, explicitly-empty, and concrete each map to a distinct
on-chain meaning:
undefined) inherits the on-chain default.[]) pins "no DVNs" viaNIL_DVN_COUNT(0xff).confirmations: 0nnow serializes toNIL_CONFIRMATIONS(
type(uint64).max), while omitting it inherits the default.To make
requiredDVNsexpress "inherit" the same wayoptionalDVNsalready could, itis now OPTIONAL on
Uln302UlnUserConfigandUlnReadUlnUserConfig(previouslymandatory). This removes the need for any count override — the count is always derived
from the array, so the three serializers (EVM ULN302, EVM Read, Solana ULN302) share a
single
resolveDVNCounthelper.The read types
Uln302UlnConfig/UlnReadUlnConfigcarryoptionalDVNCount(andUlnReadUlnConfigalsorequiredDVNCount) so the stored sentinel round-trips throughthe configuration diff, and the on-chain read path normalizes rather than re-applying
the empty→NIL mapping, keeping
hasAppUlnConfigidempotent on both paths. Thelibrary-wide DEFAULT config continues to serialize literal values (it rejects NIL
sentinels on-chain). On Solana,
confirmationsis now encoded as aBNso theu64NIL sentinel survives without precision loss.
MIGRATION:
confirmations: 0,requiredDVNs: [], oroptionalDVNs: []expectingthe config to inherit the protocol default, OMIT the field instead. An explicit empty
value now pins literal zero/none — for
confirmationsthis means zero blockconfirmations, and for
requiredDVNsit means no required DVNs, bothsecurity-relevant. Re-wiring an existing OApp whose config used these empty values
will emit a
setConfigthat flips it from inherit to pinned.Uln302UlnConfig(gainsoptionalDVNCount) andUlnReadUlnConfig(gains
requiredDVNCountandoptionalDVNCount) have new required fields. Any codethat hand-constructs one of these (e.g. mocking an SDK read) must supply the new
fields.
requiredDVNsis no longer required on the user config. Code that always set itkeeps working unchanged; you may now omit it to inherit the on-chain default.
@layerzerolabs/protocol-devtools-evm@6.0.0
Major Changes
6afd57b: Treat explicitly-empty ULN302 config values as NIL sentinels instead of defaults
This lets a team pin a literal "none"/"zero" so their security configuration is exactly
what their config file says, rather than silently inheriting a default that LayerZero
controls. Being able to opt out of defaults is the point: a pinned config cannot change
underneath a team when a default is updated.
When serializing an OApp ULN302 / Read config,
requiredDVNsandoptionalDVNsnowbehave identically — omitted, explicitly-empty, and concrete each map to a distinct
on-chain meaning:
undefined) inherits the on-chain default.[]) pins "no DVNs" viaNIL_DVN_COUNT(0xff).confirmations: 0nnow serializes toNIL_CONFIRMATIONS(
type(uint64).max), while omitting it inherits the default.To make
requiredDVNsexpress "inherit" the same wayoptionalDVNsalready could, itis now OPTIONAL on
Uln302UlnUserConfigandUlnReadUlnUserConfig(previouslymandatory). This removes the need for any count override — the count is always derived
from the array, so the three serializers (EVM ULN302, EVM Read, Solana ULN302) share a
single
resolveDVNCounthelper.The read types
Uln302UlnConfig/UlnReadUlnConfigcarryoptionalDVNCount(andUlnReadUlnConfigalsorequiredDVNCount) so the stored sentinel round-trips throughthe configuration diff, and the on-chain read path normalizes rather than re-applying
the empty→NIL mapping, keeping
hasAppUlnConfigidempotent on both paths. Thelibrary-wide DEFAULT config continues to serialize literal values (it rejects NIL
sentinels on-chain). On Solana,
confirmationsis now encoded as aBNso theu64NIL sentinel survives without precision loss.
MIGRATION:
confirmations: 0,requiredDVNs: [], oroptionalDVNs: []expectingthe config to inherit the protocol default, OMIT the field instead. An explicit empty
value now pins literal zero/none — for
confirmationsthis means zero blockconfirmations, and for
requiredDVNsit means no required DVNs, bothsecurity-relevant. Re-wiring an existing OApp whose config used these empty values
will emit a
setConfigthat flips it from inherit to pinned.Uln302UlnConfig(gainsoptionalDVNCount) andUlnReadUlnConfig(gains
requiredDVNCountandoptionalDVNCount) have new required fields. Any codethat hand-constructs one of these (e.g. mocking an SDK read) must supply the new
fields.
requiredDVNsis no longer required on the user config. Code that always set itkeeps working unchanged; you may now omit it to inherit the on-chain default.
Patch Changes
@layerzerolabs/protocol-devtools-solana@9.0.0
Major Changes
6afd57b: Treat explicitly-empty ULN302 config values as NIL sentinels instead of defaults
This lets a team pin a literal "none"/"zero" so their security configuration is exactly
what their config file says, rather than silently inheriting a default that LayerZero
controls. Being able to opt out of defaults is the point: a pinned config cannot change
underneath a team when a default is updated.
When serializing an OApp ULN302 / Read config,
requiredDVNsandoptionalDVNsnowbehave identically — omitted, explicitly-empty, and concrete each map to a distinct
on-chain meaning:
undefined) inherits the on-chain default.[]) pins "no DVNs" viaNIL_DVN_COUNT(0xff).confirmations: 0nnow serializes toNIL_CONFIRMATIONS(
type(uint64).max), while omitting it inherits the default.To make
requiredDVNsexpress "inherit" the same wayoptionalDVNsalready could, itis now OPTIONAL on
Uln302UlnUserConfigandUlnReadUlnUserConfig(previouslymandatory). This removes the need for any count override — the count is always derived
from the array, so the three serializers (EVM ULN302, EVM Read, Solana ULN302) share a
single
resolveDVNCounthelper.The read types
Uln302UlnConfig/UlnReadUlnConfigcarryoptionalDVNCount(andUlnReadUlnConfigalsorequiredDVNCount) so the stored sentinel round-trips throughthe configuration diff, and the on-chain read path normalizes rather than re-applying
the empty→NIL mapping, keeping
hasAppUlnConfigidempotent on both paths. Thelibrary-wide DEFAULT config continues to serialize literal values (it rejects NIL
sentinels on-chain). On Solana,
confirmationsis now encoded as aBNso theu64NIL sentinel survives without precision loss.
MIGRATION:
confirmations: 0,requiredDVNs: [], oroptionalDVNs: []expectingthe config to inherit the protocol default, OMIT the field instead. An explicit empty
value now pins literal zero/none — for
confirmationsthis means zero blockconfirmations, and for
requiredDVNsit means no required DVNs, bothsecurity-relevant. Re-wiring an existing OApp whose config used these empty values
will emit a
setConfigthat flips it from inherit to pinned.Uln302UlnConfig(gainsoptionalDVNCount) andUlnReadUlnConfig(gains
requiredDVNCountandoptionalDVNCount) have new required fields. Any codethat hand-constructs one of these (e.g. mocking an SDK read) must supply the new
fields.
requiredDVNsis no longer required on the user config. Code that always set itkeeps working unchanged; you may now omit it to inherit the on-chain default.
Patch Changes
@layerzerolabs/devtools-solana@3.1.0
Minor Changes
bigIntToBNhelper (andBignumtype) for converting abigintto theBNtypethe Solana program instruction builders expect, preserving full precision for
u64values that overflow a JS number.
@layerzerolabs/metadata-tools@4.0.0
Minor Changes
6afd57b:
generateConnectionsConfignow treats a pathway with no optional DVNs as an explicit"no optional DVNs" (pinned via the NIL sentinel) instead of a value that inherits the
on-chain default.
The emitted config still carries
optionalDVNs: [], but under the new ULN302 sentinelsemantics that empty array now pins "no optional DVNs" on-chain rather than falling back
to the chain default. This is deliberate: the metadata config is the primary way a config
is consumed, and an empty optional-DVN set should be visible in the file rather than
silently inheriting the default.
Re-wiring a pathway that previously inherited the on-chain default will now pin its
optional-DVN set explicitly. If that default carried optional DVNs (a non-zero threshold),
pinning an empty set drops them — this is intended. The goal is that a team's verification
config is exactly what their config file says, not something that can change underneath them
when a LayerZero-controlled default is updated. An empty optional-DVN set means "no optional
DVNs"; teams that want an optional quorum should list those DVNs explicitly. Required DVNs
are unaffected by this change.
Patch Changes
@layerzerolabs/omnicounter-devtools@6.0.0
Patch Changes
@layerzerolabs/omnicounter-devtools-evm@8.0.0
Patch Changes
@layerzerolabs/toolbox-hardhat@0.6.14
Patch Changes
@layerzerolabs/ua-devtools@6.0.0
Patch Changes
@layerzerolabs/ua-devtools-evm@8.0.0
Patch Changes
@layerzerolabs/ua-devtools-evm-hardhat@10.0.0
Patch Changes
round-trip the new NIL-sentinel semantics: a field inheriting the on-chain default is
OMITTED (for both
requiredDVNsandoptionalDVNs, which now behave identically) ratherthan emitted as an explicit empty value that would pin zero/none on re-apply. Pinned-none
configs continue to emit
[]/0n.@layerzerolabs/ua-devtools-solana@9.0.0
Patch Changes
@layerzerolabs/verify-contract@1.5.2
Patch Changes
@layerzerolabs/lzapp-migration-example@0.3.10
Patch Changes
@layerzerolabs/oft-adapter-initia-example@0.1.4
Patch Changes
@layerzerolabs/oft-initia-example@0.0.11
Patch Changes
@layerzerolabs/test-setup-devtools-evm-hardhat@10.0.0
Patch Changes