Skip to content

Commit 8c458c6

Browse files
fix(encoder): hack fix for vector<vector<address>> on encoder
1 parent 24601ac commit 8c458c6

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

bindings/bind/bcs_decoder_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ func TestDeserializer(t *testing.T) {
333333
}
334334

335335
func TestDeserializer_ShouldFail(t *testing.T) {
336+
// TODO: this test will fail when https://github.com/block-vision/sui-go-sdk/pull/78
337+
// is released and will have to be removed
338+
336339
// mystenbcs encoder has an issue where fixed-size byte arrays ([n]byte) are treated as regular slices.
337340
// so encoding a u128 via their encoder will result in failure to decode it back.
338341
// We're using this behavior to test our DeserializeBCS error handling.

bindings/bind/type_converter.go

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -585,20 +585,62 @@ func convertVectorToBCS(innerType string, value any) (any, error) {
585585
type SuiAddressBytes [32]byte
586586

587587
func bcsEncode(value any) ([]byte, error) {
588-
if addrs, ok := value.([][32]byte); ok {
589-
suiAddrs := make([]SuiAddressBytes, len(addrs))
590-
for i, addr := range addrs {
591-
suiAddrs[i] = SuiAddressBytes(addr)
592-
}
593-
value = suiAddrs
588+
// Normalize value before encoding
589+
normalized, err := normalizeValue(value)
590+
if err != nil {
591+
return nil, err
594592
}
595593

596594
bcsEncodedMsg := bytes.Buffer{}
597595
bcsEncoder := mystenbcs.NewEncoder(&bcsEncodedMsg)
598-
err := bcsEncoder.Encode(value)
596+
err = bcsEncoder.Encode(normalized)
599597
if err != nil {
600598
return nil, err
601599
}
602600

603601
return bcsEncodedMsg.Bytes(), nil
604602
}
603+
604+
// normalizeValue converts special Go types into the correct BCS-friendly form.
605+
// TODO: This is a temporary solution until sui-go-sdk addresses [n]bytes bug
606+
// https://github.com/block-vision/sui-go-sdk/issues/75 won't be necessary after release
607+
// fixes vector<address> and vector<vector<address>> encoding.
608+
func normalizeValue(value any) (any, error) {
609+
switch v := value.(type) {
610+
case [][32]byte:
611+
// Single-level vector<address>
612+
return convertToSliceSuiAddressBytes(v), nil
613+
case []interface{}:
614+
// Possible nested address vectors: [][][32]byte (wrapped as []interface{}) (vector<vector<address>>)
615+
if len(v) == 0 {
616+
return v, nil
617+
}
618+
// Check if the first element matches the pattern
619+
if _, ok := v[0].([][32]byte); !ok {
620+
return value, nil
621+
}
622+
result := make([][]SuiAddressBytes, len(v))
623+
for i, item := range v {
624+
// Make sure all the items are of the expected type
625+
addrs, ok := item.([][32]byte)
626+
if !ok {
627+
return nil, fmt.Errorf("expected [][32]byte at index %d, got %T", i, item)
628+
}
629+
result[i] = convertToSliceSuiAddressBytes(addrs)
630+
}
631+
632+
return result, nil
633+
}
634+
635+
return value, nil
636+
}
637+
638+
// convertToSuiAddressBytes converts a slice of [32]byte into []SuiAddressBytes.
639+
func convertToSliceSuiAddressBytes(addresses [][32]byte) []SuiAddressBytes {
640+
out := make([]SuiAddressBytes, len(addresses))
641+
for i, addr := range addresses {
642+
out[i] = SuiAddressBytes(addr)
643+
}
644+
645+
return out
646+
}

0 commit comments

Comments
 (0)