write static method
Writes an OZSmartAccountAuthPayload to its XdrSCVal representation.
Builds the outer map with exactly two entries in alphabetical
insertion order (context_rule_ids, then signers), matching the
Soroban Rust #[contracttype] derive ordering for the contract's
AuthPayload struct. Inner signer entries are sorted by the
lowercase-hex of their XDR-encoded keys so the encoding is
deterministic and the host-side dynamic-Map ordering check is
satisfied.
Throws SmartAccountTransactionSigningFailed when XDR encoding of a signer key fails.
Implementation
static XdrSCVal write(OZSmartAccountAuthPayload payload) {
// Build signer map entries, wrapping each raw signature byte array in
// an XdrSCVal.forBytes value.
final signerEntries = <XdrSCMapEntry>[];
for (final entry in payload.signers.entries) {
signerEntries.add(
XdrSCMapEntry(
entry.key.toScVal(),
XdrSCVal.forBytes(entry.value),
),
);
}
// Sort signer entries by lowercase-hex of their XDR-encoded key bytes.
// Lowercase-hex(byte sequence) is monotone in the underlying byte
// sequence, so the resulting order is identical to a raw byte
// lexicographic sort.
signerEntries.sort((a, b) {
try {
final keyA = _xdrHexOfScVal(a.key);
final keyB = _xdrHexOfScVal(b.key);
return keyA.compareTo(keyB);
} catch (e) {
throw SmartAccountTransactionException.signingFailed(
'Failed to XDR-encode signer key for sorting: $e',
cause: e,
);
}
});
final signersMapScVal = XdrSCVal.forMap(signerEntries);
final ruleIdsVec = payload.contextRuleIds
.map((id) => XdrSCVal.forU32(id))
.toList(growable: false);
final contextRuleIdsScVal = XdrSCVal.forVec(ruleIdsVec);
// Outer struct map keys insert in alphabetical order to match the
// Soroban Rust `#[contracttype]` derive convention. Inner dynamic-map
// keys are sorted above by XDR-byte order.
return XdrSCVal.forMap([
XdrSCMapEntry(
XdrSCVal.forSymbol('context_rule_ids'),
contextRuleIdsScVal,
),
XdrSCMapEntry(
XdrSCVal.forSymbol('signers'),
signersMapScVal,
),
]);
}