solana_kit_fast_stable_stringify 0.9.1
solana_kit_fast_stable_stringify: ^0.9.1 copied to clipboard
Deterministic JSON serialization for the Solana Kit Dart SDK.
solana_kit_fast_stable_stringify #
Deterministic JSON serialization with sorted keys. Two maps with the same keys in different insertion order produce the same output string.
Installation #
Install the package directly:
dependencies:
"solana_kit_fast_stable_stringify": ^0.9.1
If your app uses several Solana Kit packages together, you can also depend on the umbrella package instead:
dart pub add solana_kit
Inside this monorepo, Dart workspace resolution uses the local package automatically.
Documentation #
- Package page: https://pub.dev/packages/solana_kit_fast_stable_stringify
- API reference: https://pub.dev/documentation/solana_kit_fast_stable_stringify/latest/
- Workspace docs: https://openbudgetfun.github.io/solana_kit/
- Package catalog entry: https://openbudgetfun.github.io/solana_kit/reference/package-catalog#solana_kit_fast_stable_stringify
- Source code: https://github.com/openbudgetfun/solana_kit/tree/main/packages/solana_kit_fast_stable_stringify
For architecture notes, getting-started guides, and cross-package examples, start with the workspace docs site and then drill down into the package README and API reference.
Usage #
Basic stringification #
fastStableStringify works like jsonEncode but sorts object keys alphabetically, producing deterministic output regardless of insertion order.
import 'package:solana_kit_fast_stable_stringify/solana_kit_fast_stable_stringify.dart';
void main() {
final json = fastStableStringify({
'zebra': 1,
'apple': 2,
'mango': 3,
});
print(json); // {"apple":2,"mango":3,"zebra":1}
}
Compare with standard jsonEncode, which preserves insertion order:
import 'dart:convert';
void main() {
// jsonEncode preserves insertion order -- non-deterministic.
print(jsonEncode({'zebra': 1, 'apple': 2, 'mango': 3}));
// {"zebra":1,"apple":2,"mango":3}
}
Supported types #
The function handles all common Dart types:
import 'package:solana_kit_fast_stable_stringify/solana_kit_fast_stable_stringify.dart';
void main() {
// null
fastStableStringify(null); // 'null'
// Booleans
fastStableStringify(true); // 'true'
fastStableStringify(false); // 'false'
// Integers
fastStableStringify(42); // '42'
fastStableStringify(-1); // '-1'
// Doubles
fastStableStringify(3.14); // '3.14'
fastStableStringify(double.nan); // 'null' (non-finite becomes null)
fastStableStringify(double.infinity); // 'null'
// Strings (JSON-escaped)
fastStableStringify('hello'); // '"hello"'
fastStableStringify('line\nbreak'); // '"line\\nbreak"'
// BigInt (appends 'n' suffix, matching JavaScript BigInt convention)
fastStableStringify(BigInt.from(200)); // '200n'
// Lists (recursively stringified)
fastStableStringify([1, 'two', null]); // '[1,"two",null]'
// Maps with sorted keys (recursively stringified)
fastStableStringify({'b': 2, 'a': 1}); // '{"a":1,"b":2}'
}
Nested structures #
Keys are sorted at every level of nesting:
import 'package:solana_kit_fast_stable_stringify/solana_kit_fast_stable_stringify.dart';
void main() {
final result = fastStableStringify({
'users': [
{'name': 'Alice', 'age': 30},
{'name': 'Bob', 'age': 25},
],
'count': 2,
});
print(result);
// {"count":2,"users":[{"age":30,"name":"Alice"},{"age":25,"name":"Bob"}]}
}
Custom objects with ToJsonable #
Classes that mix in ToJsonable and implement toJson() are serialized by recursively processing the return value:
import 'package:solana_kit_fast_stable_stringify/solana_kit_fast_stable_stringify.dart';
class User with ToJsonable {
User(this.name, this.age);
final String name;
final int age;
@override
Object? toJson() => {'name': name, 'age': age};
}
void main() {
final result = fastStableStringify(User('Alice', 30));
print(result); // {"age":30,"name":"Alice"}
}
Return value #
fastStableStringify returns String?. It returns null for values that have no JSON representation (such as plain Object instances that lack a toJson() method).
import 'package:solana_kit_fast_stable_stringify/solana_kit_fast_stable_stringify.dart';
void main() {
// Returns null for non-serializable top-level values.
final result = fastStableStringify(Object());
print(result); // null (Object has no toJson and jsonEncode fails)
// Inside arrays, non-serializable values become 'null'.
final arrayResult = fastStableStringify([1, Object(), 3]);
print(arrayResult); // [1,null,3]
}
Request deduplication #
The primary use of this function in the Solana Kit SDK is producing stable cache keys for RPC request deduplication. Because the output is deterministic, two requests with the same parameters but different key ordering produce the same string.
import 'package:solana_kit_fast_stable_stringify/solana_kit_fast_stable_stringify.dart';
void main() {
// These produce the same output regardless of key order.
final key1 = fastStableStringify({'method': 'getBalance', 'params': ['abc']});
final key2 = fastStableStringify({'params': ['abc'], 'method': 'getBalance'});
print(key1 == key2); // true
// Both: {"method":"getBalance","params":["abc"]}
}
API reference #
Functions #
fastStableStringify(Object? value)returns a deterministic JSON string with sorted keys, ornullif the value cannot be serialized.
Mixins #
ToJsonableaddsObject? toJson()to a class. When an object with this mixin is passed tofastStableStringify, itstoJson()return value is recursively stringified.
Example #
Use example/main.dart as a runnable starting point for solana_kit_fast_stable_stringify.
- Import path:
package:solana_kit_fast_stable_stringify/solana_kit_fast_stable_stringify.dart - This section is centrally maintained with
mdtto keep package guidance aligned. - After updating shared docs templates, run
docs:updatefrom the repo root.
Maintenance #
- Validate docs in CI and locally with
docs:check. - Keep examples focused on one workflow and reference package README sections for deeper API details.