iotaledger / iotaledger/ts-packages

Fix layoutToBcs conversion function

Open
#40 2 comments 0 reactions 0 assignees View on GitHub
ts-sdk
Dominant language
TypeScript
Stars
3
Forks
3
Avg merge
1d 2h
Merged PRs (30d)
12

Description

## Bug description

layoutToBcs() is not working for some types, for example with a String I think
It's a super useful function and should be fixed
https://github.com/iotaledger/iota/blob/e61a16a304ad1580766455ae0da7592ead081329/sdk/graphql-transport/src/mappers/bcs.ts#L12

here is a modified version that seems to work, but should be checked, best to add some tests
```TS
export function toShortTypeString(type?: T): T {
return type?.replace(/0x0{31,}(\d)/g, '0x$1').replace(/,\b/g, ', ') as T;
}

export function layoutToBcs(layout: MoveTypeLayout): BcsType {
switch (layout) {
case 'address':
return bcs.Address;
case 'bool':
return bcs.Bool;
case 'u8':
return bcs.U8;
case 'u16':
return bcs.U16;
case 'u32':
return bcs.U32;
case 'u64':
return bcs.U64;
case 'u128':
return bcs.U128;
case 'u256':
return bcs.U256;
}

if ('vector' in layout) {
const innerType = layoutToBcs(layout.vector);
const vectorType = bcs.vector(innerType);

// Special handling for vector which is often used for string bytes
if (layout.vector === 'u8') {
return vectorType.transform({
input: (value: any) => {
// If it's a string, convert to bytes array
if (typeof value === 'string') {
return Array.from(new TextEncoder().encode(value));
}
return value;
},
output: (value: any) => {
// Convert bytes array back to string
if (Array.isArray(value)) {
return new TextDecoder().decode(new Uint8Array(value));
}
return value;
},
});
}

return vectorType;
}

if ('struct' in layout) {
const fields: Record> = {};

for (const { name, layout: field } of layout.struct.fields) {
fields[name] = layoutToBcs(field);
}

let struct = bcs.struct(layout.struct.type, fields);

const structName = toShortTypeString(layout.struct.type);

if (structName === '0x2::object::ID') {
struct = struct.transform({
input: (id: any) => (typeof id === 'string' ? { bytes: id } : id) as never,
output: (id) => id.id,
});
}

// Handle String type - convert JavaScript string to Move String format
if (structName === '0x1::string::String') {
struct = struct.transform({
input: (str: any) => (typeof str === 'string' ? { bytes: str } : str) as never,
output: (obj) => obj.bytes,
});
}

return struct;
}

throw new Error(`Unknown layout: ${JSON.stringify(layout)}`);
}
```
Related, one could add to make it easier to work with it also in the other way arround
```TS
export interface BcsDecodeResult {
value?: any;
error?: string;
}

/**
* Decode BCS data using a Move layout
*/
export function decodeBcs(bcsBase64: string, layout: MoveTypeLayout): BcsDecodeResult {
try {
const schema = layoutToBcs(layout);

// Decode the base64 BCS data
const bcsBytes = new Uint8Array(
atob(bcsBase64)
.split('')
.map((c) => c.charCodeAt(0)),
);

const value = schema.parse(bcsBytes);
return { value };
} catch (e: any) {
return { error: e.message || String(e) };
}
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.