(define-constant ERR_INVALID_INPUT (err u400))
(define-constant ERR_INVALID_RLP (err u401))
(define-constant ERR_INVALID_LENGTH (err u402))
(define-constant MAX_SIZE 512)
(define-read-only (get-item (input (list 2 (buff 4096))))
(unwrap-panic (element-at? input u0))
)
(define-read-only (get-rlp (input (list 2 (buff 4096))))
(unwrap-panic (element-at? input u1))
)
(define-read-only (rlp-decode-string (rlp (list 100 (buff 2048))) (index uint))
(let (
(data (unwrap-panic (element-at? rlp index))))
(decode-string data)
)
)
(define-read-only (decode-string (input (buff 2048)))
(let (
(length (unwrap-panic (to-consensus-buff? (len input))))
(sliced (unwrap-panic (slice? length u13 (len length))))
(data (concat sliced input))
(res (concat 0x0d data))
)
(from-consensus-buff? (string-ascii 4096) res)
)
)
(define-read-only (rlp-decode-uint (rlp (list 100 (buff 4096))) (index uint))
(let (
(data (unwrap-panic (element-at? rlp index))))
(decode-uint data)
)
)
(define-read-only (decode-uint (input (buff 4096)))
(buff-to-uint-be (unwrap-panic (as-max-len? input u16)))
)
(define-read-only (rlp-decode-buff (rlp (list 100 (buff 4096))) (index uint))
(let (
(data (unwrap-panic (element-at? rlp index)))
(decoded (decode-item data))
)
(unwrap-panic (element-at? decoded u1))
)
)
(define-private (get-long-item (id uint) (index uint) (input (buff 4096)))
(let (
(length-bytes-count (- index id))
(length-bytes (unwrap-panic (slice? input u1 (+ u1 length-bytes-count))))
(item-length (buff-to-uint-be (unwrap-panic (as-max-len? length-bytes u16))))
)
(list (default-to 0x (slice? input (+ u1 length-bytes-count) (+ u1 length-bytes-count item-length)))
(default-to 0x (slice? input (+ u1 length-bytes-count item-length) (len input)))
)
)
)
(define-private (get-short-item (id uint) (index uint) (input (buff 4096)))
(let ((item-length (- index id)))
(list
(default-to 0x (slice? input u1 (+ u1 item-length)))
(default-to 0x (slice? input (+ u1 item-length) (len input)))
)
)
)
(define-read-only (decode-item (input (buff 4096)))
(let (
(first-byte (unwrap-panic (element-at? input u0)))
(length (buff-to-uint-be first-byte))
)
(if (< length u128)
;; Check if this is a string (first byte between 0x80 and 0xb7)
(if (and (>= length u128) (< length u184))
;; For strings, keep the length prefix
(list
input
(default-to 0x (slice? input u1 (len input)))
)
;; For other types, strip the length prefix
(list
(default-to 0x (slice? input u0 u1))
(default-to 0x (slice? input u1 (len input)))
))
(if (< length u184)
(get-short-item u128 length input)
(if (< length u192)
(get-long-item u183 length input)
(if (< length u248)
(get-short-item u192 length input)
(get-long-item u247 length input)
))))
)
)
(define-read-only (rlp-decode-list (rlp (list 100 (buff 4096))) (index uint))
(let (
(data (unwrap-panic (element-at? rlp index))))
(to-list data)
)
)
(define-read-only (rlp-to-list (input (buff 4096)))
(let (
(item (decode-item input))
(lst (get-item item))
)
(to-list lst)
)
)
(define-private (try-decode (input (buff 4096)))
(if (is-eq input 0x)
none
(let ((pair (decode-item input)))
(some { item: (get-item pair), rest: (get-rlp pair) })
)
)
)
(define-read-only (to-list (input (buff 4096)))
(let (
(d1 (unwrap! (try-decode input) (list)))
(i1 (get item d1))
(d2 (unwrap! (try-decode (get rest d1)) (list i1)))
(i2 (get item d2))
(d3 (unwrap! (try-decode (get rest d2)) (list i1 i2)))
(i3 (get item d3))
(d4 (unwrap! (try-decode (get rest d3)) (list i1 i2 i3)))
(i4 (get item d4))
(d5 (unwrap! (try-decode (get rest d4)) (list i1 i2 i3 i4)))
(i5 (get item d5))
(d6 (unwrap! (try-decode (get rest d5)) (list i1 i2 i3 i4 i5)))
(i6 (get item d6))
(d7 (unwrap! (try-decode (get rest d6)) (list i1 i2 i3 i4 i5 i6)))
(i7 (get item d7))
(d8 (unwrap! (try-decode (get rest d7)) (list i1 i2 i3 i4 i5 i6 i7)))
(i8 (get item d8))
(d9 (unwrap! (try-decode (get rest d8)) (list i1 i2 i3 i4 i5 i6 i7 i8)))
(i9 (get item d9))
(d10 (unwrap! (try-decode (get rest d9)) (list i1 i2 i3 i4 i5 i6 i7 i8 i9)))
(i10 (get item d10))
)
(list i1 i2 i3 i4 i5 i6 i7 i8 i9 i10)
)
)