10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

symbol-sdk-typescript-javascriptをProxy環境下で使用する

Last updated at Posted at 2020-12-14

目的

symbol-sdkで実行する際、会社内やセキュリティに厳しい場所ではProxyサーバがあるせいで直接繋がらないケースがある
これは困るので、sdkにProxy経由の設定を入れてみる

こんな状況図

image.png

調査開始

symbol-sdk-typescript-javascriptはrestへの接続とかOpenApiで共通化されていて、どうやらnode-fetchを使ってるようだ。
最近の書き方(0.10.0.4)では大体、 RepositoryFactoryHttp を最初に使って自分は書き始めるので、ここらの引数で渡せないだろうかと考える。

const RepositoryFactoryHttp: new (url: string, configs?: RepositoryFactoryConfig) => RepositoryFactoryHttp
Constructor

@param url  the server url.

@param configs  optional repository factory configs

RepositoryFactoryConfig なんていうものがあった

export interface RepositoryFactoryConfig {

    /**
     * optional fetch function to be used when performing rest requests. The default value is:
     *  1) window.fetch if running on a browser
     *  2) or node-fetch if running on server (window.fetch not found)
     */
    fetchApi?: any;

fetchApi という値があったので、node-fetchの値をそのまま渡してあげればいけそうな気がする。
ただ、node-fetch ではProxyサーバの値を事前に渡せないので、環境変数から渡せるように node-fetch-with-proxy を使うことにした。

実際に動くかやってみる

node-fetch-with-proxyのインストール

$ npm i node-fetch-with-proxy

環境変数をセットする

Proxyサーバ(192.168.96.135:3128)をsquidで作ってみた(構築は割愛)

$ export HTTP_PROXY=http://192.168.96.135:3128
$ env | grep HTTP_PROXY
HTTP_PROXY=http://192.168.96.135:3128

スクリプトを書く

ポイントとしては以下の部分

const fetch = require('node-fetch-with-proxy');

(async() => {
  const config = {
    fetchApi: fetch
  }
  // Proxyの設定は環境変数に依存するため、以下の設定を事前にする
  // export HTTP_PROXY=http://PROXY_IP:PORXY_PORT
  const repo = new RepositoryFactoryHttp(url, config);
転送トランザクションを送信するスクリプト
const { 
  Account,
  Address,
  TransferTransaction,
  Deadline,
  PlainMessage,
  RepositoryFactoryHttp,
  TransactionService} = require('symbol-sdk');
const config = require('config');

const url = 'http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000';
const rawprivatekey = '送信元秘密鍵';
const rawsendadress = '送信先アドレス';
const sendaddress = Address.createFromRawAddress(rawsendadress);
const minfeemultiplier = 100;

const fetch = require('node-fetch-with-proxy');

(async() => {
  const config = {
    fetchApi: fetch
  }
  // Proxyの設定は環境変数に依存するため、以下の設定を事前にする
  // export HTTP_PROXY=http://PROXY_IP:PORXY_PORT
  const repo = new RepositoryFactoryHttp(url, config);
  

  //Networktypeをcatapultから取得
  const networkType = await repo.getNetworkType().toPromise()
  //GenerationHashをcatapultから取得
  const ghash = await repo.getGenerationHash().toPromise()

  console.log('network', networkType);
  console.log('GenerationHash', ghash);

  const epoch = await repo.getEpochAdjustment().toPromise();
  const currency = await repo.getCurrencies().toPromise();

  //トランザクションを作成するための内容を作る
  const transferTransaction = TransferTransaction.create(
    Deadline.create(epoch), // いつまでトランザクションをもたせるか
    sendaddress, //送信先アドレス
    [currency.currency.createRelative(100)], // xymの送信数
    PlainMessage.create('TEST KEIYOW'), //メッセージ
    networkType,
  ).setMaxFee(minfeemultiplier);; //最低手数料をつけます

  //送信元のアカウントをセット
  const account = Account.createFromPrivateKey(rawprivatekey, networkType);

  //作成したトランザクションに署名する
  const signedTransaction = account.sign(transferTransaction, ghash);

  //この中にトランザクションIDが入ってる
  console.log('------------------- signedTransaction ------------------------');
  console.log(signedTransaction);

  console.log('------------------- sendTransaction ------------------------');

  //websocketを作成する
  const listener = repo.createListener();
  const transactionService = new TransactionService(repo.createTransactionRepository(), repo.createReceiptRepository());

  // websocketをopenする
  await listener.open()

  // トランザクションを送信する
  transactionService.announce(signedTransaction, listener)
  .subscribe((transaction) => {
    console.log('------------------- Success --------------------------------')
    console.log('Success: Transaction', transaction)
    console.log('------------------------------------------------------------')
    listener.close()
  }, (err) => {
    console.log('Err', err)
    listener.close()
  })

})()

トランザクション実行

$ node symbol/transaction_behind_proxy.js
network 152
GenerationHash 6C1B92391CCB41C96478471C2634C111D9E989DECD66130C0430B5B8D20117CD
------------------- signedTransaction ------------------------
SignedTransaction {
  payload:
   'BC000000000000004ADD04CAB18384CB785B279BEA7DE3818AD8E381D601BCA92317FDF8527A169668528C5656296E0DD0EAFD86E3810EEC8979D65748D78664D480ADEBA02001096215F0EED3CD7DB144C2788F9C7BBEAAC3A53F7406B677448908F9DDE4D097AC000000000198544170490000000000008B1BFB080800000098DEDC169324E77AAFEF6183FB5560423BE8826CF431F7780C000100000000006008ADEC6BE7665B00E40B54020000000054455354204B4549594F57',
  hash:
   '73C55E1EBFB4C76B95B4E3125EB4A28AAD00847174CFB4660F4FDA566B253A10',
  signerPublicKey:
   '6215F0EED3CD7DB144C2788F9C7BBEAAC3A53F7406B677448908F9DDE4D097AC',
  type: 16724,
  networkType: 152 }
------------------- sendTransaction ------------------------
------------------- Success --------------------------------
Success: Transaction TransferTransaction {
  type: 16724,
  networkType: 152,
  version: 1,
  deadline: Deadline { adjustedValue: 34510412683 },
  maxFee: UInt64 { lower: 18800, higher: 0 },
  signature:
   '4ADD04CAB18384CB785B279BEA7DE3818AD8E381D601BCA92317FDF8527A169668528C5656296E0DD0EAFD86E3810EEC8979D65748D78664D480ADEBA0200109',
  signer:
   PublicAccount {
     publicKey:
      '6215F0EED3CD7DB144C2788F9C7BBEAAC3A53F7406B677448908F9DDE4D097AC',
     address:
      Address {
        address: 'TDIDPITIP63MO3MQIMUOBJZUX3WQZBGBKBWTELI',
        networkType: 152 } },
  transactionInfo:
   TransactionInfo {
     height: UInt64 { lower: 223811, higher: 0 },
     index: undefined,
     id: undefined,
     hash:
      '73C55E1EBFB4C76B95B4E3125EB4A28AAD00847174CFB4660F4FDA566B253A10',
     merkleComponentHash:
      '73C55E1EBFB4C76B95B4E3125EB4A28AAD00847174CFB4660F4FDA566B253A10' },
  payloadSize: undefined,
  recipientAddress:
   Address {
     address: 'TDPNYFUTETTXVL7PMGB7WVLAII56RATM6QY7O6A',
     networkType: 152 },
  mosaics: [ Mosaic { id: [MosaicId], amount: [UInt64] } ],
  message: PlainMessage { type: 0, payload: 'TEST KEIYOW' } }
------------------------------------------------------------

Proxyサーバ側のSquidログ確認

Squid経由でトランザクション実行できた

1607933612.394    212 192.168.96.1 TCP_REFRESH_MODIFIED/200 605 GET http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000/node/info - HIER_DIRECT/xx.xx.xx.xx application/json
1607933612.398    216 192.168.96.1 TCP_REFRESH_MODIFIED/200 605 GET http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000/node/info - HIER_DIRECT/xx.xx.xx.xx application/json
1607933612.442     37 192.168.96.1 TCP_REFRESH_MODIFIED/200 2860 GET http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000/network/properties - HIER_DIRECT/xx.xx.xx.xx application/json
1607933612.501     52 192.168.96.1 TCP_REFRESH_MODIFIED/200 2860 GET http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000/network/properties - HIER_DIRECT/xx.xx.xx.xx application/json
1607933612.643    136 192.168.96.1 TCP_MISS/200 307 POST http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000/namespaces/mosaic/names - HIER_DIRECT/xx.xx.xx.xx application/json
1607933612.643    136 192.168.96.1 TCP_MISS/200 485 POST http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000/mosaics - HIER_DIRECT/xx.xx.xx.xx application/json
1607933612.883    118 192.168.96.1 TCP_MISS/202 307 PUT http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000/transactions - HIER_DIRECT/xx.xx.xx.xx application/json
10
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?