All notable changes to ackinacki-kit are documented here. The format loosely
follows Keep a Changelog; the workspace is
versioned as a whole (package.version in the root Cargo.toml).
Account::balancenow decodes the GraphQL hexadecimal representation of TVMGramsas an unsigned magnitude. The public type remainsOption<BigInt>, but values whose most-significant byte starts with bit1are no longer misreported as negative two's-complement numbers.
The multisig binding now targets UpdateCustodianMultisigWallet_v2 v2.4.0.
The bundled ABI/TVC under contracts/abi/multisig/ are re-vendored verbatim from
gosh-sh/acki-nacki (dev, commit 44fe02ea,
contracts/0.81.0_compiled/updatecustodianmultisigwallet_v2/), replacing the
6ad89549 build shipped in 5.0.0. Nothing older is supported: the wallet
gained a fourth request queue and a stored balance config, so storage layout,
constructor and event set all differ. Wallets whose code hash is not CODE_HASH
must be driven by a binding that matches them.
- Balance config (gas self-management) — the wallet converts SHELL to vmshell
when its balance drops below
minBalance, up totargetBalance;minBalance == 0disables it, and the config survives custodian changes. Bound assubmit_config_update/confirm_config_update(withParamsOfSubmitConfigUpdate,ResultOfSubmitConfigUpdate,ParamsOfConfirmConfigUpdate) plusget_balance_config,get_config_update,get_config_updatesandget_config_update_ids. NewBalanceConfigandConfigUpdatetypes. - Custodian-set updates —
submit_data_update/confirm_data_updateand the queue readsget_update_data,get_update_datas,get_update_data_ids. Applying one now clears all four queues (transfers, data, code, config). - Code-update queue reads —
get_update_code(with the pending cells),get_update_codes(each pending code identified by hash, as the contract's listing get-method does; the hashes are computed from the stored cells) andget_update_code_ids. NewCodeUpdateInfotype. set_max_cleanup_operationsandget_max_cleanup_operations— the expired-request cleanup budget, withMIN_CLEANUP_OPERATIONS/DEFAULT_CLEANUP_OPERATIONSmirrored from the contract.is_confirmed(mask, index)— the contract'sisConfirmed, as a pure function; andexpiration_bound(now)+ZERO_TIME, the request-id expiry arithmetic behind the list-shaped reads.AccountDatagains the v2.4 fieldsrequests_mask_config,config_updatesandbalance_config.
CODE_HASHis nowcfcaac10d43c8dc062298cb48df097be67cddec52b9cfd558309a7549f01c1f1,VERSIONis2.4.0, and the vendored TVC's sha256 changed. Deploys must pair this TVC with this ABI (on ABI ≥ 2.3 the address depends on the ABI'sfieldslist).- The v2.4 constructor takes two more arguments (
minBalance,targetBalance). Deploy stays out of scope here, but a deployer's call has to grow with it. - The list-shaped reads (
get_transactions,get_transaction_ids, and the newget_update_datas/get_update_codes/get_config_updatesand their id forms) drop expired requests, the way the contract's listing get-methods do. Since expiry is derived from the request id and there is no block clock off-chain, the bound is computed from the client's clock. The by-id reads still return an expired request, also matching the contract, andaccount_data()exposes every queue unfiltered. get_custodiansis ordered by the storedhash(pubkey, address)map key — which is what the on-chain dictionary is keyed by, and what its iteration order follows. The5.0.0entry described this as ordering byowner_pubkey; the order itself is unchanged.- Constant docs:
MAX_QUEUED_TRANSACTIONS(contractMAX_QUEUED_REQUESTS) caps unconfirmed requests per custodian per queue, all four queues separately.
submit_transaction,send_transaction,confirm_transaction,submit_update_code,confirm_update_codeand their params, includingdapp_id(still stored for off-chain use and not used to address the outbound message).- Reads still decode the account's data cell instead of executing get-methods:
a get-method call still fails in
run_tvmwithcode 404 TVM internal error: can not parse actions: 0, becausetvm_block's action-list parser does not recognise a tag emitted bysol 0.81.0output. This build comes from the same compiler as the one that was verified on shellnet. - Events are still not bound. The wallet's lifecycle events (now 15, ids
1100–1116) can be decoded throughcrate::eventwith this ABI.
The multisig binding now targets UpdateCustodianMultisigWallet_v2
exclusively. The bundled ABI/TVC under contracts/abi/multisig/ are vendored
verbatim from gosh-sh/acki-nacki (dev, commit 6ad89549,
contracts/0.81.0_compiled/updatecustodianmultisigwallet_v2/), replacing the
older flat Multisig build.
submit_update_code/confirm_update_code— the v2-only code upgrade, queued and confirmed like a transaction, withParamsOfSubmitUpdateCode,ResultOfSubmitUpdateCodeandParamsOfConfirmUpdateCode.Multisig::account_data()— fetches the account and decodes its persistent storage. This is the single round-trip behind every read method; call it directly when you need more than one of them.- Storage now decoded in full:
AccountDatagainstransactions,data_updates,code_updatesandcustodians(allBTreeMap, so iteration order is stable) plus the v2 fieldrequests_mask_code. NewDataUpdateandCodeUpdatetypes. - Contract constants mirrored from the vendored build, since they live in code
and not in the data cell:
MAX_QUEUED_TRANSACTIONS,MAX_CUSTODIAN_COUNT,EXPIRATION_TIME,VERSION,CONTRACT_NAME, andCODE_HASH(the code hash a node reports for accounts deployed from the bundled TVC). - Tests pinning the vendored assets (TVC sha256 + code hash +
sol 0.81.0), asserting the ABI is the v2 build, and decoding the TVC's initial data cell throughAccountDataso the storage layout is checked without a network.
get_versionis no longer a network call: it is now a synchronousfn get_version(&self) -> ResultOfGetVersionanswering from the vendored constants. It describes the bundled assets, not the code deployed at the wallet's address — compare the account's code hash againstCODE_HASHto confirm the two agree.multisig::ResultOfGetVersionis gone; the binding reusestraits::ResultOfGetVersion, whose fields areversion/contract_name(the removed local type hadkind/version).- Every read method (
get_parameters,get_custodians,get_transactions,get_transaction,get_transaction_ids) now decodes the account's data cell instead of executing a get-method —Multisigno longer goes throughGetMethodAccessor. Running any get-method against the v2 code fails inrun_tvmwithcode 404 TVM internal error: can not parse actions: 0, becausetvm_block's action-list parser does not recognise a tag emitted bysol 0.81.0output (identical in tvm-sdk 3.0.2 and 3.0.4, so bumping the SDK does not help). Verified on shellnet for all six read methods. Writes are unaffected — they go throughprocess_message. - Consequences of reading storage:
get_parametersanswersmaxQueuedTransactions/maxCustodianCount/expirationTimefrom the mirrored constants above;get_transactionnow errors withKitErrorCode::EmptyResultwhen the id is not queued (the contract throws102in the same case);get_transactions/get_transaction_idssort ids numerically andget_custodiansis ordered byowner_pubkey. - Wallets deployed from the older flat
Multisigbuild still accept writes from this binding (all 17 shared functions keep their signatures and function ids), but decoding their storage with the v2 ABI is not valid, so the read methods are only defined for v2 wallets.
submit_transaction,send_transaction,confirm_transactionand their params, includingdapp_id.- Deploy stays out of scope — wallets are deployed by the end-user via
tvm-cli. Note that on ABI ≥ 2.3 the deploy address depends on the ABI'sfieldslist as well as the code, so a deployer must pair this TVC with this ABI.
- Bumped the
tvm-sdkpin (tvm_block/tvm_client) fromv3.0.2.antov3.0.4.an. - Added
[patch]tables to the rootCargo.toml, replicated from the tvm-sdk workspace root: sincev3.0.4.an,tvm_vmpulls the zk stack (axiom-ethplus the gosh-sh halo2 forks), and Cargo only honors[patch]from the top-level workspace — without the replicas the graph resolves two incompatible copies ofhalo2-axiom/halo2-baseand fails to compile (E0277Circuit<F>trait mismatch).
The GraphQL server is now stable at >= 1.0.0 across all networks, so the kit
no longer carries the legacy (< 1.0.0) wire format or the runtime
version-detection that switched between them. Every address-bearing query now
unconditionally uses the v3 account(account_id, dapp_id) form.
dapp::supports_dapp_id(context, module)— the server-generation probe. The kit no longer branches on server version; the SDK already gatesdapp_idinternally forget_account/send_message.
- Dropped the legacy
account(address:)GraphQL queries and the per-callif v3 { … } else { … }branches inevent,authservice::root,authservice::profile, andaccumulatorevent paging. The v3 queries (their former*_V3constants, now un-suffixed) are the only form sent.
dapp::SystemDappand its fixed dApp IDs.- All public wrapper constructors and
query_*signatures (dapp_idwas already mandatory).
DEX contract wrappers moved out of the kit into the consumer crate
(dodex-contracts). The kit now ships only the wrapper framework (traits +
infra); downstream crates name their module via a new open KitModule variant.
KitModule::External(&'static str)— an open module identity for wrappers that live in downstream crates built on the kit traits. The payload is a stable, caller-chosen id (e.g."dex.private_note") and is&'static strso it stays usable in the constModuleAccessor::MODULE.#[non_exhaustive]onKitModule, so future external module groups never require an enum edit.
- All DEX bindings and event decoders (
contracts/src/dex/:private_note,order_book,pmp,oracle,oracle_event_list,root_oracle,root_pn,nullifier, their*_events, anddex/tests.rs) and their ABIs (contracts/abi/dex/). Thedexmodule is no longer exported from the crate. KitModule::Dexand theDexModuleenum — relocated wrappers identify their module viaKitModule::External("dex.<contract>"). (The DEX market never shipped to mainnet, so no transition period / deprecation window was needed.)
- The trait framework (
traits.rs),KitError/KitErrorCode/KitResult, andaccount/event/deserialize/dapp/giver/multisigplus thesharedguard traits and the rootpub use tvm_clientre-export keep their signatures.
multisigbinding for theMultisigcontract (v2 ABI):submit_transaction,send_transaction,confirm_transaction, and the read getters (get_parameters,get_custodians,get_transaction(s),get_transaction_ids,get_version). Bundles theMultisigABI + TVC undercontracts/abi/multisig/.dapp_id(uint256) on the message-sending params —ParamsOfSubmitTransactionandParamsOfSendTransactiongain adapp_idfield (defaults to"0") — and on the decodedTransaction, matching the v2 ABI's destination dApp id.KitModule::Multisigerror-module variant.- ABI-cross-check unit tests for the multisig params: every
submitTransaction/sendTransactionABI input must have a matching serialized key, so a binding/ABI drift (e.g.flagvsflags,dapp_id) fails atcargo testrather than on-chain.
Multisig::newtakesimpl Into<ParamsOfNewContract>(address + dApp id), consistent with the other contract bindings; a user-deployed wallet is addressed under its own account-id dApp rather than the System dApp.- Synced with
dev.
Predate this changelog — see the git tags and history.