abidock_mvx 1.2.0
abidock_mvx: ^1.2.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.
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.