Reducers

Module-to-module interactions are done via reducers.

Reducers are functions in modules which can be invoked via Remote-Procedure-Calls (RPC) by other modules.

Reducers have access to the state store.

Modules and Assets can invoke reducers through the reducerHandler.

Example: Reducers of the Token module
public reducers = {
    // Credit tokens to an account
    credit: async (params: Record<string, unknown>, stateStore: StateStore): Promise<void> => {
        const { address, amount } = params;
        if (!Buffer.isBuffer(address)) {
            throw new Error('Address must be a buffer');
        }
        if (typeof amount !== 'bigint') {
            throw new Error('Amount must be a bigint');
        }
        if (amount <= BigInt(0)) {
            throw new Error('Amount must be a positive bigint.');
        }
        const account = await stateStore.account.getOrDefault<TokenAccount>(address);
        account.token.balance += amount;
        if (account.token.balance < this._minRemainingBalance) {
            throw new Error(
                `Remaining balance must be greater than ${this._minRemainingBalance.toString()}`,
            );
        }
        await stateStore.account.set(address, account);
    },
    // Debit tokens from an account
    debit: async (params: Record<string, unknown>, stateStore: StateStore): Promise<void> => {
        const { address, amount } = params;
        if (!Buffer.isBuffer(address)) {
            throw new Error('Address must be a buffer');
        }
        if (typeof amount !== 'bigint') {
            throw new Error('Amount must be a bigint');
        }
        if (amount <= BigInt(0)) {
            throw new Error('Amount must be a positive bigint.');
        }
        const account = await stateStore.account.getOrDefault<TokenAccount>(address);
        account.token.balance -= amount;
        if (account.token.balance < this._minRemainingBalance) {
            throw new Error(
                `Remaining balance must be greater than ${this._minRemainingBalance.toString()}`,
            );
        }
        await stateStore.account.set(address, account);
    },
    // Get the balance of an specific account
    getBalance: async (
        params: Record<string, unknown>,
        stateStore: StateStore,
    ): Promise<bigint> => {
        const { address } = params;
        if (!Buffer.isBuffer(address)) {
            throw new Error('Address must be a buffer');
        }
        const account = await stateStore.account.getOrDefault<TokenAccount>(address);
        return account.token.balance;
    },
    // Returns the minimum remaining balance for accounts
    getMinRemainingBalance: async (): Promise<bigint> => this._minRemainingBalance,
};

reducerHandler

Used to call reducers of other modules.

Reducers of modules can be invoked inside of the lifecycle-hooks and assets of other modules via the reducerHandler.

Example: Invoking the "debit" reducer of the Token module
// debit tokens from sender account
await reducerHandler.invoke("token:debit", {
  address: senderAddress,
  amount: asset.initValue,
});