@@ -2,59 +2,64 @@ import { ContractAction } from "./types.js";
22import { encryptSecret , deriveAddress } from "./crypto.js" ;
33import { ExtendedTransactionBuilder } from "./transaction.js" ;
44import Archethic from "./index.js" ;
5- import { hexToUint8Array , isHex } from "./utils.js" ;
5+ import { isHex } from "./utils.js" ;
66
7- export async function extractActionsFromContract ( code : string ) : Promise < ContractAction [ ] > {
8- let actions = [ ] ;
7+ type CodeWithManifest = {
8+ bytecode : string ;
9+ manifest : WasmManifest
10+ }
911
10- if ( isHex ( code ) ) {
11- const wasmModule = await WebAssembly . instantiate ( hexToUint8Array ( code ) , {
12- "archethic/env" : {
13- log : ( offset : bigint , length : bigint ) => { } ,
14- store_u8 : ( offset : bigint , data : bigint ) => { } ,
15- load_u8 : ( offset : bigint ) : number => 0 ,
16- input_size : ( ) : bigint => 0n ,
17- alloc : ( length : bigint ) : bigint => 0n ,
18- set_output : ( offset : bigint , length : bigint ) => { } ,
19- set_error : ( offset : bigint , length : bigint ) => { }
20- } ,
21- // FIXME with JSON RPC like request
22- "archethic/IO" : {
23- get_balance : ( offset : bigint , length : bigint ) => 0
24- }
25- } ) ;
12+ type WasmManifest = {
13+ abi : WasmABI
14+ }
2615
27- const reservedFunctions = [ "spec" , "init" , "onUpgrade" ] ;
28- for ( let key in wasmModule . instance . exports ) {
29- if ( wasmModule . instance . exports [ key ] instanceof Function ) {
30- if ( ! reservedFunctions . includes ( key ) ) {
31- actions . push ( { name : key , parameters : [ "WASM JSON Input" ] } ) ;
32- }
33- }
34- }
16+ type WasmABI = {
17+ functions : Record < string , WASMFunctionABI >
18+ }
3519
36- actions . push ( { name : "upgrade" , parameters : [ 'WASM JSON Input ( {"code": "wasm code as hex"})' ] } ) ;
20+ type WASMFunctionABI = {
21+ type : string ;
22+ name : string ;
23+ input : Record < string , any >
24+ }
3725
38- return actions ;
26+ export async function extractActionsFromContract ( code : string ) : Promise < ContractAction [ ] > {
27+ try {
28+ const codeWithManifest : CodeWithManifest = JSON . parse ( code )
29+ const manifest = codeWithManifest . manifest
30+ let actions : ContractAction [ ] = [ ]
31+ for ( let name of Object . keys ( manifest . abi . functions ) ) {
32+ const functionABI = manifest . abi . functions [ name ]
33+ if ( functionABI . type == "action" ) {
34+ actions . push ( {
35+ name : name ,
36+ parameters : Object . keys ( functionABI . input )
37+ } )
38+ }
39+ }
40+ return actions
3941 }
42+ catch ( e ) {
43+ let actions = [ ] ;
4044
41- const regex = / a c t i o n s \s + t r i g g e r e d _ b y : \s + t r a n s a c t i o n , \s + o n : \s + ( [ \w \s . , ( ) ] + ?) \s + d o / g;
45+ const regex = / a c t i o n s \s + t r i g g e r e d _ b y : \s + t r a n s a c t i o n , \s + o n : \s + ( [ \w \s . , ( ) ] + ?) \s + d o / g;
4246
43- for ( const match of code . matchAll ( regex ) ) {
44- const fullAction = match [ 1 ] ;
47+ for ( const match of code . matchAll ( regex ) ) {
48+ const fullAction = match [ 1 ] ;
4549
46- const regexActionName = / ( \w + ) \( ( .* ?) \) / g;
47- for ( const actionMatch of fullAction . matchAll ( regexActionName ) ) {
48- const name = actionMatch [ 1 ] ;
49- const parameters = actionMatch [ 2 ] != "" ? actionMatch [ 2 ] . split ( "," ) : [ ] ;
50- actions . push ( {
51- name : name ,
52- parameters : parameters
53- } ) ;
50+ const regexActionName = / ( \w + ) \( ( .* ?) \) / g;
51+ for ( const actionMatch of fullAction . matchAll ( regexActionName ) ) {
52+ const name = actionMatch [ 1 ] ;
53+ const parameters = actionMatch [ 2 ] != "" ? actionMatch [ 2 ] . split ( "," ) : [ ] ;
54+ actions . push ( {
55+ name : name ,
56+ parameters : parameters
57+ } ) ;
58+ }
5459 }
55- }
5660
57- return actions ;
61+ return actions ;
62+ }
5863}
5964
6065export function parseTypedArgument ( input : any ) : any {
0 commit comments