abidock_mvx 3.1.0
abidock_mvx: ^3.1.0 copied to clipboard
Full-Featured MultiversX blockchain SDK for Dart/Flutter.
Changelog #
All notable changes to abidock_mvx are documented here. We follow Semantic Versioning and the structure recommended by Keep a Changelog.
3.1.0 -- 2026-08-13 #
Corrects argument encoding for variadic, counted-variadic and multi<...>, makes Balance.fromEgld exact, reaches the gas allowances and estimator that were previously unreachable, and puts every exception under one base type. Adds the skills/ knowledge base. One source-breaking removal, AbiNotFoundException, is listed under Removed.
Contract call arguments #
- A trailing
variadic<...>accepts either form. Each trailing argument was validated against the item type, so passing a wholeVariadicValuenever matched. A singleVariadicValueand flat trailing items now encode identically. counted-variadic<...>emits itsu32count, omitted on the endpoint path, so the contract read the first item as the count.multi<...>works in any input position. It was treated as variadic on themulti<prefix and the text between the brackets re-parsed as one type name, raisingUnknown type: TokenIdentifier,BigUint. Amulti<A,B>is a fixed-arity group.multi<...>expands to one wire slot per member. The controller's encoder had no branch for it and concatenated the members into a single argument.
Balance #
Balance.fromEgld(num) is exact for decimal literals. It converted through a fixed-point rendering of the double, so 0.1 produced 100000000000000006 and 0.3 produced 299999999999999989. Binary-representable values were unaffected, which is why the error was easy to miss.
Gas, configuration and status #
- Guardian and relayer gas allowances apply even when an explicit gas limit is given, and an
IGasLimitEstimatorsupplied toSmartContractControlleris consulted. Both were unreachable: the controller returned as soon as a limit was present, and contract calls always supply one. - Proxy entrypoints forward their
NetworkProviderConfig.ProxyNetworkEntrypointand the Devnet/Testnet/Mainnet presets built their provider without it, so client name, headers, timeout, retry, throttle and cache had no effect; applying aclientNamealso dropped the throttle and cache policies. TransactionOnNetwork.isCompletedandTransactionStatus.isCompletedagree; they diverged fornot-executable-in-block. The terminal-state predicate isisFinal.- An empty
datano longer discards token transfers.createTransactionForTransferguarded on non-empty data but branched on non-null, soUint8List(0)alongside transfers produced a native-EGLD transaction and the transfers vanished silently.
Errors #
- Every exception the SDK raises descends from
AbidockException, so oneon AbidockExceptionclause catches them all. Nine types implementedExceptiondirectly and escaped it. AbiNotFoundExceptionremoved — it could never be raised. An ABI-less controller asked for an ABI throwsStateError, as the equivalent factory methods already did.
Removed #
| Removed | Use instead |
|---|---|
AbiNotFoundException |
StateError -- raised when an ABI-less controller is asked for one |
Tooling #
abidock --help,-handhelpall print usage and exit successfully.abidock generate <abi> <output> <name>honours its arguments. The command looked for a config file first, so anabidock.yamlin the working directory made it regenerate that config's contracts and discard the three arguments silently. Precedence is now--config, then explicit arguments, then a discovered config.- Event polling no longer retries a rate-limited request indefinitely. After its bounded retries it skips the poll and resumes on the next cycle, as the log message always claimed.
Docs #
- New
skills/knowledge base: 14 task-oriented reference files covering the public API, wallets and signing, transactions, contracts, ABI codecs, codegen, providers, ESDT, events, errors, Supernova and pitfalls, indexed byskills/README.md.AGENTS.mdat the repository root points agents at it. - The error-handling page no longer documents
AbiNotFoundException.
Migration from 3.0.0 #
Bump to ^3.1.0. The only source-breaking change is AbiNotFoundException: replace any on AbiNotFoundException clause with on StateError. Expect higher gas limits on guarded and relayed contract calls, because those allowances now apply when you pass an explicit limit.
3.0.0 -- 2026-08-13 #
Lands the top-level NetworkEntrypoint façade, reshapes the generated DTO surface, and corrects a set of defects that produced transactions the chain rejects. Removed API is listed under Removed; each entry has a working replacement. Migration is mostly mechanical: regenerate, swap String token-identifier/address fields for the wrapper types, and walk the compiler errors.
Minimum SDK is now Dart 3.13.
Entrypoints #
New lib/src/entrypoints/network_entrypoint.dart, exported from the package barrel.
NetworkEntrypoint/DevnetEntrypoint/TestnetEntrypoint/MainnetEntrypoint-- API-backed (indexer).ProxyNetworkEntrypoint/DevnetProxyEntrypoint/TestnetProxyEntrypoint/MainnetProxyEntrypoint-- Gateway-backed (chain-go Proxy).EntrypointUrlsconstants for the official public hosts.
Each entrypoint caches a single NetworkProvider and exposes createSmartContractController, createTransfersFactory, createTokenManagementFactory, createDelegationFactory, createMultisigFactory, createValidatorsFactory, createGovernanceFactory, create*Controller and createTransactionWatcher. Documented at docs/docs/network/entrypoints.md.
Auto-gas signing bug fixed in generator #
Generated auto-gas calls signed the transaction and then replaced its gas limit with copyWith(newGasLimit:), which invalidated the signature. The generator now builds an unsigned probe via SmartContractCallFactory, simulates gas, and calls controller.call once with the final value, so signing happens against the gas that ships. Regenerate existing output to pick up the fix.
Type-mapper changes (generated DTO breaking change) #
The codegen TypeMapper now emits the wrapper types instead of String:
| ABI type | Old Dart type | New Dart type |
|---|---|---|
Address |
String |
Address |
TokenIdentifier |
String |
TokenIdentifier |
EsdtTokenIdentifier |
String |
TokenIdentifier |
EgldOrEsdtTokenIdentifier |
String |
EgldOrEsdtTokenIdentifier |
BigFloat |
(unsupported) | double |
ManagedByteArray<N> |
(unsupported) | Uint8List |
MultiValue<...> |
(unsupported) | record (T1, T2, ...) |
Generated struct fields, query return types and call arguments shift accordingly. Where pair.firstToken gave a String it now gives a TokenIdentifier -- use .value for the raw string.
Transactions the chain rejected #
- ESDT built-in functions are addressed to the sender, not the ESDT system contract, because they execute against the caller's own account:
ESDTNFTCreate,ESDTLocalMint,ESDTLocalBurn,ESDTNFTUpdateAttributes,ESDTNFTAddQuantity,ESDTNFTBurn,ESDTModifyRoyalties,ESDTSetNewURIs,ESDTModifyCreator,ESDTMetaDataUpdate,ESDTMetaDataRecreate,ESDTNFTAddURI,ESDTNFTUpdate,ESDTNFTRecreate. The other 23 endpoints still target the system contract. - Governance contract address corrected from
…0006ffffto…0003ffff. Every governance transaction went to an account that is not a contract, andcreateTransactionForNewProposalstranded its 1000 EGLD deposit there. - Validator operations target the validator contract (
…0001ffff) instead of the staking contract (…0000ffff), which only accepts calls from the validator contract — wallet-signed staking transactions could never succeed. changeConfigencodesminQuorum,minVetoThresholdandminPassThresholdas ASCII decimal, which is what the contract parses; they were sent as big-endian integers.clearEndedProposalsgas scales with the proposer count (gasLimit + n * gasLimit) instead of a flat limit.registerAndSetAllRolesandregisterDynamicemit the mandatory token type, which both omitted;registerAndSetAllRolesDynamicappendsnumDecimalsonly forMETA.- Token properties are written in full. Only enabled flags were emitted, but a missing pair does not mean "disabled" — the contract creates tokens with
canUpgradeandcanAddSpecialRolesalready on and overrides only the properties the arguments name, soTokenProperties(canUpgrade: false)produced an upgradable token andcontrolChangescould not switch a property off. The fungibleissueendpoint omitscanTransferNFTCreateRole, which is not part of its argument list. - Factories add the data-movement gas term (
minGasLimit + gasLimitPerByte * data.length) on top of execution gas. Token-management, delegation and the guardian builders shipped the bare execution limit, under-charging by an amount that grew with the payload.
Signing and relayed transactions #
innerTransactionsno longer reaches the signing payload. The field is not part of the chain's transaction format, so every relayed transaction was signed over a payload the node cannot reconstruct and the signature could not verify. Removed fromTransactionentirely.RelayedTransactionsFactoryimplements flat relayed v3: one transaction carryingrelayerandrelayerSignature. Attach the relayer withapplyRelayerbefore signing, then sign with the sender and the relayer in either order.Transaction.serializeForSigning()applies the Keccak digest when the hash-signing option bit is set.signWith,signAsRelayerandsignAsGuardiansigned the raw payload, producing signatures the chain rejects.UserPublicKey.verifyreturnsfalsefor malformed signatures instead of throwing; the result was returned withoutawaitinside thetry, socatchnever saw asynchronous errors.Account.fromMnemonicdisposes the mnemonic after key derivation completes, not before.
Outcome parsers #
TokenManagementOutcomeParser reads the logs of the transaction's smart-contract results as well as its own. freeze, unFreeze, wipe, setSpecialRole, unSetSpecialRole and the local mint/burn pair act on another account by forwarding a built-in call, so their events land on the result rather than the transaction. Every such parse returned an empty list, and a signalError reported on a result was invisible — a failed transaction parsed as a successful empty outcome.
Network providers #
TransactionOnNetwork.fromApiResponsereads smart-contract results fromresults; they were alwaysnull.relayedVersionis aString?('v1','v2','v3'); it was parsed as an integer and threw on every relayed transaction.- Corrected routes: transaction simulation, guardian data, and the gateway's non-fungible token listing, which pointed at a path no node or proxy serves.
- Guardian fields are read from the flat account payload, and the provider sends the query flag required to return them.
GatewayNetworkProvideraccepts aNetworkProviderConfig, so user agent, timeout and retry policy apply to it as well.- Request throttling and GET-response caching are available through
NetworkProviderConfig, both off by default.
Supernova #
Block timestamps move from seconds to milliseconds at the Supernova activation epoch without a field rename, and the unit differs per route. Reading such a value as seconds yields a date in the year 57,000.
TransactionOnNetworkexposestimestampMsalongsidetimestamp, plusexecutedAt, which normalises either unit by magnitude.NetworkStatusexposesblockTimestampandblockTimestampMs; block, hyperblock, account and token models expose their millisecond counterparts.- Block models carry
lastExecutionResultHashandlastExecutionResultNonce, which asynchronous execution reports separately from the block itself. miniblockTypeis read with the spelling the node emits.AccountAwaiterpolls every 600 ms, matching sub-second block times.- Added the
reward-revertedstatus.
ABI #
- The type names
TokenId,NonZeroBigUint,PaymentandFungiblePaymentresolve. Contracts referencing them carry no definition intypes, so such an ABI failed to load. - Enum variant payload fields are parsed, so fielded enums decode rather than being truncated.
specificTypeand the contract's internal method name are surfaced on the endpoint and parameter models;specificTypedistinguishes au64holding milliseconds from one holding seconds.- Corrected
ExplicitEnumValue.toBytes()and the counted-variadic argument convention. BigFloathas no portable wire form; encoding, decoding andtoBytesthrow. The type exists so that ABIs mentioning it still load.
Removed #
Each entry has a working replacement; none of the removed members could produce a valid result.
| Removed | Use instead |
|---|---|
SignableMessage |
Message + MessageComputer.computeBytesForSigning |
ValidatorSigner(secretKey), ValidatorSigner.fromPem |
ValidatorSigner.custom(signFn) |
TransactionStatus.recalled, isRecalled |
— status does not exist on chain |
NetworkConfig.gasPriceModifierString |
gasPriceModifier |
functionCallHexParts on the multisig builders |
functionCall: <TypedValue>[...] |
RelayedTransactionsFactory.createRelayedTransaction |
applyRelayer, then sign |
createTransactionForDelegatingVote |
— callable only by a contract |
createTransactionForUnsettingBurnRoleForAll |
createTransactionForUnsettingBurnRoleGlobally |
Transaction.innerTransactions |
— not part of the transaction format |
Public API #
NetworkProviderConfig, RetryPolicy, UserAgent, GuardianData, Guardian, CodeMetadata, EsdtTokenPaymentType and EgldOrEsdtTokenPaymentType are exported. They were declared public but unreachable from the package barrel, which made the configuration surface unusable from outside the package.
Tooling #
- Generated code is formatted for the language version of the SDK running the generator. The generator wrote unformatted Dart, so any project with a
dart format --set-exit-if-changedcheck failed on its own generated sources. - The ABI validator no longer warns on keys that are not part of the ABI schema, which broke
--fail-on-warningsfor valid ABIs. - Integration tests that perform live network calls are tagged and skipped by default; run them with
dart test -P integration. - Added
dart_styleandpub_semverdependencies.
Generator internals #
bin/codegen/utils/imports_formatter.dartdeleted. Import ordering now lives inside each generator via the existingimport_manager/ per-file_writeSortedImportshelpers.BarrelGeneratorno longer dual-tracks event-model file names; the helper computes the suffix once.- Reserved-keyword sanitisation consolidated through
NameSanitizer; the duplicate list inevent_models_generator.darthas been removed (the keyword set is now sourced fromname_sanitizer.dart).
Docs #
- New page:
network/entrypoints.mdcovering all eight entrypoint classes plus thegasLimitEstimatorinjection point. - Sidebar moved entrypoints under the existing Network category.
- Codegen and smart-contract pages updated to show the new generator output (
Address/TokenIdentifierwrappers, autogas probe pattern).
Migration #
- Move to Dart 3.13 or newer, then
dart pub upgrade abidock_mvx(or bump to^3.0.0inpubspec.yaml). - Regenerate any committed codegen output. Diffs to expect:
- Struct fields that previously held
StringforAddress/TokenIdentifiernow hold the wrapper type. - Generated
*Unsignedcall helpers are unchanged on the wire; the signed helpers now do the probe-then-sign dance internally. - Generated files are formatted.
- Struct fields that previously held
- Walk the call sites; the compiler will flag every
String/Addressmismatch, every removed member listed under Removed, andrelayedVersionmoving fromint?toString?. - Re-check any hard-coded gas limits. Factory-produced limits now include the data-movement term and are higher than before.
- Re-check anything that reads
TransactionOnNetwork.timestampdirectly; preferexecutedAt. - (Optional) Swap
ApiNetworkProvider(...)+ factory plumbing forDevnetEntrypoint()/MainnetEntrypoint()etc.
1.2.0 -- 2026-04-17 #
Public-key encryption now actually uses X25519 #
PubkeyEncryptor and PubkeyDecryptor were feeding raw Ed25519 key bytes into X25519 APIs. The code round-tripped with itself (both sides made the same mistake), but the ciphertext couldn't be decrypted by anything else — mx-sdk-js-core, NaCl, libsodium, or any tool that does real X25519.
This release adds the two standard Curve25519 key conversions, both exposed under lib/src/wallet/crypto/curve25519_conversion.dart:
ed25519PublicKeyToX25519(edPub)— the Bernstein/RFC-7748 birational mapu = (1 + y) / (1 - y) mod (2^255 - 19).ed25519SeedToX25519SecretKey(seed)—SHA-512(seed)[0:32]followed by RFC 7748 clamping, matching libsodium'scrypto_sign_ed25519_sk_to_curve25519.
The encryptor and decryptor now call through these on both sides, so the wire format is real X25519-XSalsa20-Poly1305 and will interoperate with any standard implementation.
Breaking change #
Anything encrypted with 1.1.0 or earlier PubkeyEncryptor cannot be decrypted by 1.2.0, and vice versa. The serialized schema (X25519EncryptedData) is unchanged — only the math behind it is now correct.
1.1.0 -- 2026-04-16 #
This release closes a pile of wire-format mismatches against the chain, fills in the protocol coverage that was missing (staking, governance, relayed-v3, SC lifecycle), and tightens the concurrency primitives that sit between the SDK and the network. There are a handful of breaking changes, all listed at the bottom — most projects won't notice them.
Wire format #
Transaction hashing now matches the chain byte-for-byte. The culprits were subtle: protobuf zero-values were emitted as a single zero byte instead of the sign+magnitude pair, Option<T> top-level encoding dropped its marker, signed BigInt nested encoding lost its sign extension on -129 and friends, and hash-signed transactions were being fed the raw JSON bytes instead of the Keccak digest. The message-signing prefix went back to the canonical \x17Elrond Signed Message:\n — signatures need to interop with existing wallets and hardware devices, so renaming to "MultiversX" wasn't an option.
Network provider #
Endpoints that were quietly wrong got fixed: bulk-send, VM query, transaction status, NFT nonce padding (even-length hex), process-status vs transaction endpoint on Gateway, the fungible-vs-NFT filter split on _parseEsdts, account storage key routing, and block-by-nonce shard prefixing. The circuit breaker now wraps smart-contract queries too. ApiNetworkProvider.estimateTransactionCost throws UnsupportedError instead of pretending to work.
SendTransactionsResult now returns per-transaction outcomes (SendTxSuccess / SendTxFailure with the node's rejection reason) alongside the aggregate counts, so bulk submission can drive a resubmission loop properly.
New protocol coverage #
SmartContractTransactionsFactoryfor deploy / upgrade / change-owner / claim-developer-rewards.StakingTransactionsFactoryfor the direct-staking system SC (stake, unStake, unBond, claim, changeRewardAddress, changeValidatorKeys, unJail, reStakeUnStakedNodes).GovernanceTransactionsFactoryfor proposing, voting, delegate-voting, closing, and claiming accumulated fees.RelayedTransactionsFactoryfor relayed-v3.Transactiongained aninnerTransactionsfield and the protobuf serializer emits them on field 18.TransactionDecoderlearned the matching sealed subclasses:ContractDeploy,ContractUpgrade,ContractChangeOwner,ClaimDeveloperRewards,RelayedV3Transaction.TokenManagementTransactionsFactorygained the nine built-ins it was missing:transferOwnership,controlChanges,ESDTNFTAddURI,stopNFTCreate,transferNFTCreateRole,unsetBurnRoleGlobally,registerAndSetAllRolesDynamic,changeSFTToMetaESDT,updateTokenID.
Concurrency & resilience #
CircuitBreaker now enforces a single in-flight probe in the half-open state — the old behaviour let a burst of callers all punch through, which defeated the point. NonceManager uses a proper FIFO Completer-queue mutex and refuses to release nonces that were already committed on-chain. AccountAwaiter and Paginator dedup is keyed correctly now; backoffs cap at the remaining timeout instead of sleeping past it. There's a new RequestThrottle token-bucket utility for smoothing bursts against rate-limited endpoints (API is ~30 rps per IP).
TransactionWatcher accepts optional numShards + roundDuration + awaitCrossShardCompletion flags. When set, it waits for the chain's completedTxEvent / SCDeploy / signalError log before returning — no more premature "success" snapshots for cross-shard SC calls.
Wallet & accounts #
Keystore parsing rejects non-v4 / wrong-cipher / wrong-kdf at load time instead of throwing downstream with a confusing message. ScryptKeyDerivationParams.permissive() accepts weaker parameters from external wallets but still requires n >= 1024. Mnemonic derivation and the BIP-39 passphrase are NFKD-normalised now (new dep: unorm_dart) — this matters for non-ASCII passphrases. Account.fromMnemonic disposes the mnemonic in finally. Signature.fromBytes rejects non-64-byte inputs. Bech32Encoder rejects mixed-case strings per BIP-0173.
IAccount picks up prefersHashSigning, signAsGuardian, and signAsRelayer — the minimal surface a controller needs to support hardware and remote signers without hard-coding the key material.
Codegen #
Queries that return a struct, an enum, or a list of them used to crash at runtime because the generated fromAbi path only handled primitives. They work now, including List<Struct> via (result.typedValues[i] as ListValue).elements.map(...).toList(). Reserved-word parameter names (new, function, class, etc.) get sanitised. Unused imports are gone. example/cookbook/generated/pair regenerates analyzer-clean.
Core types #
Address equality now includes the HRP (two addresses with identical bytes but different hrp are not equal — they represent different networks), and AddressComputer.computeContractAddress propagates the deployer's HRP instead of hard-coding "erd". Transaction.data and Message.bytes return defensive / unmodifiable views so callers can't mutate the source. Balance gained *, ~/, %, and ratioTo. Numerical toBytes() methods now return fresh allocations instead of shared mutable singletons. AccountStorage picked up ESDT key-prefix helpers: esdtEntry, esdtRolesEntry, esdtLastNonceEntry, entriesWithPrefix.
Mnemonic-from-keystore #
Three new public entry points for integrators that need to recover the mnemonic directly from a kind == "mnemonic" keystore:
UserWallet.loadMnemonic(path, password)— reads a keystore file and returns the decryptedMnemonic.UserWallet.decryptMnemonic(json, password)— same thing, but from an already-parsed JSON map.UserWallet.decryptMnemonicBytes(json, password)— returns the raw UTF-8 bytes of the mnemonic phrase, so external libraries can build their own wrapper without going through theMnemonicclass.
Breaking changes #
Address ==/hashCodeinclude the HRP.Signature.fromBytes/.fromUint8Listreject non-64-byte inputs.IAccounthas three new required members:prefersHashSigning,signAsGuardian,signAsRelayer.SendTransactionsResultadds anoutcomesfield.TransactionaddsinnerTransactions.Transaction.dataandMessage.bytesare no longer mutable.TransactionComputer.applyGuardianthrowsStateErrorwhen replacing a different guardian (instead of silently overwriting).
1.0.1 – 2026-04-16 #
Security #
- Transaction fee calculation now uses pure integer arithmetic instead of lossy
doublemultiplication, matchingmx-chain-gobehaviour for gas prices exceeding 2^53. ProtoSerializer._serializeValuerejects negativeBigIntvalues at runtime instead of silently producing malformed hex.Address.hashCodeuses FNV-1a with& 0x7FFFFFFFmask, preventing unbounded integer growth on web targets.Balance.fromEgldandManagedDecimalValue.fromDoubleusetoStringAsFixedto eliminate IEEE 754 floating-point noise before parsing.Ed25519Crypto.generatePublicKeynow zeros extracted seed bytes in afinallyblock, matching the pattern already used insign.ListBinaryCodec.decodeTopLevelguards against zero-progress decoding loops that could cause infinite loops / OOM.Address.fromHexvalidates decoded byte length at runtime (not just via debugassert).BooleanBinaryCodecandOptionBinaryCodecmarker buffers now return fresh allocations instead of shared mutable singletons.UserSecretKey.generaterejects all-zeros and all-0xFF seeds fromRandom.secure().
Fixed #
SmartContractResult.fromJsonno longer throwsFormatExceptionwhen a network response returns a numericvaluefield (Gateway and some API shapes emitvalue: 0asint).- Generator
models_generator.dartnow emits the enum-discriminant guard as a braced block so regenerated code stays analyzer-clean undercurly_braces_in_flow_control_structures. - Applied the same block-style fix to the committed generated output under
example/cookbook/generated/.
Changed #
- Removed the arbitrary max-scale-77 restriction from
ManagedDecimalBinaryCodec.encodeNestedto matchencodeTopLeveland the Rust SDK. - Added
@visibleForTesting BinaryCodec.resetCache()to allow test isolation of the codec singleton. NativeSerializer._toBigIntusesBigInt.from(value)directly for doubles instead of the truncatingBigInt.from(value.toInt()).Transaction.copyWithaccepts an optionalnewDataparameter.Nonce.operator -throwsArgumentErrorat runtime if the result would be negative, instead of relying on a debug-onlyassert.- Added
ScryptKeyDerivationParams.permissive()constructor for keystore import/decryption, accepting weaker KDF parameters from external wallets.EncryptedData.fromJsonnow uses it. Address.getShardOfAddressuses integer bit-scan instead of floating-pointlogfor the shard mask computation.- Codebase-wide
dart formatsweep to satisfy thedart format --set-exit-if-changedCI gate.
1.0.0 – 2026-04-12 #
Fixed #
- Hardened
Address._extractHrpagainst malformed Bech32 strings where'1'appears at index 0. TransactionVersionvalues parsed from network responses (Transaction.fromPlainObject,TransactionOnNetwork.fromApiResponse) now go through a runtime-validated factory that rejectsvalue <= 0even in release builds.CircuitBreakernow resets_halfOpenSuccessCountwhen transitioning half-open → open on failure, preventing state leakage across rapid open/half-open cycles.- Fixed two's complement encoding for negative values in
NumericalValue.toTopBytes()-- was missing +1 carry propagation. - Fixed
BigIntValue.toBytes()sign extension -- positive values with high bit set now get 0x00 prefix. - Fixed
ProtoSerializerzero-value encoding from[0x00, 0x00]to[0x00], correcting transaction hash computation. - Fixed
ManagedDecimalBinaryCodecnested decode/encode for fixed-scale types -- payload offset was off by 4 bytes and length prefix was missing. - Fixed
ManagedDecimalSignedValue.fromDouble/.fromString-- was always throwing CastError due to parent-to-subclass cast. - Fixed
ManagedDecimalValue.toDecimalString()sign loss for values between -1 and 0. - Corrected Option top-level encoding to omit marker byte (None = empty, Some = raw inner value).
- Fixed
NativeSerializervariadic argument handling -- cardinality check and index-based access both failed for variadic endpoints. - Fixed
TransactionStatus.isFinalfrom!isPendingtoisExecuted || isFailed || isInvalid || isRecalled-- previously incorrectly classifiednot-executable-in-blockas final (causing watchers to stop early), and classifiedrecalledas non-final (causing infinite polling). - Fixed
TransactionWatcherto use injectedNetworkProviderinstead of raw Dio with hardcoded URL. - Fixed
UserPublicKey.toAddress(hrp:)-- was silently ignoring thehrpparameter. - Fixed
ArgSerializer.stringToBuffersreturning[Uint8List(0)]for empty input instead of[]. - Fixed
SmartContractCallFactoryhardcodedTransactionVersion(1)-- now version 2 when guardian is set. - Fixed
SmartContractQueryRunnersharing a singleEndpointResolverbetween query building and response parsing. - Fixed
Address.fromBech32HRP extraction to uselastIndexOffor Bech32/BIP-0173 compliance. - Fixed
Address.fromBech32static encoder with hardcoded 'erd' -- now creates encoder with extracted HRP. - Fixed
SmartContractOutcomeParserto pick lastwriteLogevent instead of throwing on multiples. - Fixed
NativeSerializerto respect endpoint mutability and skip return-type decoding for write endpoints. - Fixed
NativeSerializer._toBytesfrom UTF-16codeUnitsto properutf8.encode(). - Fixed
NativeSerializer._convertNativeToAddressto accept any HRP, not just 'erd'. - Fixed
GatewayNetworkProviderresponse parsing to use correct field names and safe null handling. - Fixed
ResponseParser._stringToBytesto try base64 before hex, matching API response format. - Fixed
ResponseParser._isOptionalTypefrom string comparison to proper type check. - Fixed
TransactionOnNetwork.fromApiResponseto handle non-base64 data fields gracefully. - Fixed
EndpointResolver._isVariadicParameterfrom fragile string matching toparam.type is VariadicType. - Fixed
TypeFormulaLexerto accept hyphens in type identifiers (e.g.counted-variadic). - Fixed token identifier validation to enforce 6-character hex ticker suffix.
- Fixed
AccountAwaiterdefault timeout from 30s to 60s and added retry with exponential backoff. - Fixed
AddressValue.getShardId()from simple modulo to proper bit-masking algorithm. - Fixed
BigInttype name casing to match SDK convention. - Fixed
EndpointResolverto throw on duplicate endpoint names. - Fixed
ManagedDecimalscale validation (must be non-negative). - Fixed
SmartContractEventRunnerto use boundedEventDeduplicatorinstead of unboundedSet. - Fixed
Paginator._fetch()race condition with proper request deduplication. - Input validation across infrastructure layer (circuit breaker, cache, batch, pagination).
Changed #
TransactionStatusnow includesexecuted,notExecutable, andrecalledstatuses.SmartContractEventRunnersubscriptions now returnStreamSubscriptionfor proper lifecycle management.WebSocketEventStreamreconnection uses exponential backoff with jitter.AccountOnNetworkfields (nonce,balance,address) are now required.TransactionOnNetworkadds null-safe access for optional API fields.EnumValue/ExplicitEnumValuediscriminant encoding standardized to u8.VariadicValuesvalidates matching lengths between values and types.ArgumentEncoder.encodeTypedValuesnow expands variadic and composite types into separate arguments.- Codegen:
CallsGeneratorno longer imports unused output types; fixes unused import warnings. - Codegen: generated files now include
GENERATED CODE - DO NOT MODIFYheader. - Codegen: enum
fromAbiuses discriminant lookup instead of array index. - Codegen:
toJson()properly serializes nested structs, enums, BigInt, and Address fields.
Added #
not-executable-in-blockandrecalledtransaction status support.CompositeValue.isEmpty/isNotEmptyconvenience getters.TokenTransferTypesupport in code generator type mapper.Address.isZerogetter for zero-address checks without allocating a newAddress.zero().TransactionAwaitingOptions.maxConsecutiveErrors-- aborts polling after repeated fetch failures with exponential backoff.TransactionAwaitingOptions.patience-- waits for block finalization after status reaches final state.AbiEndpoint.mutability/isPure/isReadonly-- preserves raw mutability ('pure' vs 'readonly' vs 'mutable').NetworkProvider.getDefinitionOfFungibleToken,getDefinitionOfTokenCollection, andgetNonFungibleToken-- rich token metadata queries on the API provider (Gateway surfaces these viaUnsupportedError, matching the other metadata endpoints).NetworkProvider.getBlock,getLatestBlock(shard:), andgetHyperblock(nonce)-- block and cross-shard hyperblock queries. GatewaygetLatestBlocktwo-hops throughnetwork/status/<shard>to resolve the current nonce.BlockOnNetworkandHyperblockOnNetworktypes with schema-tolerantfromJsonfactories that accept both API and Gateway field aliases.- Typed
SmartContractResultparsed eagerly from the@<returnCode>@<returnData>...payload.TransactionOnNetwork.smartContractResultsis nowList<SmartContractResult>?(wasList<Map<String, dynamic>>?). NonceManager-- stateful forward-only nonce allocator with mutex-serializednext(), release/reuse queue,applyNonce(Nonce)floor, andresync()that never goes backwards. Use it for bulk sends without round-trippinggetAccountbetween each transaction.TransactionDecoder-- pure, never-throwing parser that turns aTransactioninto a sealedDecodedTransactionhierarchy:NativeEgldTransfer,EsdtTransfer,NftTransfer,MultiTransfer,ContractCall,UnknownTransaction. Supports inner contract calls nested after ESDT/NFT/MultiESDT transfer prefixes.
Changed #
TransactionAwaitingOptionsdefaults: polling 400ms, patience 800ms, timeout 60s -- tuned for Supernova block times.SmartContractEventRunner.streamEvents/streamAllEventsdefault polling lowered from 2s to 500ms for Supernova 600ms blocks.CacheManagercaps the number of cache instances to prevent unbounded growth from high-cardinality endpoints._encodeSignedTopLevelallocates directly intoUint8Listinstead of spreading through a temporary list.base_controllerguardian/relayer checks useisZerogetter instead of allocatingAddress.zero()per call.- Codegen
CallsGenerator._collectCustomTypesnow includes output types to avoid missing imports for custom return types. - Codegen
NameSanitizerkeyword lookup is now case-insensitive and includesfunctionconsistently withKeywordSanitizer.
Security #
PubkeyDecryptorzeros secret key bytes in afinallyblock after decryption.ScryptKeyDerivationParamsnow validates KDF parameters per RFC 7914:nmust be power of 2 and ≥ 16384,r≥ 8,p≥ 1,dklen= 32. Prevents weak-parameter keystores from decrypting silently.EncryptedData.fromJsonsurfaces invalid KDF parameters from untrusted keystore input asFormatExceptionrather than passing through silently.
1.0.0-beta.2 – 2025-12-20 #
Fixed #
- Fixed dangling library doc comments in codegen files.
- Updated package description to meet pub.dev length requirements.
- Replaced
flutter_lintswithlintsfor pure Dart compatibility.
1.0.0-beta.1 – 2025-12-08 #
Added #
- First public release of the MultiversX Dart/Flutter SDK and CLI.
- Wallet tooling covering mnemonic, PEM, and keystore workflows.
- Transaction builders for EGLD, ESDT, NFT, SFT, and MetaESDT transfers.
- High-level smart-contract controller with ABI-driven calls, queries and events.
- Gateway and REST network providers plus WebSocket event streams.
- ABI codecs for primitives, collections, composites, and protocol-specific special types.
- Code generator capable of scaffolding controllers, DTOs, and tests from ABI files.
- Cookbook examples and wallet walkthroughs demonstrating real integrations.
- 900+ automated tests spanning core types, infrastructure, serializers, and integration scenarios.