diff --git a/package.json b/package.json index 662f1be..7b0fe3a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@initia/builder.js", - "version": "0.2.8", + "version": "0.2.9", "description": "The JavaScript Move Builder for Initia", "license": "MIT", "author": "Initia Foundation", diff --git a/src/builder.ts b/src/builder.ts index cd40759..495ad9a 100644 --- a/src/builder.ts +++ b/src/builder.ts @@ -11,6 +11,9 @@ import { compilerPayloadBcsType, testOptBcsType, TestOptions, + DecodedModuleBytes, + DecodedScriptBytes, + ModuleInfo, } from './types' type ModuleName = string @@ -283,9 +286,9 @@ export class MoveBuilder { * @param moduleBytes - Move module bytes. * @returns If success, return buffer, else throw an error. */ - public static async decode_module_bytes( + public static async decodeModuleBytes( moduleBytes: Buffer - ): Promise { + ): Promise { const errMsg = createRawErrMsg() const moduleBytesView = ref.alloc(ByteSliceViewType) @@ -297,11 +300,15 @@ export class MoveBuilder { ) rawModuleBytesView.len = moduleBytes.length - return handleResponse( + const response = await handleResponse( libmovevm.decode_module_bytes.async, errMsg, rawModuleBytesView ) + if (response === null) { + throw new Error('Failed to decode module bytes') + } + return JSON.parse(response.toString()) as DecodedModuleBytes } /** @@ -309,9 +316,9 @@ export class MoveBuilder { * @param scriptBytes - Move script bytes. * @returns If success, return buffer, else throw an error. */ - public static async decode_script_bytes( + public static async decodeScriptBytes( scriptBytes: Buffer - ): Promise { + ): Promise { const errMsg = createRawErrMsg() const scriptBytesView = ref.alloc(ByteSliceViewType) @@ -323,11 +330,15 @@ export class MoveBuilder { ) rawScriptBytesView.len = scriptBytes.length - return handleResponse( + const response = await handleResponse( libmovevm.decode_script_bytes.async, errMsg, rawScriptBytesView ) + if (response === null) { + throw new Error('Failed to decode module bytes') + } + return JSON.parse(response.toString()) as DecodedScriptBytes } /** @@ -335,9 +346,9 @@ export class MoveBuilder { * @param compiledBinary - Move compiled bytes. * @returns If success, return buffer, else throw an error. */ - public static async read_module_info( + public static async readModuleInfo( compiledBinary: Buffer - ): Promise { + ): Promise { const errMsg = createRawErrMsg() const compiledView = ref.alloc(ByteSliceViewType) @@ -349,10 +360,23 @@ export class MoveBuilder { ) rawCompiledView.len = compiledBinary.length - return handleResponse( + const response = await handleResponse( libmovevm.read_module_info.async, errMsg, rawCompiledView ) + if (response === null) { + throw new Error('Failed to decode module bytes') + } + + const res = JSON.parse(response.toString()) as { + address: number[] + name: string + } + return { + address: + '0x' + Buffer.from(res.address).toString('hex').replace(/^0+/, ''), + name: res.name, + } } } diff --git a/src/index.ts b/src/index.ts index 884dfd6..54bfb97 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,9 @@ -export { FFIResult, BuildOptions, TestOptions } from './types' +export { + FFIResult, + BuildOptions, + TestOptions, + ModuleInfo, + DecodedModuleBytes, + DecodedScriptBytes, +} from './types' export * from './builder' diff --git a/src/types/index.ts b/src/types/index.ts index 2b55c32..6a2b697 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -3,6 +3,7 @@ import ref from '@eleccookie/ref-napi' export * from './options' export * from './bcs' export * from './ffi' +export * from './type' const StructType = struct(ref) diff --git a/src/types/type.ts b/src/types/type.ts new file mode 100644 index 0000000..75d073e --- /dev/null +++ b/src/types/type.ts @@ -0,0 +1,39 @@ +export interface DecodedModuleBytes { + address: string + name: string + friends: string[] + exposed_functions: { + name: string + visibility: string + is_entry: boolean + is_view: boolean + generic_type_params: string[] + params: string[] + return: string[] + }[] + structs: { + name: string + is_native: boolean + abilities: string[] + generic_type_params: string[] + fields: { + name: string + type: string + }[] + }[] +} + +export interface DecodedScriptBytes { + name: string + visibility: string + is_entry: boolean + is_view: boolean + generic_type_params: string[] + params: string[] + return: string[] +} + +export interface ModuleInfo { + address: string + name: string +} diff --git a/test/build.spec.ts b/test/build.spec.ts index 03ca5ba..ef75f56 100644 --- a/test/build.spec.ts +++ b/test/build.spec.ts @@ -15,10 +15,7 @@ describe('build move package', () => { bytecodeVersion: 7, compilerVersion: '2', languageVersion: '1', - additionalNamedAddresses: [ - ['test', '0x4'], - ['test2', '0x4c4e8f7def3c24453ae7eee7d9aee9b7556a26a0'], - ], + additionalNamedAddresses: [['test', '0x4']], }) const dummyModulePath = path.join( contractDir, @@ -36,64 +33,85 @@ describe('build move package', () => { it('decodes module bytes correctly', async () => { const dummy = await builder.get('dummy') - expect(await MoveBuilder.decode_module_bytes(dummy)).toEqual( - JSON.stringify({ - address: '0x4', - name: 'dummy', - friends: [], - exposed_functions: [ - { - name: 'return_0', - visibility: 'public', - is_entry: false, - is_view: false, - generic_type_params: [], - params: [], - return: ['u32'], - }, - { - name: 'return_10', - visibility: 'public', - is_entry: false, - is_view: false, - generic_type_params: [], - params: [], - return: ['u32'], - }, - ], - structs: [], - }) - ) + expect(await MoveBuilder.decodeModuleBytes(dummy)).toEqual({ + address: '0x4', + name: 'dummy', + friends: ['0x4::hihi'], + exposed_functions: [ + { + name: 'return_0', + visibility: 'public', + is_entry: false, + is_view: false, + generic_type_params: [], + params: [], + return: ['u32'], + }, + { + name: 'return_10', + visibility: 'public', + is_entry: false, + is_view: false, + generic_type_params: [], + params: [], + return: ['u32'], + }, + { + name: 'return_10_by_friend', + visibility: 'friend', + is_entry: false, + is_view: false, + generic_type_params: [], + params: [], + return: ['u32'], + }, + ], + structs: [], + }) const hihi = await builder.get('hihi') - - expect(await MoveBuilder.decode_module_bytes(hihi)).toEqual( - JSON.stringify({ - address: '0x4c4e8f7def3c24453ae7eee7d9aee9b7556a26a0', - name: 'hihi', - friends: [], - exposed_functions: [ - { - name: 'return_0', - visibility: 'public', - is_entry: false, - is_view: false, - generic_type_params: [], - params: [], - return: ['u32'], - }, - { - name: 'return_10', - visibility: 'public', - is_entry: false, - is_view: false, - generic_type_params: [], - params: [], - return: ['u32'], - }, - ], - structs: [], - }) - ) + expect(await MoveBuilder.decodeModuleBytes(hihi)).toEqual({ + address: '0x4', + name: 'hihi', + friends: [], + exposed_functions: [ + { + name: 'return_0', + visibility: 'public', + is_entry: false, + is_view: false, + generic_type_params: [], + params: [], + return: ['u32'], + }, + { + name: 'return_10', + visibility: 'public', + is_entry: false, + is_view: false, + generic_type_params: [], + params: [], + return: ['u32'], + }, + { + name: 'call_friend', + visibility: 'public', + is_entry: false, + is_view: false, + generic_type_params: [], + params: [], + return: ['u32'], + }, + ], + structs: [ + { + name: 'HiHi', + is_native: false, + abilities: ['store'], + generic_type_params: [], + fields: [{ name: 'count', type: 'u64' }], + }, + ], + }) }) it('reads module info correctly', async () => { @@ -101,12 +119,14 @@ describe('build move package', () => { const dummy = modules['dummy'] const hihi = modules['hihi'] - expect(await MoveBuilder.read_module_info(dummy)).toEqual( - '{"address":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4],"name":"dummy"}' - ) - expect(await MoveBuilder.read_module_info(hihi)).toEqual( - '{"address":[0,0,0,0,0,0,0,0,0,0,0,0,76,78,143,125,239,60,36,69,58,231,238,231,217,174,233,183,85,106,38,160],"name":"hihi"}' - ) + expect(await MoveBuilder.readModuleInfo(dummy)).toEqual({ + address: '0x4', + name: 'dummy', + }) + expect(await MoveBuilder.readModuleInfo(hihi)).toEqual({ + address: '0x4', + name: 'hihi', + }) }) it('reads source maps correctly', async () => { @@ -123,16 +143,12 @@ describe('build move package', () => { it('reads module info correctly', async () => { const binary = await builder.get('dummy') - const moduleInfo = await MoveBuilder.read_module_info(binary) - const expectedModuleInfo = JSON.stringify({ - address: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4, - ], + const moduleInfo = await MoveBuilder.readModuleInfo(binary) + + expect(moduleInfo).toEqual({ + address: '0x4', name: 'dummy', }) - - expect(moduleInfo).toEqual(expectedModuleInfo) }) it('cleans the package correctly', async () => { diff --git a/test/contract/dummy/Move.toml b/test/contract/dummy/Move.toml index ea62bd4..3ae20b3 100644 --- a/test/contract/dummy/Move.toml +++ b/test/contract/dummy/Move.toml @@ -7,5 +7,4 @@ version = "1.0.0" [addresses] std = "0x1" initia_std = "0x1" -test="_" -test2 = "_" \ No newline at end of file +test="_" \ No newline at end of file diff --git a/test/contract/dummy/sources/dummy.move b/test/contract/dummy/sources/dummy.move index e8afa56..02f7f55 100644 --- a/test/contract/dummy/sources/dummy.move +++ b/test/contract/dummy/sources/dummy.move @@ -1,4 +1,6 @@ module test::dummy { + friend test::hihi; + public fun return_0(): u32 { 0 } @@ -7,6 +9,10 @@ module test::dummy { 10 } + public(friend) fun return_10_by_friend(): u32 { + 10 + } + #[test] fun test_return_0() { assert!(return_0() == 0,1); diff --git a/test/contract/dummy/sources/hihi.move b/test/contract/dummy/sources/hihi.move index 2d10d24..d1dfdcc 100644 --- a/test/contract/dummy/sources/hihi.move +++ b/test/contract/dummy/sources/hihi.move @@ -1,4 +1,10 @@ -module test2::hihi { +module test::hihi { + use test::dummy; + + struct HiHi has store { + count: u64 + } + public fun return_0(): u32 { 0 } @@ -6,4 +12,8 @@ module test2::hihi { public fun return_10(): u32 { 10 } + + public fun call_friend(): u32 { + dummy::return_10_by_friend() + } } \ No newline at end of file diff --git a/test/script.spec.ts b/test/script.spec.ts index c6bcc84..ef560cc 100644 --- a/test/script.spec.ts +++ b/test/script.spec.ts @@ -16,9 +16,15 @@ describe('build script and decode', () => { 'contract/script/build/script/bytecode_scripts/even_0.mv' ) const binary = await readFile(bytePath) - const decodedScript = await MoveBuilder.decode_script_bytes(binary) - expect(decodedScript).toEqual( - '{"name":"main","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["u64"],"return":[]}' - ) + const decodedScript = await MoveBuilder.decodeScriptBytes(binary) + expect(decodedScript).toEqual({ + generic_type_params: [], + is_entry: true, + is_view: false, + name: 'main', + params: ['u64'], + return: [], + visibility: 'public', + }) }) })