@railgun-community/waku-broadcaster-client-node 8.3.0 → 9.0.1

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.
Files changed (43) hide show
  1. package/README.md +138 -14
  2. package/dist/fees/broadcaster-fee-cache.d.ts +3 -0
  3. package/dist/fees/broadcaster-fee-cache.js +12 -0
  4. package/dist/fees/broadcaster-fee-cache.js.map +1 -1
  5. package/dist/fees/handle-authorized-fees-message.d.ts +2 -0
  6. package/dist/fees/handle-authorized-fees-message.js +39 -0
  7. package/dist/fees/handle-authorized-fees-message.js.map +1 -0
  8. package/dist/fees/handle-fees-message.d.ts +1 -1
  9. package/dist/fees/handle-fees-message.js +34 -3
  10. package/dist/fees/handle-fees-message.js.map +1 -1
  11. package/dist/models/broadcaster-config.d.ts +12 -2
  12. package/dist/models/broadcaster-config.js +6 -0
  13. package/dist/models/broadcaster-config.js.map +1 -1
  14. package/dist/models/constants.d.ts +3 -1
  15. package/dist/models/constants.js +7 -11
  16. package/dist/models/constants.js.map +1 -1
  17. package/dist/models/export-models.d.ts +9 -0
  18. package/dist/models/export-models.js.map +1 -1
  19. package/dist/search/best-broadcaster.d.ts +2 -2
  20. package/dist/search/best-broadcaster.js +31 -4
  21. package/dist/search/best-broadcaster.js.map +1 -1
  22. package/dist/status/broadcaster-connection-status.js +2 -1
  23. package/dist/status/broadcaster-connection-status.js.map +1 -1
  24. package/dist/transact/broadcaster-transact-response.d.ts +1 -1
  25. package/dist/transact/broadcaster-transact-response.js.map +1 -1
  26. package/dist/transact/broadcaster-transaction.js +10 -1
  27. package/dist/transact/broadcaster-transaction.js.map +1 -1
  28. package/dist/utils/broadcaster-debug.js.map +1 -1
  29. package/dist/utils/broadcaster-util.js.map +1 -1
  30. package/dist/utils/is-defined.d.ts +1 -1
  31. package/dist/waku/waku-broadcaster-waku-core-base.d.ts +31 -0
  32. package/dist/waku/waku-broadcaster-waku-core-base.js +168 -0
  33. package/dist/waku/waku-broadcaster-waku-core-base.js.map +1 -0
  34. package/dist/waku/waku-broadcaster-waku-core.d.ts +3 -24
  35. package/dist/waku/waku-broadcaster-waku-core.js +33 -141
  36. package/dist/waku/waku-broadcaster-waku-core.js.map +1 -1
  37. package/dist/waku/waku-observers.d.ts +12 -4
  38. package/dist/waku/waku-observers.js +82 -36
  39. package/dist/waku/waku-observers.js.map +1 -1
  40. package/dist/waku-broadcaster-client.d.ts +4 -6
  41. package/dist/waku-broadcaster-client.js +22 -29
  42. package/dist/waku-broadcaster-client.js.map +1 -1
  43. package/package.json +10 -9
package/README.md CHANGED
@@ -1,22 +1,146 @@
1
- # RAILGUN Broadcaster Client with Waku networking layer
1
+ # RAILGUN Broadcaster Client (Node.js)
2
2
 
3
- This package is meant specifically for Node.js.
3
+ The **Node.js** specific package for the RAILGUN Broadcaster Client. This package is designed to run in server-side environments, scripts, or bots that need to interact with the RAILGUN privacy network via Waku.
4
4
 
5
- `yarn add @railgun-community/waku-broadcaster-client-node`
5
+ ## Installation
6
6
 
7
- ## The Basics
7
+ ```bash
8
+ yarn add @railgun-community/waku-broadcaster-client-node
9
+ # or
10
+ npm install @railgun-community/waku-broadcaster-client-node
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ### 1. Initialization
16
+
17
+ Initialize the client to connect to the Waku network.
8
18
 
9
- ```js
10
- // Initialize the Broadcasting Client
11
- await WakuBroadcastClient.start(...)
19
+ ```typescript
20
+ import { WakuBroadcasterClient } from '@railgun-community/waku-broadcaster-client-node';
21
+ import { Chain } from '@railgun-community/shared-models';
12
22
 
13
- // Wait for connection (5-10 sec) and client to collect accepted gas ratios.
14
- // Broadcasts fees through the privacy-safe Waku network.
23
+ const chain: Chain = { type: 0, id: 1 }; // Ethereum Mainnet
15
24
 
16
- // Get broadcast with lowest fee for a given ERC20 token.
17
- const selectedBroadcast = await WakuBroadcastClient.findBestBroadcast(...)
25
+ const broadcasterOptions = {
26
+ // Required: Trusted Fee Signer
27
+ trustedFeeSigner: '0zk1...',
28
+ // Optional: Waku options
29
+ pubSubTopic: '/waku/2/default-waku/proto',
30
+ feeExpirationTimeout: 30000, // 30 seconds
31
+ peerDiscoveryTimeout: 10000, // 10 seconds
32
+ additionalDirectPeers: [], // Optional: Direct peers to connect to
33
+ poiActiveListKeys: [], // Optional: POI keys
34
+ useDNSDiscovery: false, // Optional: Use DNS discovery
35
+ useCustomDNS: { // Optional: Custom DNS config
36
+ onlyCustom: false,
37
+ enrTreePeers: []
38
+ },
39
+ broadcasterVersionRange: { // Optional: Broadcaster version range
40
+ minVersion: '8.0.0',
41
+ maxVersion: '8.999.0'
42
+ }
43
+ };
18
44
 
19
- // Create transaction and send through selected Broadcaster.
20
- const broadcastTransaction = await BroadcastTransaction.create(...)
21
- await BroadcastTransaction.send(...)
45
+ const statusCallback = (status: BroadcasterConnectionStatus) => {
46
+ console.log('Connection status:', status);
47
+ };
48
+
49
+ await WakuBroadcasterClient.start(chain, broadcasterOptions, statusCallback);
50
+ console.log('Waku Broadcaster Client started');
22
51
  ```
