目的
symbol-sdkで実行する際、会社内やセキュリティに厳しい場所ではProxyサーバがあるせいで直接繋がらないケースがある
これは困るので、sdkにProxy経由の設定を入れてみる
こんな状況図
調査開始
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