11@inline
2- function toBytes < T > ( val : T ) : Uint8Array {
2+ export function toBytes < T > ( val : T ) : Uint8Array {
33 if ( isInteger < T > ( ) ) {
44 const str = val . toString ( ) ;
55 return Uint8Array . wrap ( String . UTF8 . encode ( str ) ) ;
@@ -19,6 +19,10 @@ function toBytes<T>(val: T): Uint8Array {
1919 }
2020}
2121
22+ export function b < T > ( val : T ) : Uint8Array {
23+ return toBytes ( val )
24+ }
25+
2226class KeyValuePair {
2327 constructor (
2428 public key : Uint8Array | null ,
@@ -121,7 +125,7 @@ function from_b58_1(S: string, A: string = MAP): Uint8Array | null {
121125 return result ;
122126}
123127
124- function memory_read_bytes ( ptr : i32 ) : Uint8Array {
128+ export function memory_read_bytes ( ptr : i32 ) : Uint8Array {
125129 let length = load < i32 > ( ptr ) ;
126130 let result = new Uint8Array ( length ) ;
127131 memory . copy ( changetype < usize > ( result . buffer ) , ptr + 4 , length ) ;
@@ -153,10 +157,6 @@ export function base58_decode(input: string): Uint8Array {
153157 return out ;
154158}
155159
156- export function b ( str : string ) : Uint8Array {
157- return Uint8Array . wrap ( String . UTF8 . encode ( str , false ) ) ;
158- }
159-
160160export function bToI64 ( data : Uint8Array | null , defaultVal : i64 = 0 ) : i64 {
161161 if ( ! data ) return defaultVal ;
162162 const str = String . UTF8 . decodeUnsafe ( data . dataStart , data . byteLength ) ;
@@ -340,53 +340,56 @@ export function kv_get_next<K, V>(prefix: K, key: V): KeyValuePair {
340340 return new KeyValuePair ( prev_key , value ) ;
341341}
342342
343- @external ( "env" , "import_call_0" )
344- declare function import_call_0 ( module_ptr : i32 , module_len : i32 , function_ptr : i32 , function_len : i32 ) : i32 ;
345- @external ( "env" , "import_call_1" )
346- declare function import_call_1 ( module_ptr : i32 , module_len : i32 , function_ptr : i32 , function_len : i32 ,
347- args_1_ptr : i32 , args_1_len : i32 ) : i32 ;
348- @external ( "env" , "import_call_2" )
349- declare function import_call_2 ( module_ptr : i32 , module_len : i32 , function_ptr : i32 , function_len : i32 ,
350- args_1_ptr : i32 , args_1_len : i32 , args_2_ptr : i32 , args_2_len : i32 ) : i32 ;
351- @external ( "env" , "import_call_3" )
352- declare function import_call_3 ( module_ptr : i32 , module_len : i32 , function_ptr : i32 , function_len : i32 ,
353- args_1_ptr : i32 , args_1_len : i32 , args_2_ptr : i32 , args_2_len : i32 , args_3_ptr : i32 , args_3_len : i32 ) : i32 ;
354- @external ( "env" , "import_call_4" )
355- declare function import_call_4 ( module_ptr : i32 , module_len : i32 , function_ptr : i32 , function_len : i32 ,
356- args_1_ptr : i32 , args_1_len : i32 , args_2_ptr : i32 , args_2_len : i32 , args_3_ptr : i32 , args_3_len : i32 , args_4_ptr : i32 , args_4_len : i32 ) : i32 ;
357-
358- export function call ( contract : Uint8Array , func : string , args : Uint8Array [ ] ) : string {
359- let funcBytes = String . UTF8 . encode ( func , false ) ;
360- let funcPtr = changetype < i32 > ( funcBytes ) ;
361-
362- let errorPtr = 30_000
363- switch ( args . length ) {
364- case 0 :
365- errorPtr = import_call_0 ( changetype < i32 > ( contract . dataStart ) , contract . byteLength , funcPtr , funcBytes . byteLength ) ;
366- break ;
367- case 1 :
368- errorPtr = import_call_1 ( changetype < i32 > ( contract . dataStart ) , contract . byteLength , funcPtr , funcBytes . byteLength ,
369- changetype < i32 > ( args [ 0 ] . dataStart ) , args [ 0 ] . byteLength ) ;
370- break ;
371- case 2 :
372- errorPtr = import_call_2 ( changetype < i32 > ( contract . dataStart ) , contract . byteLength , funcPtr , funcBytes . byteLength ,
373- changetype < i32 > ( args [ 0 ] . dataStart ) , args [ 0 ] . byteLength , changetype < i32 > ( args [ 1 ] . dataStart ) , args [ 1 ] . byteLength ) ;
374- break ;
375- case 3 :
376- errorPtr = import_call_3 ( changetype < i32 > ( contract . dataStart ) , contract . byteLength , funcPtr , funcBytes . byteLength ,
377- changetype < i32 > ( args [ 0 ] . dataStart ) , args [ 0 ] . byteLength , changetype < i32 > ( args [ 1 ] . dataStart ) , args [ 1 ] . byteLength ,
378- changetype < i32 > ( args [ 2 ] . dataStart ) , args [ 2 ] . byteLength ) ;
379- break ;
380- case 4 :
381- errorPtr = import_call_4 ( changetype < i32 > ( contract . dataStart ) , contract . byteLength , funcPtr , funcBytes . byteLength ,
382- changetype < i32 > ( args [ 0 ] . dataStart ) , args [ 0 ] . byteLength , changetype < i32 > ( args [ 1 ] . dataStart ) , args [ 1 ] . byteLength ,
383- changetype < i32 > ( args [ 2 ] . dataStart ) , args [ 2 ] . byteLength , changetype < i32 > ( args [ 3 ] . dataStart ) , args [ 3 ] . byteLength ) ;
384- break ;
385- default :
386- abort ( "call_invalid_no_of_args" ) ;
343+ // One import to rule them all
344+ @external ( "env" , "import_call" )
345+ declare function import_call ( args_ptr : i32 , extra_args_ptr : i32 ) : i32 ;
346+ export function call < C , F , T = Uint8Array > ( contract : C , func : F , args : T [ ] , extra_args : T [ ] | null = null ) : Uint8Array {
347+ const contractBytes = toBytes < C > ( contract ) ;
348+ const funcBytes = toBytes < F > ( func ) ;
349+
350+ const pinnedArgs = new Array < Uint8Array > ( 2 + args . length ) ;
351+ pinnedArgs [ 0 ] = contractBytes ;
352+ pinnedArgs [ 1 ] = funcBytes ;
353+ for ( let j = 0 ; j < args . length ; j ++ ) { pinnedArgs [ 2 + j ] = toBytes < T > ( args [ j ] ) }
354+
355+ // 4 bytes for Count
356+ // 16 bytes for contract + func
357+ // 8 bytes * args
358+ const totalItems = 2 + args . length ;
359+ const tablePtr = __alloc ( 4 + 16 + ( 8 * totalItems ) ) ;
360+ store < i32 > ( tablePtr , totalItems ) ;
361+ for ( let i = 0 ; i < pinnedArgs . length ; i ++ ) {
362+ const arg = pinnedArgs [ i ] ;
363+ const offset = 4 + ( i * 8 ) ;
364+
365+ store < i32 > ( tablePtr + offset , changetype < i32 > ( arg . dataStart ) ) ;
366+ store < i32 > ( tablePtr + offset + 4 , arg . byteLength ) ;
387367 }
388368
389- return memory_read_string ( errorPtr ) ;
369+ //Extra args
370+ let extraTablePtr = 0 ;
371+ if ( extra_args ) {
372+ const pinnedExtraArgs = new Array < Uint8Array > ( extra_args . length ) ;
373+ for ( let i = 0 ; i < extra_args . length ; i ++ ) { pinnedExtraArgs [ i ] = toBytes < T > ( extra_args [ i ] ) }
374+
375+ extraTablePtr = __alloc ( 4 + ( 8 * extra_args . length ) ) as i32 ;
376+ store < i32 > ( extraTablePtr , extra_args . length ) ;
377+
378+ for ( let i = 0 ; i < extra_args . length ; i ++ ) {
379+ const earg = pinnedExtraArgs [ i ] ;
380+ const offset = 4 + ( i * 8 ) ;
381+
382+ store < i32 > ( extraTablePtr + offset , changetype < i32 > ( earg . dataStart ) ) ;
383+ store < i32 > ( extraTablePtr + offset + 4 , earg . byteLength ) ;
384+ }
385+ }
386+
387+ const errorPtr = import_call ( tablePtr as i32 , extraTablePtr as i32 ) ;
388+
389+ // Cleanup (Optional, but good practice if you do this in a loop)
390+ __free ( tablePtr ) ;
391+
392+ return memory_read_bytes ( errorPtr ) ;
390393}
391394
392395/*
@@ -453,36 +456,3 @@ function kv_get<T,Y>(key: Y): T {
453456 }*/
454457//return null as T;
455458//}
456-
457-
458- /*
459- @external ("env", "import_kv_increment")
460- declare function import_kv_increment(keyPtr: i32, keyLen: i32, amount: i64): i64;
461- function kv_increment(key: string, amount: i64): i64 {
462- let keyBytes = String.UTF8.encode(key);
463- let keyPtr = changetype<i32>(keyBytes);
464- let keyLen = keyBytes.byteLength;
465-
466- return import_kv_increment(keyPtr, keyLen, amount);
467- }
468-
469- @external ("env", "import_kv_get")
470- declare function import_kv_get(keyPtr: i32, keyLen: i32): i32;
471- function kv_get(key: string): string {
472- let keyBytes = String.UTF8.encode(key);
473- let keyPtr = changetype<i32>(keyBytes);
474- let keyLen = keyBytes.byteLength;
475-
476- const valPtr = import_kv_get(keyPtr, keyLen);
477- if (!valPtr) {
478- return "";
479- }
480-
481- const valLen = load<u32>(valPtr);
482- const valBytesPtr = valPtr + 4;
483- //const valBytes = new Uint8Array(import_memory.buffer, valBytesPtr, valLen);
484- //return String.UTF8.decode(valBytes.buffer);
485- return "";
486- }
487-
488- */
0 commit comments