52
+
53
+ ### 2. Finding a Broadcaster
54
+
55
+ Once started, the client listens for fee updates from Broadcasters. You can query for the best broadcaster for a specific token.
56
+
57
+ ```typescript
58
+ import { Chain } from '@railgun-community/shared-models';
59
+
60
+ const chain: Chain = { type: 0, id: 1 }; // Ethereum Mainnet
61
+ const tokenAddress = '0x6b175474e89094c44da98b954eedeac495271d0f'; // DAI
62
+
63
+ // Wait a few seconds for peer discovery and fee updates...
64
+ await new Promise(r => setTimeout(r, 5000));
65
+
66
+ const selectedBroadcaster = await WakuBroadcasterClient.findBestBroadcaster(
67
+ chain,
68
+ tokenAddress
69
+ );
70
+
71
+ if (selectedBroadcaster) {
72
+ console.log('Found broadcaster:', selectedBroadcaster.railgunAddress);
73
+ console.log('Fee per unit gas:', selectedBroadcaster.feePerUnitGas);
74
+ } else {
75
+ console.log('No broadcaster found for this token');
76
+ }
77
+ ```
78
+
79
+ ### 3. Sending a Transaction
80
+
81
+ Create a transaction and send it through the selected broadcaster.
82
+
83
+ ```typescript
84
+ import { BroadcasterTransaction } from '@railgun-community/waku-broadcaster-client-node';
85
+ import { TXIDVersion } from '@railgun-community/shared-models';
86
+
87
+ // ... (Assume you have a railgunWallet and transactionRequest)
88
+
89
+ const txidVersion = TXIDVersion.V2_PoseidonMerkle; // or V3
90
+ const to = '0x...'; // Destination address
91
+ const data = '0x...'; // Transaction data
92
+ const nullifiers = ['0x...']; // Nullifiers
93
+ const overallBatchMinGasPrice = 1000000000n; // Min gas price
94
+ const useRelayAdapt = false; // Whether to use Relay Adapt
95
+ const preTransactionPOIs = {}; // POIs
96
+
97
+ const broadcasterTransaction = await BroadcasterTransaction.create(
98
+ txidVersion,
99
+ to,
100
+ data,
101
+ selectedBroadcaster.railgunAddress,
102
+ selectedBroadcaster.feesID,
103
+ chain,
104
+ nullifiers,
105
+ overallBatchMinGasPrice,
106
+ useRelayAdapt,
107
+ preTransactionPOIs
108
+ );
109
+
110
+ try {
111
+ const response = await BroadcasterTransaction.send(broadcasterTransaction);
112
+ console.log('Transaction submitted. Tx Hash:', response.txHash);
113
+ } catch (error) {
114
+ console.error('Failed to send transaction:', error);
115
+ }
116
+ ```
117
+
118
+ ## Configuration
119
+
120
+ The `start` method accepts a `BroadcasterOptions` object.
121
+
122
+ - `trustedFeeSigner`: (Required) The public key of the trusted fee signer.
123
+ - `poiActiveListKeys`: (Optional) List of active POI list keys.
124
+ - `pubSubTopic`: (Optional) The Waku pubsub topic to subscribe to. Defaults to the RAILGUN topic.
125
+ - `additionalDirectPeers`: (Optional) Array of multiaddrs for direct peer connections.
126
+ - `peerDiscoveryTimeout`: (Optional) Timeout in milliseconds for peer discovery.
127
+ - `feeExpirationTimeout`: (Optional) Timeout in milliseconds for fee expiration.
128
+ - `useDNSDiscovery`: (Optional) Boolean to enable DNS peer discovery.
129
+ - `useCustomDNS`: (Optional) Configuration for custom DNS discovery.
130
+ - `onlyCustom`: (Boolean) If true, only use the provided `enrTreePeers`.
131
+ - `enrTreePeers`: (Array<string>) List of ENR tree URLs.
132
+ - `broadcasterVersionRange`: (Optional) Object specifying the allowed broadcaster version range.
133
+ - `minVersion`: (String) Minimum allowed version.
134
+ - `maxVersion`: (String) Maximum allowed version.
135
+
136
+ ## Dependencies
137
+
138
+ This package relies on:
139
+ - `@waku/sdk`: For Waku networking.
140
+ - `@waku/discovery`: For peer discovery.
141
+ - `@libp2p/tcp`: For TCP transport (Node.js specific).
142
+
143
+ ## License
144
+
145
+ MIT
146
+
@@ -13,6 +13,7 @@ export type BroadcasterFeeCacheState = {
13
13
  };
