diff --git a/src/lib/annotations.ts b/src/lib/annotations.ts deleted file mode 100644 index 445ab80e14..0000000000 --- a/src/lib/annotations.ts +++ /dev/null @@ -1,173 +0,0 @@ -// Some JS docs licensed under: -// -// - https://github.com/dfinity/cdk-rs/blob/main/LICENSE -// - https://github.com/dfinity/interface-spec/blob/master/LICENSE -// -// Some documentation changed from original work. - -import { GuardResult } from './results'; -import { ic } from './ic'; - -/** - * Configuration options for canister methods - * - * @param guard - an optional guard function to be executed before the canister - * method. When the guard function returns an error, the canister method will - * not proceed. - */ -export type CanisterMethodOptions = { guard?: () => GuardResult }; - -/** - * Marks the subsequent exported function as a "heartbeat" system canister method. - * {@link $heartbeat} is called with every "tick" of the internet computer and - * can be use for periodic or time-based execution. - * - * {@link $heartbeat} is triggered by the IC, and therefore has no arguments, - * no caller, and cannot reply or reject. - * - * The annotated function should take no parameters and should have a return - * type of `void`. It may be sync or async. - * - * @example - * ```ts - * import { $heartbeat, match } from 'azle'; - * import { managementCanister } from 'azle/canisters/management'; - * - * $heartbeat; - * export async function heartbeat(): Promise { - * const randomnessResult = await managementCanister.raw_rand().call(); - * - * match(randomnessResult, { - * Ok: (randomness) => { - * console.log('heartbeat initialized', randomness.length); - * }, - * Err: () => {} - * }); - * } - * ``` - */ -export const $heartbeat = (options?: CanisterMethodOptions) => {}; - -/** - * Marks the subsequent exported function as an "init" system canister method. - * {@link $init} is called on the very first deploy and can be used to set up - * initial state and invariants. - * - * The annotated function may take zero or more parameters (must match - * {@link $postUpgrade} if present) and should have a return type of `void`. - * - * @example - * ```ts - * import { blob, $init, Opt, Record } from 'azle'; - * - * type State = Record<{ - * data: blob; - * }>; - * - * let state: Opt = Opt.None; - * - * $init; - * export function init(initialState: State): void { - * state = Opt.Some(initialState); - * } - * ``` - */ -export const $init = () => {}; // TODO: See https://github.com/demergent-labs/azle/issues/954 - -/** - * Marks the subsequent exported function as an "inspect-message" system - * canister method. {@link $inspectMessage} is called before all ingress - * messages and can be used for access control. - * - * To accept the message call {@link ic.acceptMessage}. This function traps if - * invoked twice. If the canister traps in {@link $inspectMessage} or does not - * call {@link ic.acceptMessage}, then the access is denied. - * - * The annotated function should take no parameters and should have a return - * type of `void`. - * - * @example - * ```ts - * $inspectMessage; - * export function controlAccess(): void { - * if (ic.methodName() === 'accessible') { - * ic.acceptMessage(); - * return; - * } - * - * if (ic.methodName() === 'inaccessible') { - * return; - * } - * - * throw `Method "${ic.methodName()}" not allowed`; - * } - * ``` - */ -export const $inspectMessage = (options?: CanisterMethodOptions) => {}; - -/** - * Marks the subsequent exported function as a "post-upgrade" system canister - * method. {@link $postUpgrade} is called after every deploy (except the initial - * deploy) and can be used to restore data from stable memory after the new code - * has been installed. - * - * The annotated function should take no parameters and should have a return - * type of `void`. - * - * @example - * ```ts - * $postUpgrade; - * export function restoreData(): void { - * // Move data from stable memory or initialize state - * } - * ``` - */ -export const $postUpgrade = () => {}; // TODO: See https://github.com/demergent-labs/azle/issues/954 - -/** - * Marks the subsequent exported function as a "pre-upgrade" system canister - * method. {@link $preUpgrade} is called after every deploy (except the initial - * deploy) and is used to perform cleanup tasks and move data to stable memory before - * it gets wiped during the upgrade. - * - * The annotated function should have zero or more parameters (must match - * {@link $init} if present) and should have a return type of `void`. - * - * @example - * ```ts - * $preUpgrade; - * export function migrateData(): void { - * // Move data to stable memory or clean it up - * } - * ``` - */ -export const $preUpgrade = (options?: CanisterMethodOptions) => {}; - -/** - * Marks the subsequent exported function as a "query" canister method. Query - * methods do not pass through consensus and state mutations are discarded. - * - * @example - * ```ts - * $query; - * export function getMessage(): string { - * return "Hello World"; - * } - * ``` - */ -export const $query = (options?: CanisterMethodOptions) => {}; - -/** - * Marks the subsequent exported function as an "update" canister method. Update - * methods pass through consensus and state mutations are preserved. - * - * @example - * ```ts - * $update; - * export function updateMessage(newMessage: string): bool { - * state = newMessage; - * return true; - * } - * ``` - */ -export const $update = (options?: CanisterMethodOptions) => {}; diff --git a/src/lib/candid_types/func.ts b/src/lib/candid_types/func.ts deleted file mode 100644 index ea094d5dc2..0000000000 --- a/src/lib/candid_types/func.ts +++ /dev/null @@ -1,128 +0,0 @@ -// Some JS docs licensed under: -// -// - https://github.com/dfinity/cdk-rs/blob/main/LICENSE -// - https://github.com/dfinity/interface-spec/blob/master/LICENSE -// - https://github.com/dfinity/portal/blob/master/LICENSE -// -// Some documentation changed from original work. - -import { Principal, Service } from './'; -import { CallResult } from '../results'; - -/** - * An alias of a `[Principal, string]` tuple that represents a reference to a - * {@link Service} method. At runtime it is an array with two values: - * - * - the principal of the {@link Service} where the method is - * defined - * - the name of the method - * - * See https://internetcomputer.org/docs/current/references/candid-ref#type-func--- - * - * @typeParam Mode - the mode in which to call the referenced {@link Service} - * method. Its type param specifies the signature of the method. Mode must be one of: - * - * - {@link Query} - * - {@link Update} - * - {@link Oneway} - * - * @example - * The following Func declaration: - * ```ts - * type CanisterMethod = Func string>>; - * ``` - * corresponds to this Candid service method definition: - * ```candid - * service: { - * canisterMethod : (text) -> (text) query; - * } - * ``` - */ -export type Func< - Mode extends - | Query - | Update - | Oneway -> = [Principal, string]; - -/** - * Indicates that the {@link Func} will be called in query mode - * - * @typeParam FuncSignature - the signature of the {@link Service} method - * - * @example - * The following Func declaration: - * ```ts - * type CanisterMethod = Func string>>; - * ``` - * corresponds to this Candid service method definition: - * ```candid - * service: { - * canisterMethod : (text) -> (text) query; - * } - * ``` - * and will produce this func Candid definition: - * ```candid - * type CanisterMethod = func (text) -> (text) query; - * ``` - */ -export type Query any> = [ - Principal, - string -]; - -/** - * Indicates that the {@link Func} will be called in update mode - * - * @typeParam FuncSignature - the signature of the {@link Service} method - * - * @example - * The following Func declaration: - * ```ts - * type CanisterMethod = Func string>>; - * ``` - * corresponds to this Candid service method definition: - * ```candid - * service: { - * canisterMethod : (text) -> (text); - * } - * ``` - * and will produce this func Candid definition: - * ```candid - * type CanisterMethod = func (text) -> (text); - * ``` - */ -export type Update any> = [ - Principal, - string -]; - -/** - * Indicates that calls to the {@link Func} should not be awaited. Intended to - * be used with {@link CallResult.notify}. - * - * @typeParam FuncSignature - the signature of the {@link Service} method - * - * @example - * The following Func declaration: - * ```ts - * type CanisterMethod = Func string>>; - * ``` - * corresponds to this Candid service method definition: - * ```candid - * service: { - * canisterMethod : (text) -> (text); - * } - * ``` - * and will produce this func Candid definition: - * ```candid - * type CanisterMethod = func (text) -> (text) oneway; - * ``` - */ -export type Oneway any> = [ - Principal, - string -]; - -/** Describes the parameter types and return value of the {@link Func} */ -export type FuncSignature = (...args: any[]) => any; diff --git a/src/lib/candid_types/index.ts b/src/lib/candid_types/index.ts deleted file mode 100644 index f0db4cd7e6..0000000000 --- a/src/lib/candid_types/index.ts +++ /dev/null @@ -1,211 +0,0 @@ -// Some JS docs licensed under: -// -// - https://github.com/dfinity/cdk-rs/blob/main/LICENSE -// - https://github.com/dfinity/interface-spec/blob/master/LICENSE -// - https://github.com/dfinity/portal/blob/master/LICENSE -// - https://github.com/rust-lang/rust/blob/master/LICENSE-APACHE -// -// Some documentation changed from original work. - -import { Variant } from './variant'; - -export { Principal } from '@dfinity/principal'; -export { Func } from './func'; -export { Service } from './service'; -export { Variant } from './variant'; - -/** Marks a type as being an alias to a candid type */ -export type Alias = T; - -/** - * Represents a sequence of bytes`. - * - * See https://internetcomputer.org/docs/current/references/candid-ref#type-blob - */ -export type blob = Uint8Array; - -/** - * Represents the absence of a value. - * - * Practical use cases for the {@link empty} type are relatively rare. It could - * be used to mark a method as “never returns successfully”. For example: - * - * ```ts - * $query; - * export function myCanisterMethod(): empty { - * throw new Error('Never returns successfully'); - * } - * ``` - * - * See https://internetcomputer.org/docs/current/references/candid-ref#type-empty - */ -export type empty = never; - -/** - * Represents a single precision (32 bit) IEEE 754 floating point number. A - * JavaScript `number` at runtime. - * - * See https://demergent-labs.github.io/azle/reference/candid/float32.html - */ -export type float32 = number; - -/** - * Represents a double precision (64 bit) IEEE 754 floating point number. A - * JavaScript `number` at runtime. - * - * See https://demergent-labs.github.io/azle/reference/candid/float64.html - */ -export type float64 = number; - -/** - * Represents a whole number. A JavaScript `bigint` at runtime. - * - * See https://demergent-labs.github.io/azle/reference/candid/int.html - */ -export type int = bigint; - -/** - * Represents a whole number in the range {-2^63 …​ (2^63)-1}. A JavaScript - * `bigint` at runtime. - * - * See https://demergent-labs.github.io/azle/reference/candid/int64.html - */ -export type int64 = bigint; - -/** - * Represents a whole number in the range {-2^31 …​ (2^31)-1}. A JavaScript - * `number` at runtime. - * - * See https://demergent-labs.github.io/azle/reference/candid/int32.html - */ -export type int32 = number; - -/** - * Represents a whole number in the range {-2^15 …​ (2^15)-1}. A JavaScript - * `number` at runtime. - * - * See https://demergent-labs.github.io/azle/reference/candid/int16.html - */ -export type int16 = number; - -/** - * Represents a whole number in the range {-2^7 …​ (2^7)-1}. A JavaScript - * `number` at runtime. - * - * See https://demergent-labs.github.io/azle/reference/candid/int8.html - */ -export type int8 = number; - -/** - * Represents a natural (non-negative) number. A JavaScript `bigint` at - * runtime. - * - * See https://demergent-labs.github.io/azle/reference/candid/nat.html - */ -export type nat = bigint; - -/** - * Represents a natural (non-negative) number in the range {0 …​ 2^64-1}. A - * JavaScript `bigint` at runtime. - * - * See https://demergent-labs.github.io/azle/reference/candid/nat64.html - */ -export type nat64 = bigint; - -/** - * Represents a natural (non-negative) number in the range {0 …​ 2^32-1}. A - * JavaScript `number` at runtime. - * - * See https://demergent-labs.github.io/azle/reference/candid/nat32.html - */ -export type nat32 = number; - -/** - * Represents a natural (non-negative) number in the range {0 …​ 2^16-1}. A - * JavaScript `number` at runtime. - * - * See https://demergent-labs.github.io/azle/reference/candid/nat16.html - */ -export type nat16 = number; - -/** - * Represents a natural (non-negative) number in the range {0 …​ 2^8-1}. A - * JavaScript `number` at runtime. - * - * See https://demergent-labs.github.io/azle/reference/candid/nat8.html - */ -export type nat8 = number; - -/** - * Represents an optional value: every {@link Opt} is either `Some` and contains - * a value, or `None` and does not. - */ -export type Opt = Variant<{ - /** Indicates there is a value */ - Some: Value; - /** Indicates there is no value */ - None: null; -}>; - -export const Opt = { - /** - * Wraps the provided value in a `Some` {@link Opt} - * @param value - the value to be wrapped - * @returns a `Some` {@link Opt} containing the provided value - */ - Some: (value: Value): Opt => ({ - Some: value - }), - /** An {@link Opt} representing the absence of a value */ - None: Object.freeze({ None: null }) as Opt -}; - -/** - * An unordered heterogeneous collection of labeled values. - * - * @example - * ```ts - * type Address = Record<{ - * street: string, - * city: string, - * zipCode: nat, - * country: string - * }>; - * ``` - * - * See https://internetcomputer.org/docs/current/references/candid-ref#type-record--n--t-- - */ -export type Record = T; - -/** - * A type with one (uninformative) value: `reserved`. - * - * The {@link reserved} type can be used to mark canister method parameters as - * deprecated. Since parameters are identified by position, not name, removing - * a parameter would shift the position of subsequent parameters. - * - * See https://internetcomputer.org/docs/current/references/candid-ref#type-reserved - */ -export type reserved = any; - -/** - * Represents human readable text. Synonymous with the standard `string` type in - * JavaScript. - * - * See https://internetcomputer.org/docs/current/references/candid-ref#type-text - */ -export type text = string; - -/** - * An ordered heterogeneous collection of values. - * - * See https://internetcomputer.org/docs/current/references/candid-ref#type-record--n--t-- - */ -export type Tuple = T; - -/** - * A homogeneous sequence/list/array of values. - * - * See https://internetcomputer.org/docs/current/references/candid-ref#type-vec-t - */ -export type Vec = T[]; diff --git a/src/lib/candid_types/service.ts b/src/lib/candid_types/service.ts deleted file mode 100644 index 564c87a83a..0000000000 --- a/src/lib/candid_types/service.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { nat, nat64, Principal } from './'; -import { ic } from '../ic'; - -/** - * Parent class for creating Service definitions. To create a service extend - * this class. - * @example - * ```ts - * export class SomeOtherCanister extends Service { - * @serviceQuery - * someCanisterMethod: (someParam: SomeParamType) => CallResult; - * } - * ``` - * - * You can then call a method on that canister like this: - * - * ```ts - * const canister = new SomeOtherCanister( - * Principal.fromText('ryjl3-tyaaa-aaaaa-aaaba-cai') - * ); - * - * const result = await canister.someCanisterMethod().call(); - * ``` - */ -export class Service { - canisterId: Principal; - - constructor(canisterId: Principal) { - this.canisterId = canisterId; - } -} - -/** - * A decorator for marking query methods on services. Can only be - * used on class properties with a return type of (args: any[]) => - * CallResult. - * - * @example - * ```ts - * export class SomeOtherCanister extends Service { - * @serviceQuery - * someCanisterMethod: (someParam: SomeParamType) => CallResult; - * } - * ``` - */ -export function serviceQuery(target: any, name: string) { - serviceMethodDecoration(target, name); -} - -/** - * A decorator for marking update methods on services. Can only be - * used on class properties with a return type of (args: any[]) => - * CallResult. - * - * @example - * ```ts - * export class SomeOtherCanister extends Service { - * @serviceUpdate - * someCanisterMethod: (someParam: SomeParamType) => CallResult; - * } - * ``` - */ -export function serviceUpdate(target: any, name: string) { - serviceMethodDecoration(target, name); -} - -function serviceMethodDecoration(target: any, name: string) { - Object.defineProperty(target, name, { - get() { - return (...args: any[]) => { - return { - call: () => { - return (ic as any)[ - `call_${target.constructor.name}_${name}` - ](this.canisterId, args); - }, - notify: () => { - return (ic as any)[ - `notify_${target.constructor.name}_${name}` - ](this.canisterId, args); - }, - cycles: (cycles: nat64) => { - return { - call: () => { - return (ic as any)[ - `call_with_payment_${target.constructor.name}_${name}` - ](this.canisterId, [...args, cycles]); - }, - notify: () => { - // There is no notifyWithPayment, there is only a notifyWithPayment128 - return (ic as any)[ - `notify_with_payment128_${target.constructor.name}_${name}` - ](this.canisterId, args, cycles); - } - }; - }, - cycles128: (cycles: nat) => { - return { - notify: () => { - // There is no notifyWithPayment, there is only a notifyWithPayment128 - return (ic as any)[ - `notify_with_payment128_${target.constructor.name}_${name}` - ](this.canisterId, args, cycles); - }, - call: () => { - return (ic as any)[ - `call_with_payment128_${target.constructor.name}_${name}` - ](this.canisterId, [...args, cycles]); - } - }; - } - }; - }; - } - }); -} diff --git a/src/lib/candid_types/variant.ts b/src/lib/candid_types/variant.ts deleted file mode 100644 index 5330333d7e..0000000000 --- a/src/lib/candid_types/variant.ts +++ /dev/null @@ -1,280 +0,0 @@ -// Some JS docs licensed under https://github.com/dfinity/portal/blob/master/LICENSE -// Some documentation changed from original work. - -// from type-fest -type UnionToIntersection = - // `extends unknown` is always going to be the case and is used to convert the - // `Union` into a [distributive conditional - // type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types). - ( - Union extends unknown - ? // The union type is used as the only argument to a function since the union - // of function arguments is an intersection. - (distributedUnion: Union) => void - : // This won't happen. - never - ) extends // Infer the `Intersection` type since TypeScript represents the positional - // arguments of unions of functions as an intersection of the union. - (mergedIntersection: infer Intersection) => void - ? Intersection - : never; - -// from type-fest -export type RequireExactlyOne< - ObjectType, - KeysType extends keyof ObjectType = keyof ObjectType -> = { - [Key in KeysType]: Required> & - Partial, never>>; -}[KeysType] & - Omit; - -/** - * Represents a value that is from exactly one of the given cases or tags. If a - * tag does not carry data it is idiomatic to use the `null` type. - * - * @example - * ```ts - * type Shape = Variant<{ - * Dot: null, - * Circle: float64, - * Rectangle: Record<{ - * width: float64, - * height: float64 - * }>, - * '💬': string - * }>; - * ``` - * - * See https://internetcomputer.org/docs/current/references/candid-ref#type-variant--n--t-- - */ -export type Variant = RequireExactlyOne; - -type UnVariant = UnionToIntersection< - T extends Variant - ? { - [Prop in keyof Inner as Required[Prop] extends never - ? never - : Prop]: Inner[Prop]; - } - : never ->; - -type Matcher = - | { - [PropName in keyof UnVariant]: (arg: UnVariant[PropName]) => R; - } - | (Partial<{ - [PropName in keyof UnVariant]: (arg: UnVariant[PropName]) => R; - }> & { _: (arg: never) => R }); - -type PropertyValueType = T[keyof T]; - -/** - * Compares a {@link Variant} against its possible tags, finds a match, and - * executes the corresponding handler function - * @param variant the {@link Variant} to be checked - * @param matcher a mapping of {@link Variant} tags to handler functions - * @returns the return value of the matched handler function - * - * @example - * ```ts - * const result: Result = { Ok: 'okValue' }; - * - * const message: string = match(result, { - * Ok: (ok) => `The ok value was ${ok}`, - * Err: (err) => `The error value was ${err}` - * }); - * - * assert.equal(message, 'The ok value was okValue') - * ``` - */ -export function match, T extends object>( - variant: T, - matcher: U -): ReturnType>> { - for (const key in variant) { - if (key in matcher) { - return (matcher as any)[key](variant[key]); - } - } - return (matcher as any)._(); -} - -// export function match_async, T extends object>( -// variant: T, -// matcher: U -// ): Promise>>> { -// return match(variant, matcher); -// } - -// type Variant = Partial; - -// function matchVariant( -// variant: Variant, -// handlers: Record void> -// ) { -// const handledKeys = new Set(); - -// for (const key in variant) { -// if (handlers.hasOwnProperty(key)) { -// const handler = handlers[key]; -// handler(variant[key] as T[keyof T]); -// handledKeys.add(key); -// } else { -// throw new Error(`Unhandled variant member: ${key}`); -// } -// } - -// const unhandledKeys = Object.keys(handlers).filter( -// (key) => !handledKeys.has(key) -// ); -// if (unhandledKeys.length > 0) { -// throw new Error( -// `Variant members not handled: ${unhandledKeys.join(', ')}` -// ); -// } -// } - -// type Matcher = { -// [K in keyof T]: (value: V extends T[K] ? T[K] : never) => R; -// } & { -// _: () => R; -// }; - -// function match( -// value: Variant, -// matcher: Matcher -// ): R { -// const key = Object.keys(value)[0] as keyof T; -// const matchFunc = matcher[key] || matcher._; -// return matchFunc(value[key]); -// } - -// TODO check that it works with returns records and variants -// TODO check that it works with all candid types - -// type Matcher = { -// [K in keyof T]: (value: Parameters[0]) => R; -// } & { -// _: () => R; -// }; - -// type Variant = { -// [K in keyof T]: { -// K: T[K]; -// }; -// }; - -// TODO require exactly one for Variant -// TODO matcher function parameters to be inferred -// TODO _ required only if all Variant properties are not present -// TODO matcher functions must be able to return Variants -// TODO Variant.PropertyName to work - -// type RequireExactlyOne< -// ObjectType, -// KeysType extends keyof ObjectType = keyof ObjectType -// > = { -// [Key in KeysType]: Required> & -// Partial, never>>; -// }[KeysType] & -// Omit; - -// type Variant = RequireExactlyOne; - -// type FullMatcher = { -// [K in keyof Required]: (value: Required[K]) => R; -// }; - -// type PartialMatcher = Partial<{ -// [K in keyof T]: (value: T[K]) => R; -// }> & { -// _: () => R; -// }; - -// function match< -// T extends object, -// U extends FullMatcher | PartialMatcher, -// R -// >(variant: T, matcher: U): R { -// for (const key in variant) { -// if (key in matcher) { -// return (matcher as any)[key](variant[key]); -// } -// } -// return matcher._(); -// } - -// type Monkey = Variant<{ -// Hello: null; -// There: null; -// Sir: null; -// }>; - -// function test1(monkey: Monkey): string { -// // const temp = monkey.Hello; - -// return match(monkey, { -// Hello: (hello) => '', -// There: (there) => '', -// Sir: (sir) => '' -// }); -// } - -// type Result = Variant<{ -// Ok: null; -// Err: string; -// }>; - -// const thing: Result = { -// Ok: null -// // Err: '' -// }; - -// function Brancher(): { -// [K in keyof NonNullable]: (value: NonNullable[K]) => { -// [key in K]: NonNullable; -// }; -// } { -// return {}; -// } - -// type Lunky = { -// Yes: null; -// I: boolean; -// Know: number; -// }; - -// const temp = Brancher().Hello(null); - -// function test2(monkey: Monkey): Result { -// // const temp = monkey.Hello; - -// const matched_value = match(monkey, { -// Hello: (hello) => ({ -// // Ok: null, -// Err: '' -// }), -// There: (there) => ({ -// Ok: null -// }), -// _: () => ({ -// Err: '' -// }) -// }); - -// return matched_value; - -// // return match(monkey, { -// // Hello: (hello) => ({ -// // Ok: null -// // }), -// // There: (there) => ({ -// // Ok: null -// // }), -// // _: () => ({ -// // Err: '' -// // }) -// // }); -// } diff --git a/src/lib/ic.ts b/src/lib/ic.ts deleted file mode 100644 index 5a80655427..0000000000 --- a/src/lib/ic.ts +++ /dev/null @@ -1,471 +0,0 @@ -// Some JS docs licensed under https://github.com/dfinity/cdk-rs/blob/main/LICENSE -// Some documentation changed from original work. - -import { Manual } from './'; -import { - $init, - $inspectMessage, - $query, - $preUpgrade, - $postUpgrade, - $update -} from './annotations'; -import { - blob, - nat32, - nat64, - nat, - Opt, - Principal, - Variant -} from './candid_types'; -import { Result } from './results'; - -declare var globalThis: any; - -/** - * Represents a duration of time in seconds. - */ -export type Duration = nat64; // TODO: Consider modeling this after the corresponding struct in Rust - -export type NotifyResult = Result; - -/** - * Indicates an error was encountered during a canister method. - */ -export type RejectionCode = Variant<{ - NoError: null; - SysFatal: null; - SysTransient: null; - DestinationInvalid: null; - CanisterReject: null; - CanisterError: null; - Unknown: null; -}>; - -export type Stable64GrowResult = Result; - -export type StableGrowResult = Result; - -/** Indicates an error occurred when dealing with stable memory */ -export type StableMemoryError = Variant<{ - /** No more stable memory could be allocated */ - OutOfMemory: null; - /** Attempted to read more stable memory than had been allocated */ - OutOfBounds: null; -}>; - -/** - * Type returned by the {@link ic.setTimer} and {@link ic.setTimerInterval} - * functions. Pass to {@link ic.clearTimer} to remove the timer. - */ -export type TimerId = nat64; // TODO: Consider modeling this after the corresponding struct in Rust - -type ic = { - /** - * Accepts the ingress message. Calling from outside the - * {@link $inspectMessage} context will cause the canister to trap. - */ - acceptMessage: () => void; - - // argData: () => any[]; // TODO: See https://github.com/demergent-labs/azle/issues/496 - - /** - * Returns the argument data as bytes. - * @returns the argument data - */ - argDataRaw: () => blob; - - /** - * Gets the length of the raw-argument-data-bytes - * @returns the data size - */ - argDataRawSize: () => nat32; - - /** - * Performs an asynchronous call to another canister using the [System API]( - * https://internetcomputer.org/docs/current/references/ic-interface-spec/#system-api-call) - * and returns the payload without serialization - * @param canisterId the principal of the canister to call - * @param method the method to call - * @param argsRaw the args to pass to the canister method - * @param payment the number of cycles to send with the call - * @returns - */ - callRaw: ( - canisterId: Principal, - method: string, - argsRaw: blob, - payment: nat64 - ) => Promise>; - - /** - * Performs an asynchronous call to another canister using the [System API]( - * https://internetcomputer.org/docs/current/references/ic-interface-spec/#system-api-call) - * and returns the payload without serialization - * @param canisterId the principal of the canister to call - * @param method the method to call - * @param argsRaw the args to pass to the canister method - * @param payment the number of cycles to send with the call - * @returns - */ - callRaw128: ( - canisterId: Principal, - method: string, - argsRaw: blob, - payment: nat - ) => Promise>; - - /** - * Returns the caller of the current call - * @returns the caller of the current call - */ - caller: () => Principal; - - /** - * Converts a candid value into a Candid string - * @param candidEncoded a raw Candid value - * @returns the Candid string - */ - candidDecode: (candidEncoded: blob) => string; - - /** - * Converts a Candid string into bytes - * @param candidString a valid Candid string - * @returns the candid value as bytes - */ - candidEncode: (candidString: string) => blob; - - canisters: { - [canisterName: string]: (canisterId: Principal) => T; - }; - - /** - * Gets the amount of funds available in the canister - * @returns the number of cycles in the canister - */ - canisterBalance: () => nat64; - - /** - * Gets the amount of funds available in the canister - * @returns the number of cycles in the canister - */ - canisterBalance128: () => nat; - - /** - * Returns the canister version number - * - * @returns the version number - */ - canisterVersion: () => nat64; - - /** - * Cancels an existing timer. Does nothing if the timer has already been canceled. - * @param id The ID of the timer to be cancelled. - */ - clearTimer: (id: TimerId) => void; - - /** - * When called from a query call, returns the data certificate - * authenticating `certifiedData` set by this canister. Returns `None` if - * called from a query call. - * @returns the data certificate or None - */ - dataCertificate: () => Opt; - - /** - * Gets the id of this canister - * @returns the canister id - */ - id: () => Principal; - - /** - * Returns the number of instructions that the canister executed since the - * last [entry point]( - * https://internetcomputer.org/docs/current/references/ic-interface-spec/#entry-points - * ) - * - * @returns the number of instructions - */ - instructionCounter: () => nat64; - - /** Determine if a {@link Principal} is a controller of the canister. */ - isController: (principal: Principal) => boolean; - - /** - * Returns the name of the current canister methods - * @returns the current canister method - */ - methodName: () => string; - - /** - * Moves cycles from the call to the canister balance - * @param maxAmount the max amount of cycles to move - * @returns the actual amount moved - */ - msgCyclesAccept: (maxAmount: nat64) => nat64; - - /** - * Moves cycles from the call to the canister balance - * @param maxAmount the max amount of cycles to move - * @returns the actual amount moved - */ - msgCyclesAccept128: (maxAmount: nat) => nat; - - /** - * Returns the amount of cycles that were transferred by the caller of the - * current call, and is still available in this message - * @returns the amount of cycles - */ - msgCyclesAvailable: () => nat64; - - /** - * Returns the amount of cycles that were transferred by the caller of the - * current call, and is still available in this message - * @returns the amount of cycles - */ - msgCyclesAvailable128: () => nat; - - /** - * Returns the amount of cycles that came back with the response as a refund. - * The refund has already been added to the canister balance automatically. - * @returns the amount of cycles - */ - msgCyclesRefunded: () => nat64; - - /** - * Returns the amount of cycles that came back with the response as a refund. - * The refund has already been added to the canister balance automatically. - * @returns the amount of cycles - */ - msgCyclesRefunded128: () => nat; - - notifyRaw: ( - canisterId: Principal, - method: string, - argsRaw: blob, - payment: nat - ) => NotifyResult; - - /** - * Gets the value of the specified performance counter - * - * @param counterType the type of performance counter to use. Currently `0` - * (instruction counter) is the only supported type. It returns the number - * of WebAssembly instructions the system has determined that the canister - * has executed. - * @returns the performance counter metric - */ - performanceCounter: (counterType: nat32) => nat64; - - /** - * Prints the given message - * @param args the message to print - */ - print: (...args: any) => void; - - /** - * Rejects the current call with the provided message - * @param message the rejection message - */ - reject: (message: string) => void; - - /** - * Returns the rejection code from the most recently executed cross-canister - * call - * @returns the rejection code - */ - rejectCode: () => RejectionCode; - - /** - * Returns the rejection message from the most recently executed - * cross-canister call - * - * **Warning**: Traps if there is no reject message. It is recommended to - * check {@link ic.rejectCode} first. - * - * @returns the rejection message - */ - rejectMessage: () => string; - - /** - * Used to manually reply to an ingress message. Intended to be used in - * canister methods with a {@link Manual} return type. - * @param reply the value with which to reply. Must by of type `T` where `T` - * is the generic type supplied to `Manual`. Otherwise will result in an - * uncaught `TypeError`. - */ - reply: (reply: any) => void; - - /** - * Used to manually reply to an ingress message. Intended to be used in - * canister methods with a {@link Manual} return type. - * @param buf the value with which to reply. Intended to be used in conjunction with - * {@link ic.candidEncode}. - * @example - * ```ts - * $update; - * export function replyRaw(): Manual { - * ic.replyRaw( - * ic.candidEncode( - * '(record { "int" = 42; "text" = "text"; "bool" = true; "blob" = blob "raw bytes"; "variant" = variant { Medium } })' - * ) - * ); - * } - * ``` - */ - replyRaw: (buf: blob) => void; - - /** - * Sets the certified data of this canister. - * - * Canisters can store up to 32 bytes of data that is certified by the - * system on a regular basis. One can call {@link ic.dataCertificate} from a - * {@link $query} call to get a certificate authenticating the value set by - * calling this function. - - * This function can only be called from the following contexts: - * - * - {@link $init}, {@link $preUpgrade} and {@link $postUpgrade} hooks - * - {@link $update} calls - * - reply or reject callbacks - * - * This function traps if: - * - * - `data.length` > 32 - * - called from an illegal context (e.g. from a {@link $query} call) - * - * @param data the data to be set - * @returns - */ - setCertifiedData: (data: blob) => void; - - /** - * Sets callback to be executed later, after delay. Panics if `delay` + time() is more than 2^64 - 1. - * To cancel the timer before it executes, pass the returned `TimerId` to `clearTimer`. - * Note that timers are not persisted across canister upgrades. - * - * @param delay The time (in seconds) to wait before executing the provided callback. - * @param callback the function to invoke after the specified delay has passed. - * @returns the ID of the created timer. Used to cancel the timer. - */ - setTimer: ( - delay: Duration, - callback: () => void | Promise - ) => TimerId; - - /** - * Sets callback to be executed every interval. Panics if `interval` + time() is more than 2^64 - 1. - * To cancel the interval timer, pass the returned `TimerId` to `clearTimer`. - * Note that timers are not persisted across canister upgrades. - * - * @param interval The interval (in seconds) between each callback execution. - * @param callback the function to invoke after the specified delay has passed. - * @returns the ID of the created timer. Used to cancel the timer. - */ - setTimerInterval: ( - interval: Duration, - callback: () => void | Promise - ) => TimerId; - - /** - * Gets a copy of stable memory - * - * **Note:** This will map the whole memory, even if not all of it has - * been written to. - * @returns a copy of the stable memory - */ - stableBytes: () => blob; - - /** - * Attempts to grow the stable memory by `newPages` (added pages) - * - * **Note:** Pages are 64KiB in WASM - * - * @param newPages the number of pages to add - * @returns an error if it wasn't able to grow. Otherwise, returns the - * previous size that was reserved. - */ - stableGrow: (newPages: nat32) => StableGrowResult; - - /** - * Reads data from the stable memory location specified by an offset - * @param offset the location from which to read - * @param length the length of buffer to read - * @returns the raw bytes in stable memory - */ - stableRead: (offset: nat32, length: nat32) => blob; - - /** - * Gets current size of the stable memory (in WASM pages) - * @returns the current memory size - */ - stableSize: () => nat32; - - /** - * Writes data to the stable memory location specified by an offset - * - * **Warning:** this will panic if `offset` + `buffer.length` exceeds the - * current size of stable memory. Use {@link ic.stableGrow} to request more - * stable memory if needed. - * @param offset the location at which to write - * @param buffer the data to write - */ - stableWrite: (offset: nat32, buffer: blob) => void; - - /** - * Attempts to grow the stable memory by `newPages` (added pages). Supports - * 64-bit addressed memory. - * - * **Note:** Pages are 64KiB in WASM - * - * @param newPages the number of pages to add - * @returns an error if it wasn't able to grow. Otherwise, returns the - * previous size that was reserved. - */ - stable64Grow: (newPages: nat64) => Stable64GrowResult; - - /** - * Reads data from the stable memory location specified by an offset. - * Supports 64-bit addressed memory. - * @param offset the location from which to read - * @param length the length of buffer to read - * @returns the raw bytes in stable memory - */ - stable64Read: (offset: nat64, length: nat64) => blob; - - /** - * Gets current size of the stable memory (in WASM pages). Supports 64-bit - * addressed memory. - * @returns the current memory size - */ - stable64Size: () => nat64; - - /** - * Writes data to the stable memory location specified by an offset. - * Supports 64-bit addressed memory. - * - * **Warning:** this will panic if `offset` + `buffer.length` exceeds the - * current size of stable memory. Use {@link ic.stable64Grow} to request - * more stable memory if needed. - * @param offset the location at which to write - * @param buffer the data to write - */ - stable64Write: (offset: nat64, buffer: blob) => void; - - /** - * Gets current timestamp, in nanoseconds since the epoch (1970-01-01) - * @returns the current timestamp - */ - time: () => nat64; - - /** - * Stops execution and rejects the current request with a `CANISTER_ERROR` - * (5) rejection code and the provided message - * @param message the rejection message - */ - trap: (message: string) => never; -}; - -/** API entrypoint for interacting with the Internet Computer */ -export const ic: ic = globalThis.ic ?? {}; diff --git a/src/lib/index.ts b/src/lib/index.ts deleted file mode 100644 index 6419908d98..0000000000 --- a/src/lib/index.ts +++ /dev/null @@ -1,62 +0,0 @@ -export { - $heartbeat, - $init, - $inspectMessage, - $postUpgrade, - $preUpgrade, - $query, - $update, - CanisterMethodOptions -} from './annotations'; -export { - Duration, - ic, - NotifyResult, - RejectionCode, - Stable64GrowResult, - StableGrowResult, - StableMemoryError, - TimerId -} from './ic'; -export { - blob, - empty, - float32, - float64, - Func, - int, - int16, - int32, - int64, - int8, - nat, - nat16, - nat32, - nat64, - nat8, - Opt, - Principal, - Record, - reserved, - Service, - text, - Tuple, - Variant, - Vec -} from './candid_types'; -export { Oneway, Query, Update, FuncSignature } from './candid_types/func'; -export { match } from './candid_types/variant'; -export { serviceQuery, serviceUpdate } from './candid_types/service'; -export { CallResult, GuardResult, Result } from './results'; -export { StableBTreeMap } from './stable_b_tree_map'; - -export type Manual = void; - -export function registerPlugin(props: { - globalObjectName?: string; - rustRegisterFunctionName: string; -}) { - if (props.globalObjectName !== undefined) { - return (globalThis as any)[props.globalObjectName] ?? {}; - } -} diff --git a/src/lib/results.ts b/src/lib/results.ts deleted file mode 100644 index 5eaa05ff47..0000000000 --- a/src/lib/results.ts +++ /dev/null @@ -1,100 +0,0 @@ -// Some JS docs licensed under: -// -// - https://github.com/dfinity/cdk-rs/blob/main/LICENSE -// - https://github.com/dfinity/interface-spec/blob/master/LICENSE -// - https://github.com/dfinity/portal/blob/master/LICENSE -// -// Some documentation changed from original work. - -import { NotifyResult } from './ic'; -import { Variant, nat64, nat, Service } from './candid_types'; - -/** - * Represents either success (`Ok`) or failure (`Err`) - * - * @typeParam Ok - The type of the success value - * @typeParam Err - The type of the error value - */ -export type Result = Variant<{ - /** The success value */ - Ok: Ok; - /** The error value */ - Err: Err; -}>; - -export const Result = { - /** - * Wraps the provided value in an `Ok` {@link Result} - * @param value - the success value to be wrapped - * @returns a successful {@link Result} containing the provided value - */ - Ok: (value: Ok): Result => ({ - Ok: value - }), - /** - * Wraps the provided value in an `Err` {@link Result} - * @param value - the error value to be wrapped - * @returns an error {@link Result} containing the provided value - */ - Err: (value: Err): Result => ({ - Err: value - }) -}; - -/** - * An execution context for configuring {@link Service} method calls. - * - * Each service method call can await a result ({@link CallResult.call}) or can - * be sent without awaiting a response ({@link CallResult.notify}). - * - * To send cycles with your request first chain either {@link CallResult.cycles} - * or {@link CallResult.cycles128}. - */ -export type CallResult = { - /** - * Dispatches an asynchronous {@link Service} method call and returns a - * response. If sending cycles, make sure to call {@link CallResult.cycles} - * or {@link CallResult.cycles128} first. - * - * @returns A promise with a result containing the service method return - * value or an error message - */ - call: () => Promise>; - /** - * Dispatches an asynchronous {@link Service} method call without returning - * a response. If sending cycles, make sure to call - * {@link CallResult.cycles} or {@link CallResult.cycles128} first. - * - * @returns a result indicating whether the call was successfully enqueued, - * otherwise a reject code - */ - notify: () => NotifyResult; - /** - * Specifies the number of cycles to send with the {@link Service} method - * call. Must be <= 18_446_744_073_709_551_615 (2^64 - 1). For sending 2^64 - * cycles or more use {@link CallResult.cycles128}. - * - * @param cycles - the number of cycles to send with the call - * @returns a new {@link CallResult} instance with the provided cycle amount - * stored - */ - cycles: (cycles: nat64) => CallResult; - /** - * Specifies the number of cycles to send with the {@link Service} method - * call. Must be <= 340_282_366_920_938_463_463_374_607_431_768_211_455 - * (2^128 - 1). For sending fewer than 2^64 cycles use - * {@link CallResult.cycles} instead. - * - * @param cycles - the number of cycles to send with the call - * @returns the {@link CallResult} instance with the provided cycle amount - * stored - */ - cycles128: (cycles: nat) => CallResult; -}; - -/** - * The required return type of guard functions. Indicates whether the guarded - * function should halt or proceed. Functionally equivalent to - * `Result`. - */ -export type GuardResult = Result; diff --git a/src/lib/stable_b_tree_map.ts b/src/lib/stable_b_tree_map.ts deleted file mode 100644 index c71c092947..0000000000 --- a/src/lib/stable_b_tree_map.ts +++ /dev/null @@ -1,132 +0,0 @@ -// Some JS docs licensed under https://github.com/dfinity/stable-structures/blob/main/LICENSE -// Some documentation changed from original work. - -import { ic, nat8, nat32, nat64, Opt } from './index'; - -/** - * A Map based on a self-balancing tree that persists across - * canister upgrades. - */ -export class StableBTreeMap { - memoryId: nat8; - - /** - * Creates a new StableBTreeMap object. - * @param memoryId the memory id at which to instantiate this map. - * @param maxKeySize the largest size (in bytes) a key can be. - * @param maxValueSize the largest size (in bytes) a value can be. - */ - constructor(memoryId: nat8, maxKeySize: nat32, maxValueSize: nat32) { - this.memoryId = memoryId; - - // Note: Although maxKeySize and maxValueSize aren't used here, they - // are read by Azle at compilation time and are necessary to properly - // initialize the StableBTreeMap. - } - - /** - * Checks if the given key exists in the map. - * @param key the key to check. - * @returns `true` if the key exists in the map, `false` otherwise. - */ - containsKey(key: Key): boolean { - if (arguments.length === 0) { - throw new Error("An argument for 'key' was not provided"); - } - - // @ts-ignore - return ic.stableBTreeMapContainsKey(this.memoryId, key); - } - - /** - * Retrieves the value stored at the provided key. - * @param key the location from which to retrieve. - * @returns the value associated with the given key, if it exists. - */ - get(key: Key): Opt { - if (arguments.length === 0) { - throw new Error("An argument for 'key' was not provided"); - } - - // @ts-ignore - return ic.stableBTreeMapGet(this.memoryId, key); - } - - /** - * Inserts a value into the map at the provided key. - * @param key the location at which to insert. - * @param value the value to insert. - * @returns the previous value of the key, if present. - */ - insert(key: Key, value: Value): Opt { - if (arguments.length === 0) { - throw new Error("An argument for 'key' was not provided"); - } - - if (arguments.length === 1) { - throw new Error("An argument for 'value' was not provided"); - } - - // @ts-ignore - return ic.stableBTreeMapInsert(this.memoryId, key, value); - } - - /** - * Checks if the map is empty. - * @returns `true` if the map contains no elements, `false` otherwise. - */ - isEmpty(): boolean { - // @ts-ignore - return ic.stableBTreeMapIsEmpty(this.memoryId); - } - - /** - * Retrieves the items in the map in sorted order. - * @returns tuples representing key/value pairs. - */ - items(): [Key, Value][] { - // @ts-ignore - return ic.stableBTreeMapItems(this.memoryId); - } - - /** - * The keys for each element in the map in sorted order. - * @returns they keys in the map. - */ - keys(): Key[] { - // @ts-ignore - return ic.stableBTreeMapKeys(this.memoryId); - } - - /** - * Checks to see how many elements are in the map. - * @returns the number of elements in the map. - */ - len(): nat64 { - // @ts-ignore - return ic.stableBTreeMapLen(this.memoryId); - } - - /** - * Removes a key from the map. - * @param key the location from which to remove. - * @returns the previous value at the key if it exists, `null` otherwise. - */ - remove(key: Key): Opt { - if (arguments.length === 0) { - throw new Error("An argument for 'key' was not provided"); - } - - // @ts-ignore - return ic.stableBTreeMapRemove(this.memoryId, key); - } - - /** - * The values in the map in sorted order. - * @returns the values in the map. - */ - values(): Value[] { - // @ts-ignore - return ic.stableBTreeMapValues(this.memoryId); - } -}