Skip to content
This repository has been archived by the owner on Oct 17, 2022. It is now read-only.
/ nestjs-terra Public archive

Terra blockchain utilities for NestJS based on Terra.js

License

Notifications You must be signed in to change notification settings

0xslipk/nestjs-terra

Repository files navigation

NestJS-Terra

npm CircleCI Coverage Status vulnerabilities supported platforms

Terra blockchain utilities for NestJS based on Terra.js

Install

npm i nestjs-terra

Register module

Configuration params

nestjs-terra can be configured with this options:

interface TerraModuleOptions {
  /**
   * The base URL to wich Light Client Daemon (LCD) requests will be made.
   * For example: https://lcd.terra.dev
   */
  URL: string;

  /**
   * Chain ID of the blockchain to connect to.
   * For example:
   *  - columbus-5: Mainnet
   *  - tequila-0004: Testnet
   *  - bombay-9: Testnet
   */
  chainID: string;

  /**
   * Optional parameter for gas prices to use for fee estimation.
   */
  gasPrices?: Coins.Input;

  /**
   * Optional parameter for gas adjustment value to use for fee estimation.
   */
  gasAdjustment?: Numeric.Input;
}

Synchronous configuration

Use TerraModule.forRoot method with Options interface:

import {
  TerraModule,
  MAINNET_LCD_BASE_URL,
  MAINNET_CHAIN_ID
} from 'nestjs-terra';

@Module({
  imports: [
    TerraModule.forRoot({
      URL: MAINNET_LCD_BASE_URL,
      chainID: MAINNET_CHAIN_ID,
    })
  ],
  ...
})
class MyModule {}

Asynchronous configuration

With TerraModule.forRootAsync you can, for example, import your ConfigModule and inject ConfigService to use it in useFactory method.

useFactory should return object with Options interface

Here's an example:

import {
  TerraModule,
  MAINNET_LCD_BASE_URL,
  MAINNET_CHAIN_ID
} from 'nestjs-terra';

@Injectable()
class ConfigService {
  public readonly URL = MAINNET_LCD_BASE_URL;
  public readonly chainID = MAINNET_CHAIN_ID;
}

@Module({
  providers: [ConfigService],
  exports: [ConfigService]
})
class ConfigModule {}

@Module({
  imports: [
    TerraModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (config: ConfigService) => {
        await somePromise();
        return {
          URL: config.URL,
          chainID: config.chainID,
        };
      }
    })
  ],
  ...
})
class MyModule {}

Or you can just pass ConfigService to providers, if you don't have any ConfigModule:

import {
  TerraModule,
  MAINNET_LCD_BASE_URL,
  MAINNET_CHAIN_ID,
} from 'nestjs-terra';

@Injectable()
class ConfigService {
  public readonly URL = MAINNET_LCD_BASE_URL;
  public readonly chainID = MAINNET_CHAIN_ID;
}

@Module({
  imports: [
    TerraModule.forRootAsync({
      providers: [ConfigService],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => {
        return {
          URL: config.URL,
          chainID: config.chainID,
        };
      }
    })
  ],
  controllers: [TestController]
})
class MyModule {}

LCDClient

if you are familiar with LCDClient, you are ready to go.

import { InjectLCDClient, LCDClient, MnemonicKey } from 'nestjs-terra';

@Injectable()
export class TestService {
  constructor(
    @InjectLCDClient()
    private readonly terraClient: LCDClient,
  ) {}
  async someMethod(): Promise<{ accountNumber: string }> {
    const wallet = this.terraClient.wallet(
      new MnemonicKey({
        mnemonic: [
          'satisfy',
          'adjust',
          'timber',
          'high',
          'purchase',
          'tuition',
          'stool',
          'faith',
          'fine',
          'install',
          'that',
          'you',
          'unaware',
          'feed',
          'domain',
          'license',
          'impose',
          'boss',
          'human',
          'eager',
          'hat',
          'rent',
          'enjoy',
          'dawn',
        ].join(' ')
      }),
    );
    const accountNumber = await wallet.accountNumber();

    return { accountNumber: accountNumber.toString() };
  }
}

Testing a class that uses @InjectLCDClient

This package exposes a getTerraToken() function that returns a prepared injection token based on the provided context. Using this token, you can easily provide a mock implementation of the LCDClient using any of the standard custom provider techniques, including useClass, useValue, and useFactory.

  const module: TestingModule = await Test.createTestingModule({
    providers: [
      MyService,
      {
        provide: getTerraToken(),
        useValue: mockProvider,
      },
    ],
  }).compile();

Change Log

See Changelog for more information.

Contributing

Contributions welcome! See Contributing.

Author

Jose Ramirez Twitter

License

Licensed under the Apache 2.0 - see the LICENSE file for details.