14
14
  export declare class BroadcasterFeeCache {
15
15
  private static cache;
16
+ private static authorizedFees;
16
17
  static lastSubscribedFeeMessageReceivedAt: Optional<number>;
17
18
  private static poiActiveListKeys;
18
19
  static init(poiActiveListKeys: string[]): void;
@@ -21,5 +22,7 @@ export declare class BroadcasterFeeCache {
21
22
  static feesForChain(chain: Chain): Optional<BroadcasterFeeNetworkCacheMap>;
22
23
  static feesForToken(chain: Chain, tokenAddress: string): Optional<BroadcasterFeeNetworkTokenCacheMap>;
23
24
  static supportsToken(chain: Chain, tokenAddress: string, useRelayAdapt: boolean): boolean;
25
+ static addAuthorizedFees(tokenFeeMap: MapType<CachedTokenFee>): void;
26
+ static getAuthorizedFee(tokenAddress: string): Optional<CachedTokenFee>;
24
27
  }
25
28
  export {};
@@ -5,6 +5,7 @@ import { BroadcasterDebug } from '../utils/broadcaster-debug.js';
5
5
  import { nameForBroadcaster, cachedFeeExpired, DEFAULT_BROADCASTER_IDENTIFIER, invalidBroadcasterVersion, cachedFeeUnavailableOrExpired, } from '../utils/broadcaster-util.js';
6
6
  export class BroadcasterFeeCache {
7
7
  static cache = { forNetwork: {} };
8
+ static authorizedFees = {};
8
9
  static lastSubscribedFeeMessageReceivedAt;
9
10
  static poiActiveListKeys;
10
11
  static init(poiActiveListKeys) {
@@ -80,5 +81,16 @@ export class BroadcasterFeeCache {
80
81
  const availableUnexpiredFee = cachedFees.find(cachedFee => !cachedFeeUnavailableOrExpired(cachedFee, chain, useRelayAdapt));
81
82
  return availableUnexpiredFee != null;
82
83
  }
84
+ static addAuthorizedFees(tokenFeeMap) {
85
+ const newFees = Object.entries(tokenFeeMap);
86
+ const authorizedFees = {};
87
+ for (const [tokenAddress, feeMap] of newFees) {
88
+ authorizedFees[tokenAddress.toLowerCase()] = feeMap;
89
+ }
90
+ this.authorizedFees = authorizedFees;
91
+ }
92
+ static getAuthorizedFee(tokenAddress) {
93
+ return this.authorizedFees[tokenAddress.toLowerCase()];
94
+ }
83
95
  }
84
96
  //# sourceMappingURL=broadcaster-fee-cache.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"broadcaster-fee-cache.js","sourceRoot":"","sources":["../../src/fees/broadcaster-fee-cache.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CachedTokenFee,\n Chain,\n networkForChain,\n} from '@railgun-community/shared-models';\nimport { AddressFilter } from '../filters/address-filter.js';\nimport { BroadcasterConfig } from '../models/broadcaster-config.js';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport {\n nameForBroadcaster,\n cachedFeeExpired,\n DEFAULT_BROADCASTER_IDENTIFIER,\n invalidBroadcasterVersion,\n cachedFeeUnavailableOrExpired,\n} from '../utils/broadcaster-util.js';\n\n// {forNetwork: {forToken: {forBroadcaster: (fee, updatedAt)}}}\ntype BroadcasterFeeNetworkTokenBroadcasterCacheMap = {\n forIdentifier: MapType<CachedTokenFee>;\n};\ntype BroadcasterFeeNetworkTokenCacheMap = {\n forBroadcaster: MapType<BroadcasterFeeNetworkTokenBroadcasterCacheMap>;\n};\ntype BroadcasterFeeNetworkCacheMap = {\n forToken: MapType<BroadcasterFeeNetworkTokenCacheMap>;\n};\nexport type BroadcasterFeeCacheState = {\n forNetwork: MapType<BroadcasterFeeNetworkCacheMap>;\n};\n\nexport class BroadcasterFeeCache {\n private static cache: BroadcasterFeeCacheState = { forNetwork: {} };\n static lastSubscribedFeeMessageReceivedAt: Optional<number>;\n private static poiActiveListKeys: Optional<string[]>;\n\n static init(poiActiveListKeys: string[]) {\n this.poiActiveListKeys = poiActiveListKeys;\n this.lastSubscribedFeeMessageReceivedAt = Date.now();\n }\n\n static addTokenFees(\n chain: Chain,\n railgunAddress: string,\n feeExpiration: number,\n tokenFeeMap: MapType<CachedTokenFee>,\n identifier: Optional<string>,\n version: string,\n requiredPOIListKeys: string[],\n ) {\n const network = networkForChain(chain);\n if (!network) {\n return;\n }\n\n if (!this.poiActiveListKeys) {\n throw new Error(\n 'Must define active POI list keys before adding any fees.',\n );\n }\n for (const listKey of requiredPOIListKeys) {\n if (!this.poiActiveListKeys.includes(listKey)) {\n BroadcasterDebug.log(\n `[Fees] Broadcaster ${railgunAddress} requires POI list key ${listKey}, which is not active.`,\n );\n return;\n }\n }\n\n const broadcasterName = nameForBroadcaster(railgunAddress, identifier);\n const networkName = network.name;\n\n if (invalidBroadcasterVersion(version)) {\n BroadcasterDebug.log(\n `[Fees] Broadcaster version ${version} invalid (req ${BroadcasterConfig.MINIMUM_BROADCASTER_VERSION}-${BroadcasterConfig.MAXIMUM_BROADCASTER_VERSION}): ${broadcasterName}`,\n );\n return;\n }\n\n if (cachedFeeExpired(feeExpiration)) {\n BroadcasterDebug.log(\n `[Fees] Fees expired for ${networkName} (${broadcasterName})`,\n );\n return;\n }\n\n const tokenAddresses = Object.keys(tokenFeeMap);\n BroadcasterDebug.log(\n `[Fees] Updating fees for ${networkName} (${broadcasterName}): ${tokenAddresses.length} tokens`,\n );\n\n this.cache.forNetwork[networkName] ??= { forToken: {} };\n\n const tokenAddressesLowercase = tokenAddresses.map(address =>\n address.toLowerCase(),\n );\n tokenAddressesLowercase.forEach(tokenAddress => {\n this.cache.forNetwork[networkName].forToken[tokenAddress] ??= {\n forBroadcaster: {},\n };\n this.cache.forNetwork[networkName].forToken[tokenAddress].forBroadcaster[\n railgunAddress\n ] ??= { forIdentifier: {} };\n\n this.cache.forNetwork[networkName].forToken[tokenAddress].forBroadcaster[\n railgunAddress\n ].forIdentifier[identifier ?? DEFAULT_BROADCASTER_IDENTIFIER] =\n tokenFeeMap[tokenAddress];\n });\n BroadcasterFeeCache.lastSubscribedFeeMessageReceivedAt = Date.now();\n }\n\n static resetCache(chain: Chain) {\n const network = networkForChain(chain);\n if (!network) {\n return;\n }\n this.cache.forNetwork ??= {};\n delete this.cache.forNetwork[network.name];\n }\n\n static feesForChain(chain: Chain): Optional<BroadcasterFeeNetworkCacheMap> {\n const network = networkForChain(chain);\n if (!network) {\n throw new Error('Chain not found.');\n }\n return this.cache.forNetwork[network.name];\n }\n\n static feesForToken(\n chain: Chain,\n tokenAddress: string,\n ): Optional<BroadcasterFeeNetworkTokenCacheMap> {\n return this.feesForChain(chain)?.forToken[tokenAddress.toLowerCase()];\n }\n\n static supportsToken(\n chain: Chain,\n tokenAddress: string,\n useRelayAdapt: boolean,\n ): boolean {\n const feesForToken = this.feesForToken(chain, tokenAddress);\n if (!feesForToken) {\n return false;\n }\n\n const railgunAddresses = Object.keys(feesForToken.forBroadcaster);\n const filteredRailgunAddresses = AddressFilter.filter(railgunAddresses);\n\n const cachedFees: CachedTokenFee[] = filteredRailgunAddresses\n .map(railgunAddress =>\n Object.values(\n feesForToken.forBroadcaster[railgunAddress].forIdentifier,\n ),\n )\n .flat();\n\n const availableUnexpiredFee = cachedFees.find(\n cachedFee =>\n !cachedFeeUnavailableOrExpired(cachedFee, chain, useRelayAdapt),\n );\n return availableUnexpiredFee != null;\n }\n}\n"]}
1
+ {"version":3,"file":"broadcaster-fee-cache.js","sourceRoot":"","sources":["../../src/fees/broadcaster-fee-cache.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CachedTokenFee,\n Chain,\n networkForChain,\n} from '@railgun-community/shared-models';\nimport { AddressFilter } from '../filters/address-filter.js';\nimport { BroadcasterConfig } from '../models/broadcaster-config.js';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport {\n nameForBroadcaster,\n cachedFeeExpired,\n DEFAULT_BROADCASTER_IDENTIFIER,\n invalidBroadcasterVersion,\n cachedFeeUnavailableOrExpired,\n} from '../utils/broadcaster-util.js';\n\n// {forNetwork: {forToken: {forBroadcaster: (fee, updatedAt)}}}\ntype BroadcasterFeeNetworkTokenBroadcasterCacheMap = {\n forIdentifier: MapType<CachedTokenFee>;\n};\ntype BroadcasterFeeNetworkTokenCacheMap = {\n forBroadcaster: MapType<BroadcasterFeeNetworkTokenBroadcasterCacheMap>;\n};\ntype BroadcasterFeeNetworkCacheMap = {\n forToken: MapType<BroadcasterFeeNetworkTokenCacheMap>;\n};\nexport type BroadcasterFeeCacheState = {\n forNetwork: MapType<BroadcasterFeeNetworkCacheMap>;\n};\n\nexport class BroadcasterFeeCache {\n private static cache: BroadcasterFeeCacheState = { forNetwork: {} };\n private static authorizedFees: MapType<CachedTokenFee> = {};\n static lastSubscribedFeeMessageReceivedAt: Optional<number>;\n private static poiActiveListKeys: Optional<string[]>;\n\n static init(poiActiveListKeys: string[]) {\n this.poiActiveListKeys = poiActiveListKeys;\n this.lastSubscribedFeeMessageReceivedAt = Date.now();\n }\n\n static addTokenFees(\n chain: Chain,\n railgunAddress: string,\n feeExpiration: number,\n tokenFeeMap: MapType<CachedTokenFee>,\n identifier: Optional<string>,\n version: string,\n requiredPOIListKeys: string[],\n ) {\n const network = networkForChain(chain);\n if (!network) {\n return;\n }\n\n if (!this.poiActiveListKeys) {\n throw new Error(\n 'Must define active POI list keys before adding any fees.',\n );\n }\n for (const listKey of requiredPOIListKeys) {\n if (!this.poiActiveListKeys.includes(listKey)) {\n BroadcasterDebug.log(\n `[Fees] Broadcaster ${railgunAddress} requires POI list key ${listKey}, which is not active.`,\n );\n return;\n }\n }\n\n const broadcasterName = nameForBroadcaster(railgunAddress, identifier);\n const networkName = network.name;\n\n if (invalidBroadcasterVersion(version)) {\n BroadcasterDebug.log(\n `[Fees] Broadcaster version ${version} invalid (req ${BroadcasterConfig.MINIMUM_BROADCASTER_VERSION}-${BroadcasterConfig.MAXIMUM_BROADCASTER_VERSION}): ${broadcasterName}`,\n );\n return;\n }\n\n if (cachedFeeExpired(feeExpiration)) {\n BroadcasterDebug.log(\n `[Fees] Fees expired for ${networkName} (${broadcasterName})`,\n );\n return;\n }\n\n const tokenAddresses = Object.keys(tokenFeeMap);\n BroadcasterDebug.log(\n `[Fees] Updating fees for ${networkName} (${broadcasterName}): ${tokenAddresses.length} tokens`,\n );\n\n this.cache.forNetwork[networkName] ??= { forToken: {} };\n\n const tokenAddressesLowercase = tokenAddresses.map(address =>\n address.toLowerCase(),\n );\n tokenAddressesLowercase.forEach(tokenAddress => {\n this.cache.forNetwork[networkName].forToken[tokenAddress] ??= {\n forBroadcaster: {},\n };\n this.cache.forNetwork[networkName].forToken[tokenAddress].forBroadcaster[\n railgunAddress\n ] ??= { forIdentifier: {} };\n\n this.cache.forNetwork[networkName].forToken[tokenAddress].forBroadcaster[\n railgunAddress\n ].forIdentifier[identifier ?? DEFAULT_BROADCASTER_IDENTIFIER] =\n tokenFeeMap[tokenAddress];\n });\n BroadcasterFeeCache.lastSubscribedFeeMessageReceivedAt = Date.now();\n }\n\n static resetCache(chain: Chain) {\n const network = networkForChain(chain);\n if (!network) {\n return;\n }\n this.cache.forNetwork ??= {};\n delete this.cache.forNetwork[network.name];\n }\n\n static feesForChain(chain: Chain): Optional<BroadcasterFeeNetworkCacheMap> {\n const network = networkForChain(chain);\n if (!network) {\n throw new Error('Chain not found.');\n }\n return this.cache.forNetwork[network.name];\n }\n\n static feesForToken(\n chain: Chain,\n tokenAddress: string,\n ): Optional<BroadcasterFeeNetworkTokenCacheMap> {\n return this.feesForChain(chain)?.forToken[tokenAddress.toLowerCase()];\n }\n\n static supportsToken(\n chain: Chain,\n tokenAddress: string,\n useRelayAdapt: boolean,\n ): boolean {\n const feesForToken = this.feesForToken(chain, tokenAddress);\n if (!feesForToken) {\n return false;\n }\n\n const railgunAddresses = Object.keys(feesForToken.forBroadcaster);\n const filteredRailgunAddresses = AddressFilter.filter(railgunAddresses);\n\n const cachedFees: CachedTokenFee[] = filteredRailgunAddresses\n .map(railgunAddress =>\n Object.values(\n feesForToken.forBroadcaster[railgunAddress].forIdentifier,\n ),\n )\n .flat();\n\n const availableUnexpiredFee = cachedFees.find(\n cachedFee =>\n !cachedFeeUnavailableOrExpired(cachedFee, chain, useRelayAdapt),\n );\n return availableUnexpiredFee != null;\n }\n\n static addAuthorizedFees(tokenFeeMap: MapType<CachedTokenFee>) {\n const newFees = Object.entries(tokenFeeMap)\n const authorizedFees: MapType<CachedTokenFee> = {}\n for (const [tokenAddress, feeMap] of newFees) {\n authorizedFees[tokenAddress.toLowerCase()] = feeMap\n }\n this.authorizedFees = authorizedFees\n }\n\n static getAuthorizedFee(tokenAddress: string): Optional<CachedTokenFee> {\n return this.authorizedFees[tokenAddress.toLowerCase()];\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import { BroadcasterFeeMessageData } from '@railgun-community/shared-models';
2
+ export declare const handleAuthorizedFees: (feeMessageData: BroadcasterFeeMessageData) => void;
@@ -0,0 +1,39 @@
1
+ import { BroadcasterDebug } from '../utils/broadcaster-debug.js';
2
+ import { BroadcasterFeeCache } from './broadcaster-fee-cache.js';
3
+ import { cachedFeeExpired } from '../utils/broadcaster-util.js';
4
+ export const handleAuthorizedFees = (feeMessageData) => {
5
+ try {
6
+ if (cachedFeeExpired(feeMessageData.feeExpiration)) {
7
+ return;
8
+ }
9
+ const tokenFeeMap = {};
10
+ const tokenAddresses = Object.keys(feeMessageData.fees);
11
+ tokenAddresses.forEach(tokenAddress => {
12
+ const feePerUnitGas = feeMessageData.fees[tokenAddress];
13
+ if (feePerUnitGas) {
14
+ const existingFee = BroadcasterFeeCache.getAuthorizedFee(tokenAddress.toLowerCase());
15
+ if (existingFee &&
16
+ existingFee.expiration >= feeMessageData.feeExpiration) {
17
+ return;
18
+ }
19
+ const cachedFee = {
20
+ feePerUnitGas,
21
+ expiration: feeMessageData.feeExpiration,
22
+ feesID: feeMessageData.feesID,
23
+ availableWallets: feeMessageData.availableWallets,
24
+ relayAdapt: feeMessageData.relayAdapt,
25
+ reliability: feeMessageData.reliability,
26
+ };
27
+ tokenFeeMap[tokenAddress] = cachedFee;
28
+ }
29
+ });
30
+ if (Object.keys(tokenFeeMap).length > 0) {
31
+ BroadcasterFeeCache.addAuthorizedFees(tokenFeeMap);
32
+ BroadcasterDebug.log('Updated Authorized Fees');
33
+ }
34
+ }
35
+ catch (err) {
36
+ BroadcasterDebug.error(err);
37
+ }
38
+ };
39
+ //# sourceMappingURL=handle-authorized-fees-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle-authorized-fees-message.js","sourceRoot":"","sources":["../../src/fees/handle-authorized-fees-message.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAEhE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,cAAyC,EACzC,EAAE;IACF,IAAI,CAAC;QACH,IAAI,gBAAgB,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,CAAC;YACnD,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAA4B,EAAE,CAAC;QAChD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACxD,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;YACpC,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACxD,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,WAAW,GAAG,mBAAmB,CAAC,gBAAgB,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC;gBACrF,IACE,WAAW;oBACX,WAAW,CAAC,UAAU,IAAI,cAAc,CAAC,aAAa,EACtD,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,MAAM,SAAS,GAAmB;oBAChC,aAAa;oBACb,UAAU,EAAE,cAAc,CAAC,aAAa;oBACxC,MAAM,EAAE,cAAc,CAAC,MAAM;oBAC7B,gBAAgB,EAAE,cAAc,CAAC,gBAAgB;oBACjD,UAAU,EAAE,cAAc,CAAC,UAAU;oBACrC,WAAW,EAAE,cAAc,CAAC,WAAW;iBACxC,CAAC;gBACF,WAAW,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;YACxC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,mBAAmB,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACnD,gBAAgB,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,gBAAgB,CAAC,KAAK,CAAC,GAAY,CAAC,CAAC;IACvC,CAAC;AACH,CAAC,CAAC","sourcesContent":["import {\n BroadcasterFeeMessageData,\n CachedTokenFee,\n} from '@railgun-community/shared-models';\nimport { BroadcasterDebug } from '../utils/broadcaster-debug.js';\nimport { BroadcasterFeeCache } from './broadcaster-fee-cache.js';\nimport { cachedFeeExpired } from '../utils/broadcaster-util.js';\n\nexport const handleAuthorizedFees = (\n feeMessageData: BroadcasterFeeMessageData,\n) => {\n try {\n if (cachedFeeExpired(feeMessageData.feeExpiration)) {\n return;\n }\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 existingFee = BroadcasterFeeCache.getAuthorizedFee(tokenAddress.toLowerCase());\n if (\n existingFee &&\n existingFee.expiration >= feeMessageData.feeExpiration\n ) {\n return;\n }\n\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 if (Object.keys(tokenFeeMap).length > 0) {\n BroadcasterFeeCache.addAuthorizedFees(tokenFeeMap);\n BroadcasterDebug.log('Updated Authorized Fees');\n }\n } catch (err) {\n BroadcasterDebug.error(err as Error);\n }\n};\n"]}
@@ -1,3 +1,3 @@
1
1
  import { Chain } from '@railgun-community/shared-models';
2
- import { IMessage } from '@waku/interfaces';
2
+ import { type IMessage } from '@waku/sdk';
3
3
  export declare const handleBroadcasterFeesMessage: (chain: Chain, message: IMessage, contentTopic: string) => Promise<void>;
@@ -7,6 +7,7 @@ import { BroadcasterFeeCache } from './broadcaster-fee-cache.js';
7
7
  import { invalidBroadcasterVersion } from '../utils/broadcaster-util.js';
8
8
  import { bytesToUtf8, hexToUTF8String } from '../utils/conversion.js';
9
9
  import { isDefined } from '../utils/is-defined.js';
10
+ import { handleAuthorizedFees } from './handle-authorized-fees-message.js';
10
11
  const isExpiredTimestamp = (timestamp, expirationFeeTimestamp) => {
11
12
  if (!timestamp || !expirationFeeTimestamp) {
12
13
  return false;
@@ -17,6 +18,7 @@ const isExpiredTimestamp = (timestamp, expirationFeeTimestamp) => {
17
18
  }
18
19
  const nowTime = Date.now();
19
20
  const expirationMsec = nowTime - 45 * 1000;
21
+ const expirationFeeMsec = nowTime + 45 * 1000;
20
22
  const timestampExpired = messageTimestamp.getTime() < expirationMsec;
21
23
  if (timestampExpired) {
22
24
  BroadcasterDebug.log(`Broadcaster Fee STALE: Difference was ${(Date.now() - messageTimestamp.getTime()) / 1000}s`);
@@ -24,7 +26,8 @@ const isExpiredTimestamp = (timestamp, expirationFeeTimestamp) => {
24
26
  else {
25
27
  BroadcasterDebug.log(`Broadcaster Fee receipt SUCCESS in ${(Date.now() - messageTimestamp.getTime()) / 1000}s`);
26
28
  }
27
- return timestampExpired;
29
+ const feeExpired = expirationFeeTimestamp.getTime() < expirationFeeMsec;
30
+ return timestampExpired && feeExpired;
28
31
  };
29
32
  export const handleBroadcasterFeesMessage = async (chain, message, contentTopic) => {
30
33
  try {
@@ -66,15 +69,41 @@ export const handleBroadcasterFeesMessage = async (chain, message, contentTopic)
66
69
  if (!(cause instanceof Error)) {
67
70
  throw new Error('Unexpected non-error thrown', { cause });
68
71
  }
69
- BroadcasterDebug.error(new Error('Error handling Broadcaster fees', { cause }));
70
72
  }
71
73
  };
72
74
  const updateFeesForBroadcaster = (chain, feeMessageData) => {
73
75
  const tokenFeeMap = {};
74
76
  const tokenAddresses = Object.keys(feeMessageData.fees);
77
+ const isTrustedSigner = BroadcasterConfig.trustedFeeSigner &&
78
+ feeMessageData.railgunAddress.toLowerCase() ===
79
+ BroadcasterConfig.trustedFeeSigner.toLowerCase();
80
+ if (isTrustedSigner) {
81
+ handleAuthorizedFees(feeMessageData);
82
+ }
75
83
  tokenAddresses.forEach(tokenAddress => {
76
84
  const feePerUnitGas = feeMessageData.fees[tokenAddress];
77
85
  if (feePerUnitGas) {
86
+ if (!isTrustedSigner && BroadcasterConfig.trustedFeeSigner) {
87
+ const authorizedFee = BroadcasterFeeCache.getAuthorizedFee(tokenAddress.toLowerCase());
88
+ if (authorizedFee) {
89
+ const authorizedFeeAmount = BigInt(authorizedFee.feePerUnitGas);
90
+ const varianceLower = (authorizedFeeAmount *
91
+ BigInt(Math.round(BroadcasterConfig.authorizedFeeVariancePercentageLower * 100))) /
92
+ 100n;
93
+ const varianceUpper = (authorizedFeeAmount *
94
+ BigInt(Math.round(BroadcasterConfig.authorizedFeeVariancePercentageUpper * 100))) /
95
+ 100n;
96
+ const minFee = authorizedFeeAmount - varianceLower;
97
+ const maxFee = authorizedFeeAmount + varianceUpper;
98
+ const feeAmount = BigInt(feePerUnitGas);
99
+ if (feeAmount < minFee || feeAmount > maxFee) {
100
+ return;
101
+ }
102
+ }
103
+ else {
104
+ return;
105
+ }
106
+ }
78
107
  const cachedFee = {
79
108
  feePerUnitGas,
80
109
  expiration: feeMessageData.feeExpiration,
@@ -86,6 +115,8 @@ const updateFeesForBroadcaster = (chain, feeMessageData) => {
86
115
  tokenFeeMap[tokenAddress] = cachedFee;
87
116
  }
88
117
  });
89
- BroadcasterFeeCache.addTokenFees(chain, feeMessageData.railgunAddress, feeMessageData.feeExpiration, tokenFeeMap, feeMessageData.identifier, feeMessageData.version, feeMessageData.requiredPOIListKeys ?? []);
118
+ if (Object.keys(tokenFeeMap).length > 0) {
119
+ BroadcasterFeeCache.addTokenFees(chain, feeMessageData.railgunAddress, feeMessageData.feeExpiration, tokenFeeMap, feeMessageData.identifier, feeMessageData.version, feeMessageData.requiredPOIListKeys ?? []);
120
+ }
90
121
  };
91
122
  //# sourceMappingURL=handle-fees-message.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"handle-fees-message.js","sourceRoot":"","sources":["../../src/fees/handle-fees-message.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,2BAA2B,CAAC;AAMnC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,kBAAkB,GAAG,CACzB,SAAyB,EACzB,sBAAsC,EACtC,EAAE;IACF,IAAI,CAAC,SAAS,IAAI,CAAC,sBAAsB,EAAE;QACzC,OAAO,KAAK,CAAC;KACd;IACD,IAAI,gBAAgB,GAAG,SAAS,CAAC;IACjC,IAAI,gBAAgB,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;QAE3C,gBAAgB,GAAG,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;KAChE;IAGD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC3B,MAAM,cAAc,GAAG,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC;IAE3C,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,OAAO,EAAE,GAAG,cAAc,CAAC;IACrE,IAAI,gBAAgB,EAAE;QACpB,gBAAgB,CAAC,GAAG,CAClB,yCACE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,CAAC,OAAO,EAAE,CAAC,GAAG,IAC9C,GAAG,CACJ,CAAC;KACH;SAAM;QACL,gBAAgB,CAAC,GAAG,CAClB,sCACE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,CAAC,OAAO,EAAE,CAAC,GAAG,IAC9C,GAAG,CACJ,CAAC;KACH;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,4BAA4B,GAAG,KAAK,EAC/C,KAAY,EACZ,OAAiB,EACjB,YAAoB,EACpB,EAAE;IACF,IAAI;QACF,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;YAC/B,gBAAgB,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;YACtE,OAAO;SACR;QACD,IAAI,YAAY,KAAK,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;YAC9C,gBAAgB,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;YACvE,OAAO;SACR;QACD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAG7C,CAAC;QACF,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAA8B,CAAC;QAC3E,MAAM,iBAAiB,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QACjE,IAAI,kBAAkB,CAAC,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE;YAC5D,gBAAgB,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;YACjE,OAAO;SACR;QAED,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,iBAAiB,CAAC,MAAM,EAAE;YACzD,gBAAgB,CAAC,GAAG,CAClB,mHAAmH,CACpH,CAAC;YACF,wBAAwB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;YAChD,OAAO;SACR;QAED,IAAI,yBAAyB,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE;YACrD,gBAAgB,CAAC,GAAG,CAClB,+CAA+C,cAAc,CAAC,OAAO,KAAK,cAAc,CAAC,cAAc,EAAE,CAC1G,CAAC;YACF,OAAO;SACR;QAED,MAAM,EAAE,cAAc,EAAE,GAAG,cAAc,CAAC;QAC1C,MAAM,EAAE,gBAAgB,EAAE,GAAG,2BAA2B,CAAC,cAAc,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,MAAM,0BAA0B,CAC/C,SAAS,EACT,IAAI,EACJ,gBAAgB,CACjB,CAAC;QACF,IAAI,CAAC,QAAQ,EAAE;YACb,OAAO;SACR;QAED,wBAAwB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;KACjD;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE;YAC7B,MAAM,IAAI,KAAK,CAAC,6BAA6B,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;SAC3D;QAED,gBAAgB,CAAC,KAAK,CACpB,IAAI,KAAK,CAAC,iCAAiC,EAAE,EAAE,KAAK,EAAE,CAAC,CACxD,CAAC;KACH;AACH,CAAC,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAC/B,KAAY,EACZ,cAAyC,EACzC,EAAE;IACF,MAAM,WAAW,GAA4B,EAAE,CAAC;IAChD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IACxD,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;QACpC,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACxD,IAAI,aAAa,EAAE;YACjB,MAAM,SAAS,GAAmB;gBAChC,aAAa;gBACb,UAAU,EAAE,cAAc,CAAC,aAAa;gBACxC,MAAM,EAAE,cAAc,CAAC,MAAM;gBAC7B,gBAAgB,EAAE,cAAc,CAAC,gBAAgB;gBACjD,UAAU,EAAE,cAAc,CAAC,UAAU;gBACrC,WAAW,EAAE,cAAc,CAAC,WAAW;aACxC,CAAC;YACF,WAAW,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;SACvC;IACH,CAAC,CAAC,CAAC;IAEH,mBAAmB,CAAC,YAAY,CAC9B,KAAK,EACL,cAAc,CAAC,cAAc,EAC7B,cAAc,CAAC,aAAa,EAC5B,WAAW,EACX,cAAc,CAAC,UAAU,EACzB,cAAc,CAAC,OAAO,EACtB,cAAc,CAAC,mBAAmB,IAAI,EAAE,CACzC,CAAC;AACJ,CAAC,CAAC","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 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"]}
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 { type IMessage } from '@waku/sdk';\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';\nimport { handleAuthorizedFees } from './handle-authorized-fees-message.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. -- should be no longer an issue. \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 ${(Date.now() - messageTimestamp.getTime()) / 1000\n }s`,\n );\n } else {\n BroadcasterDebug.log(\n `Broadcaster Fee receipt SUCCESS in ${(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 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};\n\nconst updateFeesForBroadcaster = (\n chain: Chain,\n feeMessageData: BroadcasterFeeMessageData,\n) => {\n const tokenFeeMap: MapType<CachedTokenFee> = {};\n const tokenAddresses = Object.keys(feeMessageData.fees);\n\n const isTrustedSigner =\n BroadcasterConfig.trustedFeeSigner &&\n feeMessageData.railgunAddress.toLowerCase() ===\n BroadcasterConfig.trustedFeeSigner.toLowerCase();\n\n if (isTrustedSigner) {\n handleAuthorizedFees(feeMessageData);\n }\n\n tokenAddresses.forEach(tokenAddress => {\n const feePerUnitGas = feeMessageData.fees[tokenAddress];\n if (feePerUnitGas) {\n if (!isTrustedSigner && BroadcasterConfig.trustedFeeSigner) {\n const authorizedFee = BroadcasterFeeCache.getAuthorizedFee(\n tokenAddress.toLowerCase(),\n );\n if (authorizedFee) {\n const authorizedFeeAmount = BigInt(authorizedFee.feePerUnitGas);\n const varianceLower =\n (authorizedFeeAmount *\n BigInt(\n Math.round(\n BroadcasterConfig.authorizedFeeVariancePercentageLower * 100,\n ),\n )) /\n 100n;\n const varianceUpper =\n (authorizedFeeAmount *\n BigInt(\n Math.round(\n BroadcasterConfig.authorizedFeeVariancePercentageUpper * 100,\n ),\n )) /\n 100n;\n const minFee = authorizedFeeAmount - varianceLower;\n const maxFee = authorizedFeeAmount + varianceUpper;\n\n const feeAmount = BigInt(feePerUnitGas);\n if (feeAmount < minFee || feeAmount > maxFee) {\n return;\n }\n } else {\n // No authorized fee, and we require one.\n return;\n }\n }\n\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 if (Object.keys(tokenFeeMap).length > 0) {\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};\n"]}
@@ -1,5 +1,15 @@
1
+ export type CustomDNSConfig = {
2
+ onlyCustom: boolean;
3
+ enrTreePeers: string[];
4
+ };
1
5
  export declare class BroadcasterConfig {
2
6
  static IS_DEV: boolean;
3
- static readonly MINIMUM_BROADCASTER_VERSION = "8.0.0";
4
- static readonly MAXIMUM_BROADCASTER_VERSION = "8.999.0";
7
+ static trustedFeeSigner: string;
8
+ static feeExpirationTimeout: number;
9
+ static authorizedFeeVariancePercentageLower: number;
10
+ static authorizedFeeVariancePercentageUpper: number;
11
+ static MINIMUM_BROADCASTER_VERSION: string;
12
+ static MAXIMUM_BROADCASTER_VERSION: string;
13
+ static useDNSDiscovery: boolean;
14
+ static customDNS: CustomDNSConfig | undefined;
5
15
  }
@@ -1,6 +1,12 @@
1
1
  export class BroadcasterConfig {
2
2
  static IS_DEV = false;
3
+ static trustedFeeSigner;
4
+ static feeExpirationTimeout = 120_000;
5
+ static authorizedFeeVariancePercentageLower = 0.10;
6
+ static authorizedFeeVariancePercentageUpper = 0.30;
3
7
  static MINIMUM_BROADCASTER_VERSION = '8.0.0';
4
8
  static MAXIMUM_BROADCASTER_VERSION = '8.999.0';
9
+ static useDNSDiscovery = false;
10
+ static customDNS = undefined;
5
11
  }
6
12
  //# sourceMappingURL=broadcaster-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"broadcaster-config.js","sourceRoot":"","sources":["../../src/models/broadcaster-config.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,iBAAiB;IAC5B,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;IAEtB,MAAM,CAAU,2BAA2B,GAAG,OAAO,CAAC;IACtD,MAAM,CAAU,2BAA2B,GAAG,SAAS,CAAC","sourcesContent":["export class BroadcasterConfig {\n static IS_DEV = false;\n\n static readonly MINIMUM_BROADCASTER_VERSION = '8.0.0';\n static readonly MAXIMUM_BROADCASTER_VERSION = '8.999.0';\n}\n"]}
1
+ {"version":3,"file":"broadcaster-config.js","sourceRoot":"","sources":["../../src/models/broadcaster-config.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,iBAAiB;IAC5B,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;IAEtB,MAAM,CAAC,gBAAgB,CAAS;IAEhC,MAAM,CAAC,oBAAoB,GAAG,OAAO,CAAC;IAEtC,MAAM,CAAC,oCAAoC,GAAG,IAAI,CAAC;IACnD,MAAM,CAAC,oCAAoC,GAAG,IAAI,CAAC;IAEnD,MAAM,CAAC,2BAA2B,GAAG,OAAO,CAAC;IAC7C,MAAM,CAAC,2BAA2B,GAAG,SAAS,CAAC;IAE/C,MAAM,CAAC,eAAe,GAAG,KAAK,CAAA;IAC9B,MAAM,CAAC,SAAS,GAAgC,SAAS,CAAA","sourcesContent":["export type CustomDNSConfig = {\n onlyCustom: boolean,\n enrTreePeers: string[]\n}\nexport class BroadcasterConfig {\n static IS_DEV = false;\n\n static trustedFeeSigner: string;\n\n static feeExpirationTimeout = 120_000; // 2 minutes\n\n static authorizedFeeVariancePercentageLower = 0.10; // 10% lower variance\n static authorizedFeeVariancePercentageUpper = 0.30; // 30% upper variance\n\n static MINIMUM_BROADCASTER_VERSION = '8.0.0';\n static MAXIMUM_BROADCASTER_VERSION = '8.999.0';\n\n static useDNSDiscovery = false\n static customDNS: CustomDNSConfig | undefined = undefined\n}\n"]}
@@ -1,7 +1,9 @@
1
- export declare const WAKU_RAILGUN_PUB_SUB_TOPIC = "/waku/2/rs/0/1";
1
+ export declare const WAKU_RAILGUN_PUB_SUB_TOPIC = "/waku/2/rs/1/1";
2
2
  export declare const WAKU_RAILGUN_DEFAULT_SHARD: {
3
3
  clusterId: number;
4
4
  shard: number;
5
+ shardId: number;
6
+ pubsubTopic: string;
5
7
  };
6
8
  export declare const WAKU_RAILGUN_DEFAULT_SHARDS: {
7
9
  clusterId: number;
@@ -1,18 +1,14 @@
1
- export const WAKU_RAILGUN_PUB_SUB_TOPIC = '/waku/2/rs/0/1';
1
+ export const WAKU_RAILGUN_PUB_SUB_TOPIC = '/waku/2/rs/1/1';
2
2
  export const WAKU_RAILGUN_DEFAULT_SHARD = {
3
- clusterId: 0,
3
+ clusterId: 1,
4
4
  shard: 1,
5
+ shardId: 1,
6
+ pubsubTopic: WAKU_RAILGUN_PUB_SUB_TOPIC,
5
7
  };
6
8
  export const WAKU_RAILGUN_DEFAULT_SHARDS = {
7
- clusterId: 0,
9
+ clusterId: 1,
8
10
  shards: [0, 1, 2, 3, 4, 5],
9
11
  };
10
- export const WAKU_RAILGUN_DEFAULT_PEERS_WEB = [
11
- '/dns4/core.rootedinprivacy.com/tcp/8000/wss/p2p/16Uiu2HAm4Ai1GzKv4EykU26ST1BPT4AHtABsYCLKrDG74GWX7D6H',
12
- '/dns4/fleet.rootedinprivacy.com/tcp/8000/wss/p2p/16Uiu2HAm3GnUDQhBfax298CMkZX9MBHTJ9B8GXhrbueozESUaRZP',
13
- ];
14
- export const WAKU_RAILGUN_DEFAULT_PEERS_NODE = [
15
- '/dns4/core.rootedinprivacy.com/tcp/60000/p2p/16Uiu2HAm4Ai1GzKv4EykU26ST1BPT4AHtABsYCLKrDG74GWX7D6H',
16
- '/dns4/fleet.rootedinprivacy.com/tcp/60000/p2p/16Uiu2HAm3GnUDQhBfax298CMkZX9MBHTJ9B8GXhrbueozESUaRZP',
17
- ];
12
+ export const WAKU_RAILGUN_DEFAULT_PEERS_WEB = [];
13
+ export const WAKU_RAILGUN_DEFAULT_PEERS_NODE = [];
18
14
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/models/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,0BAA0B,GAAG,gBAAgB,CAAC;AAE3D,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,SAAS,EAAE,CAAC;IACZ,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,SAAS,EAAE,CAAC;IACZ,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GAAa;IAEtD,uGAAuG;IACvG,wGAAwG;CACzG,CAAC;AAEF,MAAM,CAAC,MAAM,+BAA+B,GAAa;IAEvD,oGAAoG;IACpG,qGAAqG;CACtG,CAAC","sourcesContent":["export const WAKU_RAILGUN_PUB_SUB_TOPIC = '/waku/2/rs/0/1';\n\nexport const WAKU_RAILGUN_DEFAULT_SHARD = {\n clusterId: 0,\n shard: 1,\n};\n\nexport const WAKU_RAILGUN_DEFAULT_SHARDS = {\n clusterId: 0,\n shards: [0, 1, 2, 3, 4, 5],\n};\n\nexport const WAKU_RAILGUN_DEFAULT_PEERS_WEB: string[] = [\n // Some Websocket broadcasters (web friendly):\n '/dns4/core.rootedinprivacy.com/tcp/8000/wss/p2p/16Uiu2HAm4Ai1GzKv4EykU26ST1BPT4AHtABsYCLKrDG74GWX7D6H',\n '/dns4/fleet.rootedinprivacy.com/tcp/8000/wss/p2p/16Uiu2HAm3GnUDQhBfax298CMkZX9MBHTJ9B8GXhrbueozESUaRZP',\n];\n\nexport const WAKU_RAILGUN_DEFAULT_PEERS_NODE: string[] = [\n // Some TCP broadcasters (node friendly):\n '/dns4/core.rootedinprivacy.com/tcp/60000/p2p/16Uiu2HAm4Ai1GzKv4EykU26ST1BPT4AHtABsYCLKrDG74GWX7D6H',\n '/dns4/fleet.rootedinprivacy.com/tcp/60000/p2p/16Uiu2HAm3GnUDQhBfax298CMkZX9MBHTJ9B8GXhrbueozESUaRZP',\n];\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/models/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,0BAA0B,GAAG,gBAAgB,CAAC;AAE3D,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,SAAS,EAAE,CAAC;IACZ,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;IACV,WAAW,EAAE,0BAA0B;CACxC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,SAAS,EAAE,CAAC;IACZ,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GAAa,EAEvD,CAAC;AAEF,MAAM,CAAC,MAAM,+BAA+B,GAAa,EAExD,CAAC","sourcesContent":["export const WAKU_RAILGUN_PUB_SUB_TOPIC = '/waku/2/rs/1/1';\n\nexport const WAKU_RAILGUN_DEFAULT_SHARD = {\n clusterId: 1,\n shard: 1,\n shardId: 1,\n pubsubTopic: WAKU_RAILGUN_PUB_SUB_TOPIC,\n};\n\nexport const WAKU_RAILGUN_DEFAULT_SHARDS = {\n clusterId: 1,\n shards: [0, 1, 2, 3, 4, 5],\n};\n\nexport const WAKU_RAILGUN_DEFAULT_PEERS_WEB: string[] = [\n // Some Websocket broadcasters (web friendly):\n];\n\nexport const WAKU_RAILGUN_DEFAULT_PEERS_NODE: string[] = [\n // Some TCP broadcasters (node friendly):\n];\n"]}
@@ -1,9 +1,18 @@
1
1
  import { Chain, BroadcasterConnectionStatus } from '@railgun-community/shared-models';
2
+ import type { CustomDNSConfig } from './broadcaster-config.js';
2
3
  export type BroadcasterOptions = {
4
+ trustedFeeSigner: string;
3
5
  poiActiveListKeys?: string[];
4
6
  pubSubTopic?: string;
5
7
  additionalDirectPeers?: string[];
6
8
  peerDiscoveryTimeout?: number;
9
+ feeExpirationTimeout?: number;
10
+ useDNSDiscovery?: boolean;
11
+ useCustomDNS?: CustomDNSConfig;
12
+ broadcasterVersionRange?: {
13
+ minVersion: string;
14
+ maxVersion: string;
15
+ };
7
16
  };
8
17
  export type BroadcasterConnectionStatusCallback = (chain: Chain, status: BroadcasterConnectionStatus) => void;
9
18
  export type BroadcasterDebugger = {
@@ -1 +1 @@
1
- {"version":3,"file":"export-models.js","sourceRoot":"","sources":["../../src/models/export-models.ts"],"names":[],"mappings":"","sourcesContent":["import {\n Chain,\n BroadcasterConnectionStatus,\n} from '@railgun-community/shared-models';\n\nexport type BroadcasterOptions = {\n poiActiveListKeys?: string[];\n pubSubTopic?: string;\n additionalDirectPeers?: string[];\n peerDiscoveryTimeout?: number;\n};\n\nexport type BroadcasterConnectionStatusCallback = (\n chain: Chain,\n status: BroadcasterConnectionStatus,\n) => void;\n\nexport type BroadcasterDebugger = {\n log: (msg: string) => void;\n error: (error: Error) => void;\n};\n"]}
1
+ {"version":3,"file":"export-models.js","sourceRoot":"","sources":["../../src/models/export-models.ts"],"names":[],"mappings":"","sourcesContent":["import {\n Chain,\n BroadcasterConnectionStatus,\n} from '@railgun-community/shared-models';\nimport type { CustomDNSConfig } from './broadcaster-config.js';\n\nexport type BroadcasterOptions = {\n trustedFeeSigner: string;\n poiActiveListKeys?: string[];\n pubSubTopic?: string;\n additionalDirectPeers?: string[];\n peerDiscoveryTimeout?: number;\n feeExpirationTimeout?: number;\n useDNSDiscovery?: boolean;\n useCustomDNS?: CustomDNSConfig,\n broadcasterVersionRange?: {\n minVersion: string;\n maxVersion: string;\n };\n};\n\nexport type BroadcasterConnectionStatusCallback = (\n chain: Chain,\n status: BroadcasterConnectionStatus,\n) => void;\n\nexport type BroadcasterDebugger = {\n log: (msg: string) => void;\n error: (error: Error) => void;\n};\n"]}
@@ -1,7 +1,7 @@
1
1
  import { Chain, SelectedBroadcaster } from '@railgun-community/shared-models';
2
2
  export declare class BroadcasterSearch {
3
- static findBroadcastersForToken(chain: Chain, tokenAddress: string, useRelayAdapt: boolean): Optional<SelectedBroadcaster[]>;
4
- static findAllBroadcastersForChain(chain: Chain, useRelayAdapt: boolean): Optional<SelectedBroadcaster[]>;
3
+ static findBroadcastersForToken(chain: Chain, tokenAddress: string, useRelayAdapt: boolean, ignoreMissingAuthorizedFee?: boolean): Optional<SelectedBroadcaster[]>;
4
+ static findAllBroadcastersForChain(chain: Chain, useRelayAdapt: boolean, ignoreMissingAuthorizedFee?: boolean): Optional<SelectedBroadcaster[]>;
5
5
  static findRandomBroadcasterForToken(chain: Chain, tokenAddress: string, useRelayAdapt: boolean, percentageThreshold: number): Optional<SelectedBroadcaster>;
6
6
  static findBestBroadcaster(chain: Chain, tokenAddress: string, useRelayAdapt: boolean): Optional<SelectedBroadcaster>;
7
7
  }