SDK 開発

SDK の最初のグループを構築するときに私たちが持っていた主な目的の 1 つは、開発者がまったく異なる設計に適応することなく、プログラミング言語間で迅速に変更できるようにすることでした。このドキュメントは相互運用性を実現するために、同じ設計を共有する Symbol ベースの SDK を出荷するように開発者をガイドすることを目的としています。

アーキテクチャ

パッケージ構成

../_images/sdk-architecture.png

パッケージ構成ダイアグラム

インフラストラクチャ

このパッケージには生成された API クライアントと DTO が含まれています。HTTP リクエストはリポジトリパターンに則しており、これらはオブザーバルパターンを介して Symbol の変更不可なモデルを返します。

モデル

Symbol ドメインモデルは定義によっては不変ですが、開発者はその属性を変更できません。代わりに、開発者は新しいトランザクションを作成して TransactionHTTP 経由でブロックチェーンへ送信する必要があります。

サービス

複数の REST API リクエストを結合する必要がある一般的な操作

特徴

  • 標準化された契約: データモデルの相互運用性と調和を保証する。
  • 疎結合: コンポーネントの結合度合いを取り除く。
  • 抽象化: 相互運用性の長期的な一貫性を高め、基礎となるコンポーネントを独立して進化させる。
  • 再利用性: モジュールとコンポーネント利用者間での高いレベルの相互運用性。
  • ステートレス: コンポーネントの可用性と拡張性を高め、より頻繁で信頼できる相互運用を可能にします。
  • 合成性: 効果的なコンポーネントの構成のために、相互運用可能でなければなりません。

リアクティブ

Symbol SDK は ReactiveX Library ライブラリを多用しています。

リアクティブアプローチを使用する利点は次のとおりです:

  • 機能性: 開発者はオブザーバブルなストリームにクリーンな入出力関数を使用して、複雑でステートフルなプログラムを避けることができます。
  • 少ない事で多くの事を: 大抵の場合、ReactiveX オペレータは複雑なコードを数行のコードへ還元します。
  • 非同期的エラーハンドリング: 伝統的な try/catch は非同期処理でのエラー処理には非力ですが、ReactiveX はエラーを処理するための適切なツールを開発者に提供します。
  • 並列処理: ReactiveX のオブザーバブルとスケジューラは、プログラマへの低水準のスレッディング、同期、並行処理の実装を抽象化することができます。
  • フロントエンド: Web上で RxJS を使用したUIイベントとAPI応答の操作。
  • バックエンド: ReactiveX の非同期性を利用し、同時性と実装の独立性を可能にします。

リアクティブプログラミングを初めて使用する場合は、オンラインガイド Learn RxJS から始めることをお勧めします。

始める前に

  1. Symbol ビルドイン機能 に詳しくなるためにはテクニカルドキュメントを見てください。
  2. Symbol の ローカル環境を Docker で セットアップします。
  3. API リファレンス を確認して、エンドポイントを実行してみてください。
  4. 現在の SDK のコード例CLI に詳しくなる。
  5. Join our Slack to ask Symbol related questions.
  6. 作成しようとしている SDK にまだ誰も取り組んでいないことを確認してください。リポジトリリスト をチェックし #sig-api チャンネルであなたの意向をコメントしてください。
  7. このリポジトリをフォークしている そのSDK を要求して リポジトリリスト に新しいエントリを追加してください。

プロジェクトの作成

You can base your work on the TypeScript SDK. The TypeScript version is the first SDK getting the latest updates. Check regularly the Changelog to be sure you didn’t miss any code change update.

可能であれば GitHub で新しいリポジトリを作成します:

  1. SDK のインストール手順の README
  2. Code of Conduct
  3. The Contributors guidelines to help others know how they can help you.

テスト

良好なテストカバレッジのプロジェクトは開発者にとって、より信頼のおけるものとなるでしょう。

We strongly suggest to do Test-Driven Development or Unit-Testing (test last). If you need inspiration, feel free to adapt directly the same tests we did.

Once you have written some tests, setup a Continuous Integration (CI) system to run the test suite and code linter automatically. We use travis-ci, but feel free to use the one that suits you best.

Also, we strive to keep our codebases with a unit test coverage of 80% or higher. We use coveralls to monitor test coverage.

インフラストラクチャ

The OpenAPI Generator handles the API and DTOs generation. It supports multiple languages, and hopefully, yours is on the list.

These are the steps we followed to generate the Typescript DTOs (data transfer objects):

  1. Download the latest Symbol OpenAPI spec from GitHub releases.
  2. OpenAPI ジェネレータ CLI のインストール
  1. 選択したプログラミング言語向けの DTO を生成する。
