@railgun-community/waku-broadcaster-client-node 9.0.3 → 9.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getRailgunWalletAddressData, encryptDataWithSharedKey, getCompletedTxidFromNullifiers, } from '@railgun-community/wallet';
|
|
2
|
-
import { poll, } from '@railgun-community/shared-models';
|
|
2
|
+
import { poll, BroadcasterTransactRequestType, } from '@railgun-community/shared-models';
|
|
3
3
|
import { BroadcasterConfig } from '../models/broadcaster-config.js';
|
|
4
4
|
import { bytesToHex } from '../utils/conversion.js';
|
|
5
5
|
import { BroadcasterDebug } from '../utils/broadcaster-debug.js';
|
|
@@ -48,6 +48,7 @@ export class BroadcasterTransaction {
|
|
|
48
48
|
}
|
|
49
49
|
const { viewingPublicKey: broadcasterViewingKey } = getRailgunWalletAddressData(broadcasterRailgunAddress);
|
|
50
50
|
const transactData = {
|
|
51
|
+
transactType: BroadcasterTransactRequestType.COMMON,
|
|
51
52
|
txidVersion: txidVersionForInputs,
|
|
52
53
|
to: getAddress(to),
|
|
53
54
|
data,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broadcaster-transaction.js","sourceRoot":"","sources":["../../src/transact/broadcaster-transaction.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getRailgunWalletAddressData,\n encryptDataWithSharedKey,\n getCompletedTxidFromNullifiers,\n} from '@railgun-community/wallet';\nimport {\n Chain,\n EncryptDataWithSharedKeyResponse,\n poll,\n PreTransactionPOIsPerTxidLeafPerList,\n BroadcasterEncryptedMethodParams,\n BroadcasterRawParamsTransact,\n TXIDVersion,\n} from '@railgun-community/shared-models';\nimport { BroadcasterConfig } from '../models/broadcaster-config.js';\nimport { bytesToHex } from '../utils/conversion.js';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport { isDefined } from '../utils/is-defined.js';\nimport { WakuBroadcasterWakuCore } from '../waku/waku-broadcaster-waku-core.js';\nimport { contentTopics } from '../waku/waku-topics.js';\nimport {\n WakuTransactResponse,\n BroadcasterTransactResponse,\n} from './broadcaster-transact-response.js';\nimport { getAddress, isHexString } from 'ethers';\n\n//\n// Transact: Encryption Flow\n//\n// Client:\n// 1. Generates random 16 bytes: `responseKey` and adds to transact data\n// 2. Generates a `sharedKey` from a random `privkey` and the Broadcaster's `pubkey`\n// 3. Encrypts the transact data asymmetrically, using `sharedKey` (`encryptedData = encrypt(transactData, sharedKey)`)\n// 4. Includes `publicKey` and `encryptedData` in transact message\n// 5. Sends the message\n//\n// Broadcaster:\n// 1. Decrypts the `encryptedData` using Broadcaster privkey and `sharedKey` (if error, it's not addressed to us)\n// 2. Processes transaction\n// 3. Encrypts response (`txHash` or `error`) using `responseKey` (symmetric: AES-GCM-256)\n// 4. Sends back encrypted response on transact-response: {encryptedData}\n//\n// Client:\n// 1. Catches all `transact-response`'s after sending a transaction.\n// 2. Decrypts each using the `responseKey`. (If error, not addressed to us)\n// 3. After successful decryption, parses `txHash` or `error`.\n//\n\nenum BroadcastRetryState {\n RetryTransact = 'RetryTransact',\n Wait = 'Wait',\n Timeout = 'Timeout',\n}\n\ntype BroadcastMessageData = {\n method: string;\n params: BroadcasterEncryptedMethodParams;\n};\n\n// NOTE: Broadcaster default transaction-send timeout is 45 seconds.\nconst SECONDS_PER_RETRY = 2;\nconst POLL_DELAY_SECONDS = 0.1;\nconst RETRY_TRANSACTION_SECONDS = 20;\nconst POST_ALERT_TOTAL_WAITING_SECONDS = 120;\n\nexport class BroadcasterTransaction {\n private messageData: BroadcastMessageData;\n private contentTopic: string;\n private txidVersionForInputs: TXIDVersion;\n private chain: Chain;\n private nullifiers: string[];\n\n private constructor(\n encryptedDataResponse: EncryptDataWithSharedKeyResponse,\n txidVersionForInputs: TXIDVersion,\n chain: Chain,\n nullifiers: string[],\n ) {\n this.messageData = {\n method: 'transact',\n params: {\n pubkey: encryptedDataResponse.randomPubKey,\n encryptedData: encryptedDataResponse.encryptedData,\n },\n };\n this.contentTopic = contentTopics.transact(chain);\n this.txidVersionForInputs = txidVersionForInputs;\n this.chain = chain;\n this.nullifiers = nullifiers;\n BroadcasterTransactResponse.setSharedKey(encryptedDataResponse.sharedKey);\n }\n\n static async create(\n txidVersionForInputs: TXIDVersion,\n to: string,\n data: string,\n broadcasterRailgunAddress: string,\n broadcasterFeesID: string,\n chain: Chain,\n nullifiers: string[],\n overallBatchMinGasPrice: bigint,\n useRelayAdapt: boolean,\n preTransactionPOIsPerTxidLeafPerList: PreTransactionPOIsPerTxidLeafPerList,\n ): Promise<BroadcasterTransaction> {\n const encryptedDataResponse = await this.encryptTransaction(\n txidVersionForInputs,\n to,\n data,\n broadcasterRailgunAddress,\n broadcasterFeesID,\n chain,\n overallBatchMinGasPrice,\n useRelayAdapt,\n preTransactionPOIsPerTxidLeafPerList,\n );\n return new BroadcasterTransaction(\n encryptedDataResponse,\n txidVersionForInputs,\n chain,\n nullifiers,\n );\n }\n\n private static async encryptTransaction(\n txidVersionForInputs: TXIDVersion,\n to: string,\n data: string,\n broadcasterRailgunAddress: string,\n broadcasterFeesID: string,\n chain: Chain,\n overallBatchMinGasPrice: bigint,\n useRelayAdapt: boolean,\n preTransactionPOIsPerTxidLeafPerList: PreTransactionPOIsPerTxidLeafPerList,\n ): Promise<EncryptDataWithSharedKeyResponse> {\n if (!isHexString(data)) {\n throw new Error('Data field must be a hex string.');\n }\n\n const { viewingPublicKey: broadcasterViewingKey } =\n getRailgunWalletAddressData(broadcasterRailgunAddress);\n\n const transactData: BroadcasterRawParamsTransact = {\n txidVersion: txidVersionForInputs,\n to: getAddress(to),\n data,\n broadcasterViewingKey: bytesToHex(broadcasterViewingKey),\n chainID: chain.id,\n chainType: chain.type,\n minGasPrice: overallBatchMinGasPrice.toString(),\n feesID: broadcasterFeesID,\n useRelayAdapt,\n devLog: BroadcasterConfig.IS_DEV,\n minVersion: BroadcasterConfig.MINIMUM_BROADCASTER_VERSION,\n maxVersion: BroadcasterConfig.MAXIMUM_BROADCASTER_VERSION,\n preTransactionPOIsPerTxidLeafPerList,\n };\n\n const encryptedDataResponse = await encryptDataWithSharedKey(\n transactData,\n broadcasterViewingKey,\n );\n\n return encryptedDataResponse;\n }\n\n private async findMatchingNullifierTxid(): Promise<Optional<string>> {\n try {\n const { txid } = await getCompletedTxidFromNullifiers(\n this.txidVersionForInputs,\n this.chain,\n this.nullifiers,\n );\n return txid;\n } catch (cause) {\n if (!(cause instanceof Error)) {\n throw new Error('Unexpected non-error thrown', { cause });\n }\n BroadcasterDebug.error(\n new Error('Failed to find matching nullifier txid', { cause }),\n );\n return undefined;\n }\n }\n\n private async getTransactionResponse(): Promise<\n Optional<WakuTransactResponse>\n > {\n if (BroadcasterTransactResponse.storedTransactionResponse) {\n return BroadcasterTransactResponse.storedTransactionResponse;\n }\n\n const nullifiersTxid = await this.findMatchingNullifierTxid();\n if (isDefined(nullifiersTxid)) {\n return {\n id: 'nullifier-transaction',\n txHash: nullifiersTxid,\n };\n }\n\n return undefined;\n }\n\n private getBroadcastRetryState(retryNumber: number): BroadcastRetryState {\n const retrySeconds = retryNumber * SECONDS_PER_RETRY;\n if (retrySeconds <= RETRY_TRANSACTION_SECONDS) {\n return BroadcastRetryState.RetryTransact;\n }\n if (retrySeconds >= POST_ALERT_TOTAL_WAITING_SECONDS) {\n return BroadcastRetryState.Timeout;\n }\n return BroadcastRetryState.Wait;\n }\n\n async send(): Promise<string> {\n return this.broadcast();\n }\n\n private async broadcast(retryNumber = 0): Promise<string> {\n const broadcastRetryState = this.getBroadcastRetryState(retryNumber);\n switch (broadcastRetryState) {\n case BroadcastRetryState.RetryTransact:\n // 0-20 seconds.\n BroadcasterDebug.log(\n `Broadcast Waku message: ${this.messageData.method} via ${this.contentTopic}`,\n );\n try {\n await WakuBroadcasterWakuCore.broadcastMessage(\n this.messageData,\n this.contentTopic,\n );\n } catch (err) {\n if (err instanceof Error) {\n BroadcasterDebug.log(`Broadcast error: ${err.message}`);\n }\n }\n break;\n case BroadcastRetryState.Wait:\n // 21-60 seconds.\n // Do nothing.\n break;\n case BroadcastRetryState.Timeout:\n // Exactly 60 seconds.\n throw new Error('Request timed out.');\n }\n\n // 15 iterations (1.5 sec total, iterate every 100ms).\n const pollIterations = SECONDS_PER_RETRY / POLL_DELAY_SECONDS;\n\n const responseTopic = contentTopics.transactResponse(this.chain);\n await WakuBroadcasterWakuCore.retrieveHistoricalForTopic(responseTopic);\n\n const response: Optional<WakuTransactResponse> = await poll(\n async () => this.getTransactionResponse(),\n (result: Optional<WakuTransactResponse>) => result != null,\n POLL_DELAY_SECONDS * 1000,\n pollIterations,\n );\n if (isDefined(response)) {\n if (isDefined(response.txHash)) {\n BroadcasterTransactResponse.clearSharedKey();\n return response.txHash;\n }\n if (isDefined(response.error)) {\n BroadcasterDebug.log(`Broadcast error: ${response.error}`);\n BroadcasterTransactResponse.clearSharedKey();\n throw new Error('Received response error from broadcaster.', {\n cause: new Error(response.error),\n });\n }\n }\n\n // Retry.\n return this.broadcast(retryNumber + 1);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"broadcaster-transaction.js","sourceRoot":"","sources":["../../src/transact/broadcaster-transaction.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getRailgunWalletAddressData,\n encryptDataWithSharedKey,\n getCompletedTxidFromNullifiers,\n} from '@railgun-community/wallet';\nimport {\n Chain,\n EncryptDataWithSharedKeyResponse,\n poll,\n PreTransactionPOIsPerTxidLeafPerList,\n BroadcasterEncryptedMethodParams,\n BroadcasterRawParamsTransact,\n TXIDVersion,\n BroadcasterTransactRequestType,\n} from '@railgun-community/shared-models';\nimport { BroadcasterConfig } from '../models/broadcaster-config.js';\nimport { bytesToHex } from '../utils/conversion.js';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport { isDefined } from '../utils/is-defined.js';\nimport { WakuBroadcasterWakuCore } from '../waku/waku-broadcaster-waku-core.js';\nimport { contentTopics } from '../waku/waku-topics.js';\nimport {\n WakuTransactResponse,\n BroadcasterTransactResponse,\n} from './broadcaster-transact-response.js';\nimport { getAddress, isHexString } from 'ethers';\n\n//\n// Transact: Encryption Flow\n//\n// Client:\n// 1. Generates random 16 bytes: `responseKey` and adds to transact data\n// 2. Generates a `sharedKey` from a random `privkey` and the Broadcaster's `pubkey`\n// 3. Encrypts the transact data asymmetrically, using `sharedKey` (`encryptedData = encrypt(transactData, sharedKey)`)\n// 4. Includes `publicKey` and `encryptedData` in transact message\n// 5. Sends the message\n//\n// Broadcaster:\n// 1. Decrypts the `encryptedData` using Broadcaster privkey and `sharedKey` (if error, it's not addressed to us)\n// 2. Processes transaction\n// 3. Encrypts response (`txHash` or `error`) using `responseKey` (symmetric: AES-GCM-256)\n// 4. Sends back encrypted response on transact-response: {encryptedData}\n//\n// Client:\n// 1. Catches all `transact-response`'s after sending a transaction.\n// 2. Decrypts each using the `responseKey`. (If error, not addressed to us)\n// 3. After successful decryption, parses `txHash` or `error`.\n//\n\nenum BroadcastRetryState {\n RetryTransact = 'RetryTransact',\n Wait = 'Wait',\n Timeout = 'Timeout',\n}\n\ntype BroadcastMessageData = {\n method: string;\n params: BroadcasterEncryptedMethodParams;\n};\n\n// NOTE: Broadcaster default transaction-send timeout is 45 seconds.\nconst SECONDS_PER_RETRY = 2;\nconst POLL_DELAY_SECONDS = 0.1;\nconst RETRY_TRANSACTION_SECONDS = 20;\nconst POST_ALERT_TOTAL_WAITING_SECONDS = 120;\n\nexport class BroadcasterTransaction {\n private messageData: BroadcastMessageData;\n private contentTopic: string;\n private txidVersionForInputs: TXIDVersion;\n private chain: Chain;\n private nullifiers: string[];\n\n private constructor(\n encryptedDataResponse: EncryptDataWithSharedKeyResponse,\n txidVersionForInputs: TXIDVersion,\n chain: Chain,\n nullifiers: string[],\n ) {\n this.messageData = {\n method: 'transact',\n params: {\n pubkey: encryptedDataResponse.randomPubKey,\n encryptedData: encryptedDataResponse.encryptedData,\n },\n };\n this.contentTopic = contentTopics.transact(chain);\n this.txidVersionForInputs = txidVersionForInputs;\n this.chain = chain;\n this.nullifiers = nullifiers;\n BroadcasterTransactResponse.setSharedKey(encryptedDataResponse.sharedKey);\n }\n\n static async create(\n txidVersionForInputs: TXIDVersion,\n to: string,\n data: string,\n broadcasterRailgunAddress: string,\n broadcasterFeesID: string,\n chain: Chain,\n nullifiers: string[],\n overallBatchMinGasPrice: bigint,\n useRelayAdapt: boolean,\n preTransactionPOIsPerTxidLeafPerList: PreTransactionPOIsPerTxidLeafPerList,\n ): Promise<BroadcasterTransaction> {\n const encryptedDataResponse = await this.encryptTransaction(\n txidVersionForInputs,\n to,\n data,\n broadcasterRailgunAddress,\n broadcasterFeesID,\n chain,\n overallBatchMinGasPrice,\n useRelayAdapt,\n preTransactionPOIsPerTxidLeafPerList,\n );\n return new BroadcasterTransaction(\n encryptedDataResponse,\n txidVersionForInputs,\n chain,\n nullifiers,\n );\n }\n\n private static async encryptTransaction(\n txidVersionForInputs: TXIDVersion,\n to: string,\n data: string,\n broadcasterRailgunAddress: string,\n broadcasterFeesID: string,\n chain: Chain,\n overallBatchMinGasPrice: bigint,\n useRelayAdapt: boolean,\n preTransactionPOIsPerTxidLeafPerList: PreTransactionPOIsPerTxidLeafPerList,\n ): Promise<EncryptDataWithSharedKeyResponse> {\n if (!isHexString(data)) {\n throw new Error('Data field must be a hex string.');\n }\n\n const { viewingPublicKey: broadcasterViewingKey } =\n getRailgunWalletAddressData(broadcasterRailgunAddress);\n\n const transactData: BroadcasterRawParamsTransact = {\n transactType: BroadcasterTransactRequestType.COMMON,\n txidVersion: txidVersionForInputs,\n to: getAddress(to),\n data,\n broadcasterViewingKey: bytesToHex(broadcasterViewingKey),\n chainID: chain.id,\n chainType: chain.type,\n minGasPrice: overallBatchMinGasPrice.toString(),\n feesID: broadcasterFeesID,\n useRelayAdapt,\n devLog: BroadcasterConfig.IS_DEV,\n minVersion: BroadcasterConfig.MINIMUM_BROADCASTER_VERSION,\n maxVersion: BroadcasterConfig.MAXIMUM_BROADCASTER_VERSION,\n preTransactionPOIsPerTxidLeafPerList,\n };\n\n const encryptedDataResponse = await encryptDataWithSharedKey(\n transactData,\n broadcasterViewingKey,\n );\n\n return encryptedDataResponse;\n }\n\n private async findMatchingNullifierTxid(): Promise<Optional<string>> {\n try {\n const { txid } = await getCompletedTxidFromNullifiers(\n this.txidVersionForInputs,\n this.chain,\n this.nullifiers,\n );\n return txid;\n } catch (cause) {\n if (!(cause instanceof Error)) {\n throw new Error('Unexpected non-error thrown', { cause });\n }\n BroadcasterDebug.error(\n new Error('Failed to find matching nullifier txid', { cause }),\n );\n return undefined;\n }\n }\n\n private async getTransactionResponse(): Promise<\n Optional<WakuTransactResponse>\n > {\n if (BroadcasterTransactResponse.storedTransactionResponse) {\n return BroadcasterTransactResponse.storedTransactionResponse;\n }\n\n const nullifiersTxid = await this.findMatchingNullifierTxid();\n if (isDefined(nullifiersTxid)) {\n return {\n id: 'nullifier-transaction',\n txHash: nullifiersTxid,\n };\n }\n\n return undefined;\n }\n\n private getBroadcastRetryState(retryNumber: number): BroadcastRetryState {\n const retrySeconds = retryNumber * SECONDS_PER_RETRY;\n if (retrySeconds <= RETRY_TRANSACTION_SECONDS) {\n return BroadcastRetryState.RetryTransact;\n }\n if (retrySeconds >= POST_ALERT_TOTAL_WAITING_SECONDS) {\n return BroadcastRetryState.Timeout;\n }\n return BroadcastRetryState.Wait;\n }\n\n async send(): Promise<string> {\n return this.broadcast();\n }\n\n private async broadcast(retryNumber = 0): Promise<string> {\n const broadcastRetryState = this.getBroadcastRetryState(retryNumber);\n switch (broadcastRetryState) {\n case BroadcastRetryState.RetryTransact:\n // 0-20 seconds.\n BroadcasterDebug.log(\n `Broadcast Waku message: ${this.messageData.method} via ${this.contentTopic}`,\n );\n try {\n await WakuBroadcasterWakuCore.broadcastMessage(\n this.messageData,\n this.contentTopic,\n );\n } catch (err) {\n if (err instanceof Error) {\n BroadcasterDebug.log(`Broadcast error: ${err.message}`);\n }\n }\n break;\n case BroadcastRetryState.Wait:\n // 21-60 seconds.\n // Do nothing.\n break;\n case BroadcastRetryState.Timeout:\n // Exactly 60 seconds.\n throw new Error('Request timed out.');\n }\n\n // 15 iterations (1.5 sec total, iterate every 100ms).\n const pollIterations = SECONDS_PER_RETRY / POLL_DELAY_SECONDS;\n\n const responseTopic = contentTopics.transactResponse(this.chain);\n await WakuBroadcasterWakuCore.retrieveHistoricalForTopic(responseTopic);\n\n const response: Optional<WakuTransactResponse> = await poll(\n async () => this.getTransactionResponse(),\n (result: Optional<WakuTransactResponse>) => result != null,\n POLL_DELAY_SECONDS * 1000,\n pollIterations,\n );\n if (isDefined(response)) {\n if (isDefined(response.txHash)) {\n BroadcasterTransactResponse.clearSharedKey();\n return response.txHash;\n }\n if (isDefined(response.error)) {\n BroadcasterDebug.log(`Broadcast error: ${response.error}`);\n BroadcasterTransactResponse.clearSharedKey();\n throw new Error('Received response error from broadcaster.', {\n cause: new Error(response.error),\n });\n }\n }\n\n // Retry.\n return this.broadcast(retryNumber + 1);\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@railgun-community/waku-broadcaster-client-node",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -23,6 +23,14 @@
|
|
|
23
23
|
"test": "npm run compile-test && NODE_ENV=test mocha 'dist/**/*.test.js'",
|
|
24
24
|
"postinstall": "patch-package"
|
|
25
25
|
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/Railgun-Community/waku-broadcaster-client.git"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/Railgun-Community/waku-broadcaster-client#readme",
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/Railgun-Community/waku-broadcaster-client/issues"
|
|
33
|
+
},
|
|
26
34
|
"dependencies": {
|
|
27
35
|
"@libp2p/tcp": "^10.0.0",
|
|
28
36
|
"@waku/discovery": "^0.0.13",
|
|
@@ -33,12 +41,12 @@
|
|
|
33
41
|
"protons-runtime": "5.6.0"
|
|
34
42
|
},
|
|
35
43
|
"peerDependencies": {
|
|
36
|
-
"@railgun-community/shared-models": "^8.0.
|
|
37
|
-
"@railgun-community/wallet": "^10.8.
|
|
44
|
+
"@railgun-community/shared-models": "^8.0.1",
|
|
45
|
+
"@railgun-community/wallet": "^10.8.3"
|
|
38
46
|
},
|
|
39
47
|
"devDependencies": {
|
|
40
|
-
"@railgun-community/shared-models": "^8.0.
|
|
41
|
-
"@railgun-community/wallet": "^10.8.
|
|
48
|
+
"@railgun-community/shared-models": "^8.0.1",
|
|
49
|
+
"@railgun-community/wallet": "^10.8.3",
|
|
42
50
|
"@types/chai": "^4.3.5",
|
|
43
51
|
"@types/chai-as-promised": "^7.1.5",
|
|
44
52
|
"@types/leveldown": "^4.0.3",
|
|
@@ -54,7 +62,7 @@
|
|
|
54
62
|
"eslint-config-prettier": "^8.8.0",
|
|
55
63
|
"eslint-plugin-flowtype": "^8.0.3",
|
|
56
64
|
"eslint-plugin-import": "^2.27.5",
|
|
57
|
-
"ethers": "6.
|
|
65
|
+
"ethers": "6.14.3",
|
|
58
66
|
"leveldown": "^6.1.1",
|
|
59
67
|
"madge": "^6.1.0",
|
|
60
68
|
"mocha": "^10.2.0",
|