はじめに
こんにちは。OpeningLIneの坂本です。symbol-sdkの3系が手軽に利用できるようになりましたね。
npmでは、執筆時点で3.0.7が公開されています。
では、少し触ってみようと思います。
インストール
今回はブラウザではなくて、Node.jsの環境で実施します。
以下
npm i symbol-sdk
のコマンドで、
"symbol-sdk": "^3.0.7"
が入りました。rxjsはいらないみたいです。
また、REST Gatewayとの通信のためにaxiosをインストールしておきます。
npm i axios
Typescriptは使えない
最初Typescriptで始めようとしたら、コンパイルでこけました。どうやらTypescriptは対応していないようです。
> tsc
src/index.ts:1:23 - error TS7016: Could not find a declaration file for module 'symbol-sdk'. '/node_modules/symbol-sdk/src/index.js' implicitly has an 'any' type.
Try `npm i --save-dev @types/symbol-sdk` if it exists or add a new declaration (.d.ts) file containing `declare module 'symbol-sdk';`
Typescriptについては詳しくはないのですが、型定義を作成すると使えるようになるのかな、と思います。
ですので、以下はJavaScriptで進めようと思います。
転送トランザクションサンプル
情報を収集する
epoch adjustmentやモザイクID、ネットワークIDを取得していきます。
const node = axios.create({
baseURL: NODE_URL,
timeout: 1000,
headers: { 'Content-Type': 'application/json' }
});
const networkProperties = await node.get('/network/properties').then((res) => res.data);
const epochAdjustment = BigInt(networkProperties.network.epochAdjustment.slice(0, -1)) * 1000n;
// 1667250467000n
const currencyMosaicId = BigInt(networkProperties.chain.currencyMosaicId.replace(/'/g, ''));
// 0x72C0212E67A08BCEn
const symbolNetwork = networkProperties.network.identifier;
// 'testnet'
Facadeを生成する
symbol用のfacadeを生成します。このfacadeを使ってsymbol固有の処理を実行していきます。
const facade = new symbolSdk.facade.SymbolFacade(symbolNetwork);
トランザクションを作成する
ここは2系のものと大きくは変わっていません。
const privateKey = new symbolSdk.PrivateKey(PRIVATE_KEY);
const keyPair = new facade.constructor.KeyPair(privateKey);
const transaction = facade.transactionFactory.create({
type: 'transfer_transaction_v1',
signerPublicKey: keyPair.publicKey.toString(),
fee: 1000000n,
deadline: BigInt(Date.now()) - epochAdjustment + 7200000n,
recipientAddress: ADDRESS_RECEIVER_1,
mosaics: [
{ mosaicId: currencyMosaicId, amount: 1000000n }
]
});
署名してハッシュを計算する
この辺りも2系のものと大きくは変わっていませんが、少し難しくなりましたかね。
jsonPayloadには、トランザクションのバイト列が入っています。これをそのままの形でREST Gatewayに送信することになります。
const signature = facade.signTransaction(keyPair, transaction);
const jsonPayload = facade.transactionFactory.constructor.attachSignature(transaction, signature);
const hash = facade.hashTransaction(transaction).toString();
console.log(jsonPayload);
// '{ "payload": "B000000000000000F514132000..." }'
console.log(hash);
// "D9140C1F85150ED9A0BE92DB18BBA02401AC6788B0D11DA190C50011FBD09C14"
ここでジェネレーションハッシュを入力していませんが、SDKの中に直に書かれていました。
送信する
REST Gatewayのエンドポイントへ送信します。
const response = await node.put("/transactions", jsonPayload).then((res) => res.data);
console.log(response);
// { message: 'packet 9 was pushed to the network via /transactions' }
確認する
SDKでは、情報を取得するためのものが無いため、自らREST Gatewayに問い合わせる必要があります。
トランザクションステータス
const statusRes = await node.get("/transactionStatus/" + hash).then((res) => res.data);
console.log(statusRes);
このようなデータが返ってきます。
{
group: 'unconfirmed',
code: 'Success',
hash: 'F80F27E817288971AB533EAA9EF6DD846DECD0305734E047C04FC6BFEFCAE327',
deadline: '16032354275',
height: '0'
}
承認されていたら、こうなります。
{
"group": "confirmed",
"code": "Success",
"hash": "F80F27E817288971AB533EAA9EF6DD846DECD0305734E047C04FC6BFEFCAE327",
"deadline": "16032354275",
"height": "436904"
}
トランザクション詳細
また、トランザクション承認後は、以下のエンドポイントが利用可能になりますね。
const hash = "F80F27E817288971AB533EAA9EF6DD846DECD0305734E047C04FC6BFEFCAE327"
const confirmedRes = await node.get("/transactions/confirmed/" + hash).then((res) => res.data);
console.log(confirmedRes);
コード全体
補足
ネットワーク情報やデッドラインの作成方法がいくつかあるみたいでした。
import symbolSdk from 'symbol-sdk';
const network = symbolSdk.symbol.Network.TESTNET;
とすることで、Symbolテストネットのネットネット情報にアクセスできるようです。
const network = symbolSdk.symbol.Network.MAINNET;
とすれば、メインネット。
他には、このような方法も見つかりました。
const network = symbolSdk.NetworkLocator.findByName(symbolSdk.symbol.Network.NETWORKS, 'testnet');
これを使って、2時間のデッドラインを計算するには、以下のようにします。
const deadline = network.fromDatetime(new Date(Date.now() + 7200000)).timestamp;
// 16034333219n
7200000は、2時間をミリ秒に直した数値です。
おわりに
新しくなったsymbol-sdkにて、転送トランザクションを送信することをやってみました。少し難しくなった印象がありますね。その分、SDK自体は軽くなっているような気がします。