openapi-generator generate -i ./openapi3.yml -g typescript-node -o ./symbol-ts-sdk/ && rm -R symbol-ts-sdk/test
  1. The generated lib is normally published into a central repository (e.g. maven, npm). The SDKs depend on those libraries like any other third party dependency. To automate the deployment of the packages, including the generator for the selected programming language in the symbol-openapi-generator project.
  2. Drop the generated client classes and implement them using the Repository pattern returning Observables of ReactiveX.

注釈

The SDK for TypeScript currently chooses the typescript-node template from the OpenAPI Generator, but there are also other templates available to fit for other purposes. The SDK has interfaced out all the Http Repositories so that different implementations can be applied.

リポジトリ実装の例:

See the complete list of repositories and implementations.

  1. The repositories return models instead of DTOs. You will need to code the models before finishing the API wrapper.

モデル

By default, models are immutable and aim to hide the complexity, like type conversion or relationship between objects.

モデル実装の例:

See the complete list of models.

You will find in the implementations different invariants to ensure the object is well constructed and a nicer API is published.

Particular decisions we considered:

  • UInt64 support: While Java supports big numbers, for example, JavaScript doesn’t. The JavaScript SDK has a custom class to handle the uint64 types. If your language supports uint64, use that implementation instead.
  • API 変換: API によって返されるデータは圧縮される場合があります。ユーザーのこれらのタイプを変換する必要がある場合があります。
  • Namespace id: At creation time you add the string name, but when you receive the Namespace from the network, it comes in formatted as uint64 id. A specific endpoint returns the Namespace string name.

トランザクションのシリアル化

catbuffer ライブラリ は Symbol のエンティティをシリアライズ/デシリアライズするプロトコルを定義します。

In combination with the catbuffer-generators project, developers can generate builder classes for a given set of programming languages. For example, the Symbol SDK uses the generated code to operate with the entities in binary form.

注釈

If there is no generator for the programming language selected, you will need to develop it first. You can base your work on the generator for TypeScript.

If there is a generator, follow the next steps to generate the builders for all the existent entities:

  1. Clone the catbuffer-generators repository recursively.
git clone --recursive git@github.com:nemtech/catbuffer-generators.git
  1. 必須パッケージをインストール
pip install -r requirements.txt
  1. Clone the catbuffer repository inside the catbuffer-generators folder.
  2. Generate code for all the schemas running the following command under the catbuffer-generators directory, replacing cpp_builder for the targeted programming language.
python scripts/generate_all.sh cpp_builder

The previous command creates a new file for every schema under the catbuffer/_generated/cpp_builder folder.

  1. Publish the generated code into a central repository (e.g. Maven, NPM) and make the SDK dependant on this library. For every transaction type, use the generated builders to serialize and deserialize transactions.

Here you can find some examples of how we used transactions builders:

See the complete list of transactions.

キーペアと暗号化関数

注釈

このセクションは未完了です。

Cryptographic functions are required to sign transactions. All the crypto-related functions can be found under the core/crypto module.

SDKs use standard tweetnacl (ed2559) for key pair generation, address derivation (from public key) and signings:

  • Keypairs are based on tweetnacl 64 bytes secretKey (public + private) using SHA-512.
  • Signatures use tweetnacl detached mode and also get generated using SHA-512.

Finally, pay special attention to the test vectors. The best way to make sure your implementation is correct is to use the test vectors files as inputs and expected outputs.

ベクタテストの例:

サービス

Services combine multiple REST API requests and provide developers with handy methods that cannot be retrieved directly from the API.

Services are considered 「nice to have」 features, and these usually are not required to consider the SDK complete. We recommend starting coding services only if you have a fully operational and well-tested SDK first.

サービスの例:

  • AggregateTransactionService: Helps application developers to announce aggregate transactions without having to develop the logic to wait for the hash lock confirmation.
  • MetadataTransactionService: Creates metadata transactions without having to pass the previous value.
  • BlockService: Provides with methods to verify that the data returned by a given node is valid.

See the complete list of services.

SDK のドキュメント

The SDKs need to be adopted by other developers. As the main developer, no one knows better than you how the SDK works. Consider helping others and spread the usage of the SDK by providing the following documentation.

公式として公開されているSDK

To make an SDK officially supported, submit it as a NIP. The reason behind the Symbol Improvement Proposal is to ensure that the new libraries are reviewed, tested, and shared among Symbol developers.