From 962335bb92e5256e1086c5f6c843c3bcf61f849e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Vujovi=C4=87?= Date: Mon, 19 Sep 2022 22:41:18 +0200 Subject: [PATCH] feat: Refactor API internally Improve type definitions for QJS environment Rename variables and parameters to JavaScript standards Refactor code --- lib/api.d.ts | 38 +++---- lib/api.js | 73 +++++--------- src/api.ts | 273 ++++++++++++++++++++++++++++++++++----------------- 3 files changed, 228 insertions(+), 156 deletions(-) diff --git a/lib/api.d.ts b/lib/api.d.ts index f80fe858c..a2e2e9560 100644 --- a/lib/api.d.ts +++ b/lib/api.d.ts @@ -1,5 +1,5 @@ -import { Bytes } from "./utils"; -export declare function log(...params: any[]): void; +import { Bytes, NearAmount, PromiseIndex } from "./utils"; +export declare function log(...params: unknown[]): void; export declare function signerAccountId(): string; export declare function signerAccountPk(): Bytes; export declare function predecessorAccountId(): string; @@ -21,7 +21,7 @@ export declare function logUtf8(msg: Bytes): void; export declare function logUtf16(msg: Bytes): void; export declare function storageRead(key: Bytes): Bytes | null; export declare function storageHasKey(key: Bytes): boolean; -export declare function validatorStake(accountId: string): any; +export declare function validatorStake(accountId: string): bigint; export declare function validatorTotalStake(): bigint; export declare function altBn128G1Multiexp(value: Bytes): Bytes; export declare function altBn128G1Sum(value: Bytes): Bytes; @@ -33,24 +33,24 @@ export declare function storageUsage(): bigint; export declare function accountBalance(): bigint; export declare function accountLockedBalance(): bigint; export declare function valueReturn(value: Bytes): void; -export declare function promiseCreate(accountId: string, methodName: string, args: Bytes, amount: number | bigint, gas: number | bigint): bigint; -export declare function promiseThen(promiseIndex: number | bigint, accountId: string, methodName: string, args: Bytes, amount: number | bigint, gas: number | bigint): any; -export declare function promiseAnd(...promiseIndex: number[] | bigint[]): bigint; +export declare function promiseCreate(accountId: string, methodName: string, args: Bytes, amount: NearAmount, gas: NearAmount): bigint; +export declare function promiseThen(promiseIndex: PromiseIndex, accountId: string, methodName: string, args: Bytes, amount: NearAmount, gas: NearAmount): bigint; +export declare function promiseAnd(...promiseIndexes: PromiseIndex[]): bigint; export declare function promiseBatchCreate(accountId: string): bigint; -export declare function promiseBatchThen(promiseIndex: number | bigint, accountId: string): bigint; -export declare function promiseBatchActionCreateAccount(promiseIndex: number | bigint): void; -export declare function promiseBatchActionDeployContract(promiseIndex: number | bigint, code: Bytes): void; -export declare function promiseBatchActionFunctionCall(promiseIndex: number | bigint, methodName: string, args: Bytes, amount: number | bigint, gas: number | bigint): void; -export declare function promiseBatchActionTransfer(promiseIndex: number | bigint, amount: number | bigint): void; -export declare function promiseBatchActionStake(promiseIndex: number | bigint, amount: number | bigint, publicKey: Bytes): void; -export declare function promiseBatchActionAddKeyWithFullAccess(promiseIndex: number | bigint, publicKey: Bytes, nonce: number | bigint): void; -export declare function promiseBatchActionAddKeyWithFunctionCall(promiseIndex: number | bigint, publicKey: Bytes, nonce: number | bigint, allowance: number | bigint, receiverId: string, methodNames: string): void; -export declare function promiseBatchActionDeleteKey(promiseIndex: number | bigint, publicKey: Bytes): void; -export declare function promiseBatchActionDeleteAccount(promiseIndex: number | bigint, beneficiaryId: string): void; -export declare function promiseBatchActionFunctionCallWeight(promiseIndex: number | bigint, methodName: string, args: Bytes, amount: number | bigint, gas: number | bigint, weight: number | bigint): void; +export declare function promiseBatchThen(promiseIndex: PromiseIndex, accountId: string): bigint; +export declare function promiseBatchActionCreateAccount(promiseIndex: PromiseIndex): void; +export declare function promiseBatchActionDeployContract(promiseIndex: PromiseIndex, code: Bytes): void; +export declare function promiseBatchActionFunctionCall(promiseIndex: PromiseIndex, methodName: string, args: Bytes, amount: NearAmount, gas: NearAmount): void; +export declare function promiseBatchActionTransfer(promiseIndex: PromiseIndex, amount: NearAmount): void; +export declare function promiseBatchActionStake(promiseIndex: PromiseIndex, amount: NearAmount, publicKey: Bytes): void; +export declare function promiseBatchActionAddKeyWithFullAccess(promiseIndex: PromiseIndex, publicKey: Bytes, nonce: number | bigint): void; +export declare function promiseBatchActionAddKeyWithFunctionCall(promiseIndex: PromiseIndex, publicKey: Bytes, nonce: number | bigint, allowance: NearAmount, receiverId: string, methodNames: string): void; +export declare function promiseBatchActionDeleteKey(promiseIndex: PromiseIndex, publicKey: Bytes): void; +export declare function promiseBatchActionDeleteAccount(promiseIndex: PromiseIndex, beneficiaryId: string): void; +export declare function promiseBatchActionFunctionCallWeight(promiseIndex: PromiseIndex, methodName: string, args: Bytes, amount: NearAmount, gas: NearAmount, weight: number | bigint): void; export declare function promiseResultsCount(): bigint; -export declare function promiseResult(resultIdx: number | bigint): Bytes; -export declare function promiseReturn(promiseIdx: number | bigint): void; +export declare function promiseResult(promiseIndex: PromiseIndex): Bytes; +export declare function promiseReturn(promiseIndex: PromiseIndex): void; export declare function storageWrite(key: Bytes, value: Bytes): boolean; export declare function storageRemove(key: Bytes): boolean; export declare function storageByteCost(): bigint; diff --git a/lib/api.js b/lib/api.js index 149dfbed2..1620bab2c 100644 --- a/lib/api.js +++ b/lib/api.js @@ -1,11 +1,12 @@ +import { assert } from "./utils"; import { PromiseResult } from "./types"; const U64_MAX = 2n ** 64n - 1n; const EVICTED_REGISTER = U64_MAX - 1n; export function log(...params) { - env.log(`${params + env.log(params .map((x) => (x === undefined ? "undefined" : x)) // Stringify undefined .map((x) => (typeof x === "object" ? JSON.stringify(x) : x)) // Convert Objects to strings - .join(" ")}` // Convert to string + .join(" ") // Convert to string ); } export function signerAccountId() { @@ -62,8 +63,8 @@ export function ripemd160(value) { return env.read_register(0); } export function ecrecover(hash, sig, v, malleabilityFlag) { - const ret = env.ecrecover(hash, sig, v, malleabilityFlag, 0); - if (ret === 0n) { + const returnValue = env.ecrecover(hash, sig, v, malleabilityFlag, 0); + if (returnValue === 0n) { return null; } return env.read_register(0); @@ -79,22 +80,14 @@ export function logUtf16(msg) { env.log_utf16(msg); } export function storageRead(key) { - const ret = env.storage_read(key, 0); - if (ret === 1n) { - return env.read_register(0); - } - else { + const returnValue = env.storage_read(key, 0); + if (returnValue !== 1n) { return null; } + return env.read_register(0); } export function storageHasKey(key) { - const ret = env.storage_has_key(key); - if (ret === 1n) { - return true; - } - else { - return false; - } + return env.storage_has_key(key) === 1n; } export function validatorStake(accountId) { return env.validator_stake(accountId); @@ -111,13 +104,7 @@ export function altBn128G1Sum(value) { return env.read_register(0); } export function altBn128PairingCheck(value) { - const ret = env.alt_bn128_pairing_check(value); - if (ret === 1n) { - return true; - } - else { - return false; - } + return env.alt_bn128_pairing_check(value) === 1n; } export function storageGetEvicted() { return env.read_register(EVICTED_REGISTER); @@ -148,8 +135,8 @@ export function promiseCreate(accountId, methodName, args, amount, gas) { export function promiseThen(promiseIndex, accountId, methodName, args, amount, gas) { return env.promise_then(promiseIndex, accountId, methodName, args, amount, gas); } -export function promiseAnd(...promiseIndex) { - return env.promise_and(...promiseIndex); +export function promiseAnd(...promiseIndexes) { + return env.promise_and(...promiseIndexes); } export function promiseBatchCreate(accountId) { return env.promise_batch_create(accountId); @@ -190,35 +177,23 @@ export function promiseBatchActionFunctionCallWeight(promiseIndex, methodName, a export function promiseResultsCount() { return env.promise_results_count(); } -export function promiseResult(resultIdx) { - const status = env.promise_result(resultIdx, 0); - if (status == PromiseResult.Successful) { - return env.read_register(0); - } - else { - throw Error(`Promise result ${status == PromiseResult.Failed - ? "Failed" - : status == PromiseResult.NotReady - ? "NotReady" - : status}`); - } +export function promiseResult(promiseIndex) { + const status = env.promise_result(promiseIndex, 0); + assert(Number(status) === PromiseResult.Successful, `Promise result ${status == PromiseResult.Failed + ? "Failed" + : status == PromiseResult.NotReady + ? "NotReady" + : status}`); + return env.read_register(0); } -export function promiseReturn(promiseIdx) { - env.promise_return(promiseIdx); +export function promiseReturn(promiseIndex) { + env.promise_return(promiseIndex); } export function storageWrite(key, value) { - const exist = env.storage_write(key, value, EVICTED_REGISTER); - if (exist === 1n) { - return true; - } - return false; + return env.storage_write(key, value, EVICTED_REGISTER) === 1n; } export function storageRemove(key) { - const exist = env.storage_remove(key, EVICTED_REGISTER); - if (exist === 1n) { - return true; - } - return false; + return env.storage_remove(key, EVICTED_REGISTER) === 1n; } export function storageByteCost() { return 10000000000000000000n; diff --git a/src/api.ts b/src/api.ts index a4e2dd4cb..fe5a9f603 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,4 +1,4 @@ -import { Bytes } from "./utils"; +import { assert, Bytes, NearAmount, PromiseIndex, Register } from "./utils"; import { PromiseResult } from "./types"; const U64_MAX = 2n ** 64n - 1n; @@ -6,18 +6,128 @@ const EVICTED_REGISTER = U64_MAX - 1n; // Interface available in QuickJS interface Env { - panic_utf8: (msg: string) => never; - [x: string]: any; + panic_utf8(msg: string): never; + log(message: string): void; + log_utf8(message: string): void; + log_utf16(message: string): void; + read_register(register: Register): string; + storage_read(key: string, register: Register): bigint; + storage_has_key(key: string): bigint; + storage_write(key: string, value: string, register: Register): bigint; + storage_remove(key: string, register: Register): bigint; + signer_account_id(register: Register): void; + signer_account_pk(register: Register): void; + predecessor_account_id(register: Register): void; + current_account_id(register: Register): void; + random_seed(register: Register): void; + block_index(): bigint; + block_timestamp(): bigint; + epoch_height(): bigint; + attached_deposit(): bigint; + prepaid_gas(): bigint; + used_gas(): bigint; + sha256(value: string, register: Register): void; + keccak256(value: string, register: Register): void; + keccak512(value: string, register: Register): void; + ripemd160(value: string, register: Register): void; + ecrecover( + hash: Bytes, + sig: Bytes, + v: number, + malleabilityFlag: number, + register: Register + ): bigint; + validator_stake(accountId: string): bigint; + validator_total_stake(): bigint; + alt_bn128_g1_multiexp(value: string, register: Register): void; + alt_bn128_g1_sum(value: string, register: Register): void; + alt_bn128_pairing_check(value: string): bigint; + input(register: Register): void; + storage_usage(): bigint; + account_balance(): bigint; + account_locked_balance(): bigint; + value_return(value: string): void; + promise_create( + accountId: string, + methodName: string, + args: Bytes, + amount: NearAmount, + gas: NearAmount + ): bigint; + promise_then( + promiseIndex: PromiseIndex, + accountId: string, + methodName: string, + args: Bytes, + amount: NearAmount, + gas: NearAmount + ): bigint; + promise_and(...promiseIndexes: PromiseIndex[]): bigint; + promise_batch_create(accountId: string): bigint; + promise_batch_then(promiseIndex: PromiseIndex, accountId: string): bigint; + promise_batch_action_create_account(promiseIndex: PromiseIndex): void; + promise_batch_action_deploy_contract( + promiseIndex: PromiseIndex, + code: string + ): void; + promise_batch_action_function_call( + promiseIndex: PromiseIndex, + methodName: string, + args: Bytes, + amount: NearAmount, + gas: NearAmount + ): void; + promise_batch_action_transfer( + promiseIndex: PromiseIndex, + amount: NearAmount + ): void; + promise_batch_action_stake( + promiseIndex: PromiseIndex, + amount: NearAmount, + publicKey: Bytes + ): void; + promise_batch_action_add_key_with_full_access( + promiseIndex: PromiseIndex, + publicKey: Bytes, + nonce: number | bigint + ): void; + promise_batch_action_add_key_with_function_call( + promiseIndex: PromiseIndex, + publicKey: Bytes, + nonce: number | bigint, + allowance: NearAmount, + receiverId: string, + methodNames: string + ): void; + promise_batch_action_delete_key( + promiseIndex: PromiseIndex, + publicKey: Bytes + ): void; + promise_batch_action_delete_account( + promiseIndex: PromiseIndex, + beneficiaryId: string + ): void; + promise_batch_action_function_call_weight( + promiseIndex: PromiseIndex, + methodName: string, + args: Bytes, + amount: NearAmount, + gas: NearAmount, + weight: number | bigint + ): void; + promise_results_count(): bigint; + promise_result(promiseIndex: PromiseIndex, register: Register): PromiseResult; + promise_return(promiseIndex: PromiseIndex): void; } declare let env: Env; -export function log(...params: any[]) { +export function log(...params: unknown[]) { env.log( - `${params + params .map((x) => (x === undefined ? "undefined" : x)) // Stringify undefined .map((x) => (typeof x === "object" ? JSON.stringify(x) : x)) // Convert Objects to strings - .join(" ")}` // Convert to string + .join(" ") // Convert to string ); } @@ -95,10 +205,12 @@ export function ecrecover( v: number, malleabilityFlag: number ): Bytes | null { - const ret = env.ecrecover(hash, sig, v, malleabilityFlag, 0); - if (ret === 0n) { + const returnValue = env.ecrecover(hash, sig, v, malleabilityFlag, 0); + + if (returnValue === 0n) { return null; } + return env.read_register(0); } @@ -117,24 +229,20 @@ export function logUtf16(msg: Bytes) { } export function storageRead(key: Bytes): Bytes | null { - const ret = env.storage_read(key, 0); - if (ret === 1n) { - return env.read_register(0); - } else { + const returnValue = env.storage_read(key, 0); + + if (returnValue !== 1n) { return null; } + + return env.read_register(0); } export function storageHasKey(key: Bytes): boolean { - const ret = env.storage_has_key(key); - if (ret === 1n) { - return true; - } else { - return false; - } + return env.storage_has_key(key) === 1n; } -export function validatorStake(accountId: string) { +export function validatorStake(accountId: string): bigint { return env.validator_stake(accountId); } @@ -153,12 +261,7 @@ export function altBn128G1Sum(value: Bytes): Bytes { } export function altBn128PairingCheck(value: Bytes): boolean { - const ret = env.alt_bn128_pairing_check(value); - if (ret === 1n) { - return true; - } else { - return false; - } + return env.alt_bn128_pairing_check(value) === 1n; } export function storageGetEvicted(): Bytes { @@ -187,7 +290,7 @@ export function accountLockedBalance(): bigint { return env.account_locked_balance(); } -export function valueReturn(value: Bytes) { +export function valueReturn(value: Bytes): void { env.value_return(value); } @@ -195,20 +298,20 @@ export function promiseCreate( accountId: string, methodName: string, args: Bytes, - amount: number | bigint, - gas: number | bigint + amount: NearAmount, + gas: NearAmount ): bigint { return env.promise_create(accountId, methodName, args, amount, gas); } export function promiseThen( - promiseIndex: number | bigint, + promiseIndex: PromiseIndex, accountId: string, methodName: string, args: Bytes, - amount: number | bigint, - gas: number | bigint -) { + amount: NearAmount, + gas: NearAmount +): bigint { return env.promise_then( promiseIndex, accountId, @@ -219,8 +322,8 @@ export function promiseThen( ); } -export function promiseAnd(...promiseIndex: number[] | bigint[]): bigint { - return env.promise_and(...promiseIndex); +export function promiseAnd(...promiseIndexes: PromiseIndex[]): bigint { + return env.promise_and(...promiseIndexes); } export function promiseBatchCreate(accountId: string): bigint { @@ -228,30 +331,32 @@ export function promiseBatchCreate(accountId: string): bigint { } export function promiseBatchThen( - promiseIndex: number | bigint, + promiseIndex: PromiseIndex, accountId: string ): bigint { return env.promise_batch_then(promiseIndex, accountId); } -export function promiseBatchActionCreateAccount(promiseIndex: number | bigint) { +export function promiseBatchActionCreateAccount( + promiseIndex: PromiseIndex +): void { env.promise_batch_action_create_account(promiseIndex); } export function promiseBatchActionDeployContract( - promiseIndex: number | bigint, + promiseIndex: PromiseIndex, code: Bytes -) { +): void { env.promise_batch_action_deploy_contract(promiseIndex, code); } export function promiseBatchActionFunctionCall( - promiseIndex: number | bigint, + promiseIndex: PromiseIndex, methodName: string, args: Bytes, - amount: number | bigint, - gas: number | bigint -) { + amount: NearAmount, + gas: NearAmount +): void { env.promise_batch_action_function_call( promiseIndex, methodName, @@ -262,25 +367,25 @@ export function promiseBatchActionFunctionCall( } export function promiseBatchActionTransfer( - promiseIndex: number | bigint, - amount: number | bigint -) { + promiseIndex: PromiseIndex, + amount: NearAmount +): void { env.promise_batch_action_transfer(promiseIndex, amount); } export function promiseBatchActionStake( - promiseIndex: number | bigint, - amount: number | bigint, + promiseIndex: PromiseIndex, + amount: NearAmount, publicKey: Bytes -) { +): void { env.promise_batch_action_stake(promiseIndex, amount, publicKey); } export function promiseBatchActionAddKeyWithFullAccess( - promiseIndex: number | bigint, + promiseIndex: PromiseIndex, publicKey: Bytes, nonce: number | bigint -) { +): void { env.promise_batch_action_add_key_with_full_access( promiseIndex, publicKey, @@ -289,13 +394,13 @@ export function promiseBatchActionAddKeyWithFullAccess( } export function promiseBatchActionAddKeyWithFunctionCall( - promiseIndex: number | bigint, + promiseIndex: PromiseIndex, publicKey: Bytes, nonce: number | bigint, - allowance: number | bigint, + allowance: NearAmount, receiverId: string, methodNames: string -) { +): void { env.promise_batch_action_add_key_with_function_call( promiseIndex, publicKey, @@ -307,27 +412,27 @@ export function promiseBatchActionAddKeyWithFunctionCall( } export function promiseBatchActionDeleteKey( - promiseIndex: number | bigint, + promiseIndex: PromiseIndex, publicKey: Bytes -) { +): void { env.promise_batch_action_delete_key(promiseIndex, publicKey); } export function promiseBatchActionDeleteAccount( - promiseIndex: number | bigint, + promiseIndex: PromiseIndex, beneficiaryId: string -) { +): void { env.promise_batch_action_delete_account(promiseIndex, beneficiaryId); } export function promiseBatchActionFunctionCallWeight( - promiseIndex: number | bigint, + promiseIndex: PromiseIndex, methodName: string, args: Bytes, - amount: number | bigint, - gas: number | bigint, + amount: NearAmount, + gas: NearAmount, weight: number | bigint -) { +): void { env.promise_batch_action_function_call_weight( promiseIndex, methodName, @@ -342,41 +447,33 @@ export function promiseResultsCount(): bigint { return env.promise_results_count(); } -export function promiseResult(resultIdx: number | bigint): Bytes { - const status: PromiseResult = env.promise_result(resultIdx, 0); - if (status == PromiseResult.Successful) { - return env.read_register(0); - } else { - throw Error( - `Promise result ${ - status == PromiseResult.Failed - ? "Failed" - : status == PromiseResult.NotReady - ? "NotReady" - : status - }` - ); - } +export function promiseResult(promiseIndex: PromiseIndex): Bytes { + const status = env.promise_result(promiseIndex, 0); + + assert( + Number(status) === PromiseResult.Successful, + `Promise result ${ + status == PromiseResult.Failed + ? "Failed" + : status == PromiseResult.NotReady + ? "NotReady" + : status + }` + ); + + return env.read_register(0); } -export function promiseReturn(promiseIdx: number | bigint) { - env.promise_return(promiseIdx); +export function promiseReturn(promiseIndex: PromiseIndex): void { + env.promise_return(promiseIndex); } export function storageWrite(key: Bytes, value: Bytes): boolean { - const exist = env.storage_write(key, value, EVICTED_REGISTER); - if (exist === 1n) { - return true; - } - return false; + return env.storage_write(key, value, EVICTED_REGISTER) === 1n; } export function storageRemove(key: Bytes): boolean { - const exist = env.storage_remove(key, EVICTED_REGISTER); - if (exist === 1n) { - return true; - } - return false; + return env.storage_remove(key, EVICTED_REGISTER) === 1n; } export function storageByteCost(): bigint {