(define-private (check-length (data (buff 8192)))
(unwrap-panic (as-max-len? data u4096))
)
(define-private (encode-buff-arr (objects (list 100 (buff 4096))))
(fold concat-buff objects 0x)
)
(define-private (concat-buff (a (buff 4096)) (b (buff 4096)))
(check-length (concat b a))
)
(define-private (rm-lead (num (buff 1)) (buffer (buff 4096)))
(if (is-eq 0x00 buffer)
num
(check-length (concat buffer num))
)
)
(define-read-only (encode-string (message (string-ascii 4096)))
(let (
(encoded (unwrap-panic (to-consensus-buff? message)))
)
(if (is-eq (len encoded) u5)
;; Special case for empty string
0x80
(let (
;; Remove type prefix and length bytes
(encoded-length (- (len encoded) u5))
(string-content (unwrap-panic (slice? encoded u5 (len encoded))))
)
(if (> encoded-length u55)
;; Long string case (>55 bytes)
(let (
(length-bytes (unwrap-panic (to-consensus-buff? encoded-length)))
(length-byte (unwrap-panic (element-at? length-bytes u16)))
(length-hex (unwrap-panic (slice? length-bytes u1 (len length-bytes))))
(prefix (if (> encoded-length u255)
0xb9 ;; Two bytes needed for length
0xb8 ;; One byte needed for length
))
)
(check-length (concat
(if (> encoded-length u255)
(concat prefix length-hex) ;; Use full length for large strings
(concat prefix length-byte) ;; Use single byte for smaller strings
)
string-content)))
;; Short string case (<=55 bytes)
(let (
(id (unwrap-panic (to-consensus-buff? (+ u128 encoded-length))))
(prefix (unwrap-panic (element-at? id u16)))
(res (concat prefix string-content))
)
(check-length res))
)
)
)
)
)
(define-private (encode-uint-raw (data uint))
(if (is-eq data u0)
0x80
(let (
(encoded (unwrap-panic (to-consensus-buff? data)))
(sliced (unwrap-panic (slice? encoded u1 (len encoded))))
(stripped (fold rm-lead sliced 0x00))
)
(if (>= data (pow u256 u3))
(check-length (concat 0x00 stripped))
stripped)
)
)
)
(define-read-only (encode-uint (data uint))
(if (is-eq data u0)
0x80
(let ((encoded (unwrap-panic (to-consensus-buff? data)))
(sliced (unwrap-panic (slice? encoded u1 (len encoded))))
(stripped (fold rm-lead sliced 0x00)))
(print {
event: "prefix",
prefix: sliced,
data: stripped
})
(encode-buff stripped)
)
)
)
(define-read-only (encode-arr (objects (list 100 (buff 4096))))
(let (
(encoded-data (encode-buff-arr objects))
(total-length (len encoded-data))
(prefix (
if (> total-length u55)
(check-length (concat (encode-uint-raw (+ u247 (len (encode-uint-raw total-length)))) (encode-uint-raw total-length)))
(check-length (encode-uint-raw (+ u192 total-length)))))
)
(check-length (concat prefix encoded-data))
)
)
(define-read-only (encode-buff (data (buff 4096)))
(if (not (and (is-eq u1 (len data)) (< (buff-to-uint-be (unwrap-panic (as-max-len? data u1))) u128)))
(encode-buff-long data)
data
)
)
(define-private (encode-buff-long (data (buff 4096)))
(let
(
(data_len (len data))
(prefix (
if (> data_len u55)
(check-length (concat (encode-uint-raw (+ u183 (len (encode-uint-raw data_len)))) (encode-uint-raw data_len)))
(check-length (encode-uint-raw (+ u128 data_len)))))
)
(print {
event: "prefix",
prefix: prefix,
data: data
})
(check-length (concat prefix data))
)
)