@railgun-community/waku-broadcaster-client-node 7.0.3 → 7.1.0
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.
- package/dist/fees/handle-fees-message.js +1 -0
- package/dist/fees/handle-fees-message.js.map +1 -1
- package/dist/search/best-broadcaster.js +1 -0
- package/dist/search/best-broadcaster.js.map +1 -1
- package/dist/transact/broadcaster-transaction.js +4 -4
- package/dist/transact/broadcaster-transaction.js.map +1 -1
- package/package.json +5 -5
|
@@ -81,6 +81,7 @@ const updateFeesForBroadcaster = (chain, feeMessageData) => {
|
|
|
81
81
|
feesID: feeMessageData.feesID,
|
|
82
82
|
availableWallets: feeMessageData.availableWallets,
|
|
83
83
|
relayAdapt: feeMessageData.relayAdapt,
|
|
84
|
+
reliability: feeMessageData.reliability,
|
|
84
85
|
};
|
|
85
86
|
tokenFeeMap[tokenAddress] = cachedFee;
|
|
86
87
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle-fees-message.js","sourceRoot":"","sources":["../../src/fees/handle-fees-message.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"handle-fees-message.js","sourceRoot":"","sources":["../../src/fees/handle-fees-message.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n verifyBroadcasterSignature,\n getRailgunWalletAddressData,\n} from '@railgun-community/wallet';\nimport {\n CachedTokenFee,\n Chain,\n BroadcasterFeeMessageData,\n} from '@railgun-community/shared-models';\nimport crypto from 'crypto';\nimport { IMessage } from '@waku/interfaces';\nimport { contentTopics } from '../waku/waku-topics.js';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport { BroadcasterConfig } from '../models/broadcaster-config.js';\nimport { BroadcasterFeeCache } from './broadcaster-fee-cache.js';\nimport { invalidBroadcasterVersion } from '../utils/broadcaster-util.js';\nimport { bytesToUtf8, hexToUTF8String } from '../utils/conversion.js';\nimport { isDefined } from '../utils/is-defined.js';\n\nconst isExpiredTimestamp = (\n timestamp: Optional<Date>,\n expirationFeeTimestamp: Optional<Date>,\n) => {\n if (!timestamp || !expirationFeeTimestamp) {\n return false;\n }\n let messageTimestamp = timestamp;\n if (messageTimestamp.getFullYear() === 1970) {\n // Waku timestamp bug.\n messageTimestamp = new Date(messageTimestamp.getTime() * 1000);\n }\n // Expired if message originated > 45 seconds ago.\n // check if fee expires within 45 seconds; if it doesn't ignore it.\n const nowTime = Date.now();\n const expirationMsec = nowTime - 45 * 1000;\n // const expirationFeeMsec = nowTime + 45 * 1000;\n const timestampExpired = messageTimestamp.getTime() < expirationMsec;\n if (timestampExpired) {\n BroadcasterDebug.log(\n `Broadcaster Fee STALE: Difference was ${\n (Date.now() - messageTimestamp.getTime()) / 1000\n }s`,\n );\n } else {\n BroadcasterDebug.log(\n `Broadcaster Fee receipt SUCCESS in ${\n (Date.now() - messageTimestamp.getTime()) / 1000\n }s`,\n );\n }\n // const feeExpired = expirationFeeTimestamp.getTime() < expirationFeeMsec;\n return timestampExpired; // || feeExpired;\n};\n\nexport const handleBroadcasterFeesMessage = async (\n chain: Chain,\n message: IMessage,\n contentTopic: string,\n) => {\n try {\n if (!isDefined(message.payload)) {\n BroadcasterDebug.log('Skipping Broadcaster fees message: NO PAYLOAD');\n return;\n }\n if (contentTopic !== contentTopics.fees(chain)) {\n BroadcasterDebug.log('Skipping Broadcaster fees message: WRONG TOPIC');\n return;\n }\n const payload = bytesToUtf8(message.payload);\n const { data, signature } = JSON.parse(payload) as {\n data: string;\n signature: string;\n };\n const utf8String = hexToUTF8String(data);\n const feeMessageData = JSON.parse(utf8String) as BroadcasterFeeMessageData;\n const feeExpirationTime = new Date(feeMessageData.feeExpiration);\n if (isExpiredTimestamp(message.timestamp, feeExpirationTime)) {\n BroadcasterDebug.log('Skipping fee message. Timestamp Expired.');\n return;\n }\n\n if (!isDefined(crypto.subtle) && BroadcasterConfig.IS_DEV) {\n BroadcasterDebug.log(\n 'Skipping Broadcaster fee validation in DEV. `crypto.subtle` does not exist (not secure: use https or localhost). ',\n );\n updateFeesForBroadcaster(chain, feeMessageData);\n return;\n }\n\n if (invalidBroadcasterVersion(feeMessageData.version)) {\n BroadcasterDebug.log(\n `Skipping Broadcaster outside version range: ${feeMessageData.version}, ${feeMessageData.railgunAddress}`,\n );\n return;\n }\n\n const { railgunAddress } = feeMessageData;\n const { viewingPublicKey } = getRailgunWalletAddressData(railgunAddress);\n //TODO: rename this to verifyBroadcasterSignature\n const verified = await verifyBroadcasterSignature(\n signature,\n data,\n viewingPublicKey,\n );\n if (!verified) {\n return;\n }\n\n updateFeesForBroadcaster(chain, feeMessageData);\n } catch (cause) {\n if (!(cause instanceof Error)) {\n throw new Error('Unexpected non-error thrown', { cause });\n }\n\n BroadcasterDebug.error(\n new Error('Error handling Broadcaster fees', { cause }),\n );\n }\n};\n\nconst updateFeesForBroadcaster = (\n chain: Chain,\n feeMessageData: BroadcasterFeeMessageData,\n) => {\n const tokenFeeMap: MapType<CachedTokenFee> = {};\n const tokenAddresses = Object.keys(feeMessageData.fees);\n tokenAddresses.forEach(tokenAddress => {\n const feePerUnitGas = feeMessageData.fees[tokenAddress];\n if (feePerUnitGas) {\n const cachedFee: CachedTokenFee = {\n feePerUnitGas,\n expiration: feeMessageData.feeExpiration,\n feesID: feeMessageData.feesID,\n availableWallets: feeMessageData.availableWallets,\n relayAdapt: feeMessageData.relayAdapt,\n reliability: feeMessageData.reliability,\n };\n tokenFeeMap[tokenAddress] = cachedFee;\n }\n });\n\n BroadcasterFeeCache.addTokenFees(\n chain,\n feeMessageData.railgunAddress,\n feeMessageData.feeExpiration,\n tokenFeeMap,\n feeMessageData.identifier,\n feeMessageData.version,\n feeMessageData.requiredPOIListKeys ?? [],\n );\n};\n"]}
|
|
@@ -42,6 +42,7 @@ export class BroadcasterSearch {
|
|
|
42
42
|
selectedBroadcasters.push(selectedBroadcaster);
|
|
43
43
|
});
|
|
44
44
|
});
|
|
45
|
+
selectedBroadcasters.sort((a, b) => b.tokenFee.reliability - a.tokenFee.reliability);
|
|
45
46
|
return selectedBroadcasters;
|
|
46
47
|
}
|
|
47
48
|
static findAllBroadcastersForChain(chain, useRelayAdapt) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"best-broadcaster.js","sourceRoot":"","sources":["../../src/search/best-broadcaster.ts"],"names":[],"mappings":"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","sourcesContent":["import { Chain, SelectedBroadcaster } from '@railgun-community/shared-models';\nimport { BroadcasterFeeCache } from '../fees/broadcaster-fee-cache.js';\nimport { AddressFilter } from '../filters/address-filter.js';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport {\n cachedFeeUnavailableOrExpired,\n shortenAddress,\n} from '../utils/broadcaster-util.js';\nimport { isDefined } from '../utils/is-defined.js';\n\nconst SelectedBroadcasterAscendingFee = (\n a: SelectedBroadcaster,\n b: SelectedBroadcaster,\n) => {\n const feeAmount =\n BigInt(a.tokenFee.feePerUnitGas) - BigInt(b.tokenFee.feePerUnitGas);\n if (feeAmount === BigInt(0)) {\n return 0;\n }\n return feeAmount > BigInt(0) ? 1 : -1;\n};\nexport class BroadcasterSearch {\n static findBroadcastersForToken(\n chain: Chain,\n tokenAddress: string,\n useRelayAdapt: boolean,\n ): Optional<SelectedBroadcaster[]> {\n const tokenAddressLowercase = tokenAddress.toLowerCase();\n const broadcasterTokenFees =\n BroadcasterFeeCache.feesForChain(chain)?.forToken[tokenAddressLowercase]\n ?.forBroadcaster;\n if (!isDefined(broadcasterTokenFees)) {\n return undefined;\n }\n\n const unfilteredAddresses = Object.keys(broadcasterTokenFees);\n const broadcasterAddresses = AddressFilter.filter(unfilteredAddresses);\n if (unfilteredAddresses.length !== broadcasterAddresses.length) {\n const removedAddresses = unfilteredAddresses.filter(\n address => !broadcasterAddresses.includes(address),\n );\n BroadcasterDebug.log(\n `Filtered RAILGUN broadcaster addresses ${\n removedAddresses.length\n }: ${removedAddresses\n .map(address => shortenAddress(address))\n .join(', ')}`,\n );\n }\n\n const selectedBroadcasters: SelectedBroadcaster[] = [];\n\n broadcasterAddresses.forEach((broadcasterAddress: string) => {\n const identifiers: string[] = Object.keys(\n broadcasterTokenFees[broadcasterAddress].forIdentifier,\n );\n identifiers.forEach((identifier: string) => {\n const nextCachedFee =\n broadcasterTokenFees[broadcasterAddress].forIdentifier[identifier];\n if (\n cachedFeeUnavailableOrExpired(nextCachedFee, chain, useRelayAdapt)\n ) {\n return;\n }\n const selectedBroadcaster: SelectedBroadcaster = {\n railgunAddress: broadcasterAddress,\n tokenFee: nextCachedFee,\n tokenAddress,\n };\n selectedBroadcasters.push(selectedBroadcaster);\n });\n });\n\n return selectedBroadcasters;\n }\n\n static findAllBroadcastersForChain(\n chain: Chain,\n useRelayAdapt: boolean,\n ): Optional<SelectedBroadcaster[]> {\n const broadcasterTokenFees =\n BroadcasterFeeCache.feesForChain(chain)?.forToken;\n if (!isDefined(broadcasterTokenFees)) {\n return undefined;\n }\n const allTokens = Object.keys(broadcasterTokenFees);\n const selectedBroadcasters: SelectedBroadcaster[] = [];\n allTokens.forEach((tokenAddress: string) => {\n const broadcastersForToken = this.findBroadcastersForToken(\n chain,\n tokenAddress,\n useRelayAdapt,\n );\n if (!broadcastersForToken) {\n return;\n }\n selectedBroadcasters.push(...broadcastersForToken);\n });\n return selectedBroadcasters;\n }\n\n static findRandomBroadcasterForToken(\n chain: Chain,\n tokenAddress: string,\n useRelayAdapt: boolean,\n percentageThreshold: number,\n ): Optional<SelectedBroadcaster> {\n const broadcasterTokenFees =\n BroadcasterFeeCache.feesForChain(chain)?.forToken;\n if (!isDefined(broadcasterTokenFees)) {\n return undefined;\n }\n\n const broadcastersForToken = this.findBroadcastersForToken(\n chain,\n tokenAddress,\n useRelayAdapt,\n );\n if (!isDefined(broadcastersForToken)) {\n return undefined;\n }\n if (broadcastersForToken.length === 0) {\n return undefined;\n }\n\n const sortedBroadcasters = broadcastersForToken.sort(\n SelectedBroadcasterAscendingFee,\n );\n\n const minFee = BigInt(sortedBroadcasters[0].tokenFee.feePerUnitGas);\n const feeThreshold = (minFee * (100n + BigInt(percentageThreshold))) / 100n;\n const eligibleBroadcasters = sortedBroadcasters.filter(\n broadcaster => BigInt(broadcaster.tokenFee.feePerUnitGas) <= feeThreshold,\n );\n const randomIndex = Math.floor(Math.random() * eligibleBroadcasters.length);\n\n return eligibleBroadcasters[randomIndex];\n }\n\n static findBestBroadcaster(\n chain: Chain,\n tokenAddress: string,\n useRelayAdapt: boolean,\n ): Optional<SelectedBroadcaster> {\n const broadcasterTokenFees =\n BroadcasterFeeCache.feesForChain(chain)?.forToken;\n if (!isDefined(broadcasterTokenFees)) {\n return undefined;\n }\n\n const broadcastersForToken = this.findBroadcastersForToken(\n chain,\n tokenAddress,\n useRelayAdapt,\n );\n if (!isDefined(broadcastersForToken)) {\n return undefined;\n }\n\n const sortedBroadcasters = broadcastersForToken.sort(\n SelectedBroadcasterAscendingFee,\n );\n\n return sortedBroadcasters[0];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"best-broadcaster.js","sourceRoot":"","sources":["../../src/search/best-broadcaster.ts"],"names":[],"mappings":"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","sourcesContent":["import { Chain, SelectedBroadcaster } from '@railgun-community/shared-models';\nimport { BroadcasterFeeCache } from '../fees/broadcaster-fee-cache.js';\nimport { AddressFilter } from '../filters/address-filter.js';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport {\n cachedFeeUnavailableOrExpired,\n shortenAddress,\n} from '../utils/broadcaster-util.js';\nimport { isDefined } from '../utils/is-defined.js';\n\nconst SelectedBroadcasterAscendingFee = (\n a: SelectedBroadcaster,\n b: SelectedBroadcaster,\n) => {\n const feeAmount =\n BigInt(a.tokenFee.feePerUnitGas) - BigInt(b.tokenFee.feePerUnitGas);\n if (feeAmount === BigInt(0)) {\n return 0;\n }\n return feeAmount > BigInt(0) ? 1 : -1;\n};\nexport class BroadcasterSearch {\n static findBroadcastersForToken(\n chain: Chain,\n tokenAddress: string,\n useRelayAdapt: boolean,\n ): Optional<SelectedBroadcaster[]> {\n const tokenAddressLowercase = tokenAddress.toLowerCase();\n const broadcasterTokenFees =\n BroadcasterFeeCache.feesForChain(chain)?.forToken[tokenAddressLowercase]\n ?.forBroadcaster;\n if (!isDefined(broadcasterTokenFees)) {\n return undefined;\n }\n\n const unfilteredAddresses = Object.keys(broadcasterTokenFees);\n const broadcasterAddresses = AddressFilter.filter(unfilteredAddresses);\n if (unfilteredAddresses.length !== broadcasterAddresses.length) {\n const removedAddresses = unfilteredAddresses.filter(\n address => !broadcasterAddresses.includes(address),\n );\n BroadcasterDebug.log(\n `Filtered RAILGUN broadcaster addresses ${\n removedAddresses.length\n }: ${removedAddresses\n .map(address => shortenAddress(address))\n .join(', ')}`,\n );\n }\n\n const selectedBroadcasters: SelectedBroadcaster[] = [];\n\n broadcasterAddresses.forEach((broadcasterAddress: string) => {\n const identifiers: string[] = Object.keys(\n broadcasterTokenFees[broadcasterAddress].forIdentifier,\n );\n identifiers.forEach((identifier: string) => {\n const nextCachedFee =\n broadcasterTokenFees[broadcasterAddress].forIdentifier[identifier];\n if (\n cachedFeeUnavailableOrExpired(nextCachedFee, chain, useRelayAdapt)\n ) {\n return;\n }\n const selectedBroadcaster: SelectedBroadcaster = {\n railgunAddress: broadcasterAddress,\n tokenFee: nextCachedFee,\n tokenAddress,\n };\n selectedBroadcasters.push(selectedBroadcaster);\n });\n });\n\n selectedBroadcasters.sort(\n (a, b) => b.tokenFee.reliability - a.tokenFee.reliability,\n );\n return selectedBroadcasters;\n }\n\n static findAllBroadcastersForChain(\n chain: Chain,\n useRelayAdapt: boolean,\n ): Optional<SelectedBroadcaster[]> {\n const broadcasterTokenFees =\n BroadcasterFeeCache.feesForChain(chain)?.forToken;\n if (!isDefined(broadcasterTokenFees)) {\n return undefined;\n }\n const allTokens = Object.keys(broadcasterTokenFees);\n const selectedBroadcasters: SelectedBroadcaster[] = [];\n allTokens.forEach((tokenAddress: string) => {\n const broadcastersForToken = this.findBroadcastersForToken(\n chain,\n tokenAddress,\n useRelayAdapt,\n );\n if (!broadcastersForToken) {\n return;\n }\n selectedBroadcasters.push(...broadcastersForToken);\n });\n return selectedBroadcasters;\n }\n\n static findRandomBroadcasterForToken(\n chain: Chain,\n tokenAddress: string,\n useRelayAdapt: boolean,\n percentageThreshold: number,\n ): Optional<SelectedBroadcaster> {\n const broadcasterTokenFees =\n BroadcasterFeeCache.feesForChain(chain)?.forToken;\n if (!isDefined(broadcasterTokenFees)) {\n return undefined;\n }\n\n const broadcastersForToken = this.findBroadcastersForToken(\n chain,\n tokenAddress,\n useRelayAdapt,\n );\n if (!isDefined(broadcastersForToken)) {\n return undefined;\n }\n if (broadcastersForToken.length === 0) {\n return undefined;\n }\n\n const sortedBroadcasters = broadcastersForToken.sort(\n SelectedBroadcasterAscendingFee,\n );\n\n const minFee = BigInt(sortedBroadcasters[0].tokenFee.feePerUnitGas);\n const feeThreshold = (minFee * (100n + BigInt(percentageThreshold))) / 100n;\n const eligibleBroadcasters = sortedBroadcasters.filter(\n broadcaster => BigInt(broadcaster.tokenFee.feePerUnitGas) <= feeThreshold,\n );\n const randomIndex = Math.floor(Math.random() * eligibleBroadcasters.length);\n\n return eligibleBroadcasters[randomIndex];\n }\n\n static findBestBroadcaster(\n chain: Chain,\n tokenAddress: string,\n useRelayAdapt: boolean,\n ): Optional<SelectedBroadcaster> {\n const broadcasterTokenFees =\n BroadcasterFeeCache.feesForChain(chain)?.forToken;\n if (!isDefined(broadcasterTokenFees)) {\n return undefined;\n }\n\n const broadcastersForToken = this.findBroadcastersForToken(\n chain,\n tokenAddress,\n useRelayAdapt,\n );\n if (!isDefined(broadcastersForToken)) {\n return undefined;\n }\n\n const sortedBroadcasters = broadcastersForToken.sort(\n SelectedBroadcasterAscendingFee,\n );\n\n return sortedBroadcasters[0];\n }\n}\n"]}
|
|
@@ -14,10 +14,10 @@ var RelayRetryState;
|
|
|
14
14
|
RelayRetryState["Wait"] = "Wait";
|
|
15
15
|
RelayRetryState["Timeout"] = "Timeout";
|
|
16
16
|
})(RelayRetryState || (RelayRetryState = {}));
|
|
17
|
-
const SECONDS_PER_RETRY =
|
|
18
|
-
const POLL_DELAY_SECONDS = 0.
|
|
19
|
-
const RETRY_TRANSACTION_SECONDS =
|
|
20
|
-
const POST_ALERT_TOTAL_WAITING_SECONDS =
|
|
17
|
+
const SECONDS_PER_RETRY = 1.5;
|
|
18
|
+
const POLL_DELAY_SECONDS = 0.1;
|
|
19
|
+
const RETRY_TRANSACTION_SECONDS = 15;
|
|
20
|
+
const POST_ALERT_TOTAL_WAITING_SECONDS = 60;
|
|
21
21
|
export class BroadcasterTransaction {
|
|
22
22
|
messageData;
|
|
23
23
|
contentTopic;
|
|
@@ -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 RelayRetryState {\n RetryTransact = 'RetryTransact',\n Wait = 'Wait',\n Timeout = 'Timeout',\n}\n\ntype RelayMessageData = {\n method: string;\n params: BroadcasterEncryptedMethodParams;\n};\n\n// NOTE: Broadcaster default transaction-send timeout is 45 seconds.\nconst SECONDS_PER_RETRY = 12;\nconst POLL_DELAY_SECONDS = 0.2;\nconst RETRY_TRANSACTION_SECONDS = 45;\nconst POST_ALERT_TOTAL_WAITING_SECONDS = 220;\n\nexport class BroadcasterTransaction {\n private messageData: RelayMessageData;\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 getRelayRetryState(retryNumber: number): RelayRetryState {\n const retrySeconds = retryNumber * SECONDS_PER_RETRY;\n if (retrySeconds <= RETRY_TRANSACTION_SECONDS) {\n return RelayRetryState.RetryTransact;\n }\n if (retrySeconds >= POST_ALERT_TOTAL_WAITING_SECONDS) {\n return RelayRetryState.Timeout;\n }\n return RelayRetryState.Wait;\n }\n\n async send(): Promise<string> {\n return this.relay();\n }\n\n private async relay(retryNumber = 0): Promise<string> {\n const relayRetryState = this.getRelayRetryState(retryNumber);\n switch (relayRetryState) {\n case RelayRetryState.RetryTransact:\n // 0-20 seconds.\n BroadcasterDebug.log(\n `Relay Waku message: ${this.messageData.method} via ${this.contentTopic}`,\n );\n await WakuBroadcasterWakuCore.relayMessage(\n this.messageData,\n this.contentTopic,\n );\n break;\n case RelayRetryState.Wait:\n // 21-60 seconds.\n // Do nothing.\n break;\n case RelayRetryState.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 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 BroadcasterTransactResponse.clearSharedKey();\n throw new Error('Failed to relay transaction on Waku', {\n cause: new Error(response.error),\n });\n }\n }\n\n // Retry.\n return this.relay(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} 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 RelayRetryState {\n RetryTransact = 'RetryTransact',\n Wait = 'Wait',\n Timeout = 'Timeout',\n}\n\ntype RelayMessageData = {\n method: string;\n params: BroadcasterEncryptedMethodParams;\n};\n\n// NOTE: Broadcaster default transaction-send timeout is 45 seconds.\nconst SECONDS_PER_RETRY = 1.5;\nconst POLL_DELAY_SECONDS = 0.1;\nconst RETRY_TRANSACTION_SECONDS = 15;\nconst POST_ALERT_TOTAL_WAITING_SECONDS = 60;\n\nexport class BroadcasterTransaction {\n private messageData: RelayMessageData;\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 getRelayRetryState(retryNumber: number): RelayRetryState {\n const retrySeconds = retryNumber * SECONDS_PER_RETRY;\n if (retrySeconds <= RETRY_TRANSACTION_SECONDS) {\n return RelayRetryState.RetryTransact;\n }\n if (retrySeconds >= POST_ALERT_TOTAL_WAITING_SECONDS) {\n return RelayRetryState.Timeout;\n }\n return RelayRetryState.Wait;\n }\n\n async send(): Promise<string> {\n return this.relay();\n }\n\n private async relay(retryNumber = 0): Promise<string> {\n const relayRetryState = this.getRelayRetryState(retryNumber);\n switch (relayRetryState) {\n case RelayRetryState.RetryTransact:\n // 0-20 seconds.\n BroadcasterDebug.log(\n `Relay Waku message: ${this.messageData.method} via ${this.contentTopic}`,\n );\n await WakuBroadcasterWakuCore.relayMessage(\n this.messageData,\n this.contentTopic,\n );\n break;\n case RelayRetryState.Wait:\n // 21-60 seconds.\n // Do nothing.\n break;\n case RelayRetryState.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 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 BroadcasterTransactResponse.clearSharedKey();\n throw new Error('Failed to relay transaction on Waku', {\n cause: new Error(response.error),\n });\n }\n }\n\n // Retry.\n return this.relay(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": "7.0
|
|
3
|
+
"version": "7.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -32,13 +32,13 @@
|
|
|
32
32
|
"libp2p": "^1.1.2"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@railgun-community/shared-models": "7.0
|
|
36
|
-
"@railgun-community/wallet": "
|
|
35
|
+
"@railgun-community/shared-models": "7.1.0",
|
|
36
|
+
"@railgun-community/wallet": "10.0.2",
|
|
37
37
|
"ethers": "github:Railgun-Community/ethers.js#v6.7.10"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@railgun-community/shared-models": "7.0
|
|
41
|
-
"@railgun-community/wallet": "
|
|
40
|
+
"@railgun-community/shared-models": "7.1.0",
|
|
41
|
+
"@railgun-community/wallet": "10.0.2",
|
|
42
42
|
"ethers": "github:Railgun-Community/ethers.js#v6.7.10",
|
|
43
43
|
"@types/chai": "^4.3.5",
|
|
44
44
|
"@types/chai-as-promised": "^7.1.5",
|