Skip to content

Commit 55eff93

Browse files
authored
Merge branch 'main' into ds/v7-exchange-rate-release
2 parents a443913 + 2e68788 commit 55eff93

File tree

9 files changed

+120
-36
lines changed

9 files changed

+120
-36
lines changed

src/components/CCIP/Drawer/LaneDrawer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ function LaneDrawer({
9696
Rate limit capacity
9797
<Tooltip
9898
label=""
99-
tip="Rate limit data is currently unavailable. You can find this Token Pool rate limit by reading the Token Pool contract directly on the relevant blockchain."
99+
tip="Maximum amount per transaction"
100100
labelStyle={{
101101
marginRight: "5px",
102102
}}

src/components/CCIP/Drawer/TokenDrawer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ function TokenDrawer({
163163
Rate limit capacity
164164
<Tooltip
165165
label=""
166-
tip="Rate limit data is currently unavailable. You can find this Token Pool rate limit by reading the Token Pool contract directly on the relevant blockchain."
166+
tip="Maximum amount per transaction"
167167
labelStyle={{
168168
marginRight: "5px",
169169
}}

src/content/chainlink-nodes/v1/node-config.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,7 +1534,7 @@ PeerID = '12D3KooWMoejJznyDuEk5aX6GvbjaG12UzeornPCBNzMRqdwrFJw' # Example
15341534
TraceLogging = false # Default
15351535
```
15361536

1537-
P2P has a versioned networking stack. Currenly only `[P2P.V2]` is supported.
1537+
P2P has a versioned networking stack. Currently only `[P2P.V2]` is supported.
15381538
All nodes in the OCR network should share the same networking stack.
15391539

15401540
### IncomingMessageBufferSize
@@ -17026,7 +17026,7 @@ SenderAddress is optional and can be set to a specific sender address for gas li
1702617026
If you are using gas limit estimation:
1702717027

1702817028
- Setting SenderAddress is optional for most products. If it is set, the from address for the transaction for gas estimation will be set to the inputted SenderAddress. If it is not set, the actual address the transaction is sent from is used if available.
17029-
- Setting SenderAddress is neccessary for gas limit estimation to function correctly for CCIP. Gas limit estimation works only in CCIP 1.6 and above if SenderAddress is set to the given example value (0x00c11c11c11C11c11C11c11c11C11C11c11C11c1). This value is hardcoded in the CCIP 1.6 contracts and is not needed for other products.
17029+
- Setting SenderAddress is necessary for gas limit estimation to function correctly for CCIP. Gas limit estimation works only in CCIP 1.6 and above if SenderAddress is set to the given example value (0x00c11c11c11C11c11C11c11c11C11C11c11C11c1). This value is hardcoded in the CCIP 1.6 contracts and is not needed for other products.
1703017030

1703117031
### BumpMin
1703217032

@@ -17110,7 +17110,7 @@ In EIP-1559 mode, the following changes occur to how configuration works:
1711017110
- All new transactions will be sent as type 0x2 transactions specifying a TipCap and FeeCap. Be aware that existing pending legacy transactions will continue to be gas bumped in legacy mode.
1711117111
- `BlockHistoryEstimator` will apply its calculations (gas percentile etc) to the TipCap and this value will be used for new transactions (GasPrice will be ignored)
1711217112
- `FixedPriceEstimator` will use `GasTipCapDefault` instead of `GasPriceDefault` for the tip cap
17113-
- `FixedPriceEstimator` will use `GasFeeCapDefault` instaed of `GasPriceDefault` for the fee cap
17113+
- `FixedPriceEstimator` will use `GasFeeCapDefault` instead of `GasPriceDefault` for the fee cap
1711417114
- `PriceMin` is ignored for new transactions and `GasTipCapMinimum` is used instead (default 0)
1711517115
- `PriceMax` still represents that absolute upper limit that Chainlink will ever spend (total) on a single tx
1711617116
- `Keeper.GasTipCapBufferPercent` is ignored in EIP-1559 mode and `Keeper.GasTipCapBufferPercent` is used instead

src/content/data-streams/reference/report-schema-v10.mdx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,21 @@ Chainlink Backed xStock Data Streams adhere to the report schema outlined below.
1919

2020
### Schema Fields
2121

22-
| Field | Type | Description |
23-
| ----------------------- | --------- | -------------------------------------------------------------------------------------------------------------------- |
24-
| `feedId` | `bytes32` | Unique identifier for the Data Streams feed |
25-
| `validFromTimestamp` | `uint32` | Earliest timestamp when the price is valid (seconds) |
26-
| `observationsTimestamp` | `uint32` | Latest timestamp when the price is valid (seconds) |
27-
| `nativeFee` | `uint192` | Cost to verify report onchain (native token) |
28-
| `linkFee` | `uint192` | Cost to verify report onchain (LINK) |
29-
| `expiresAt` | `uint32` | Expiration date of the report (seconds) |
30-
| `lastUpdateTimestamp` | `uint64` | Timestamp of the last valid price update (nanoseconds) |
31-
| `price` | `int192` | Last traded price from the real-world equity market |
32-
| `marketStatus` | `uint32` | Status of the real-world equity market. <br/> Possible values: `0` (Unknown), `1` (Closed), `2` (Open), `3` (Halted) |
33-
| `currentMultiplier` | `int192` | Currently applied multiplier accounting for past corporate actions |
34-
| `newMultiplier` | `int192` | Multiplier to be applied at the activationDateTime <br/> (set to `0` if none is scheduled) |
35-
| `activationDateTime` | `uint32` | When the next corporate action takes effect <br/> (set to `0` if none is scheduled) (seconds) |
36-
| `tokenizedPrice` | `int192` | 24/7 tokenized equity price as traded on supported exchanges <br/> (In development; currently returns `0`). |
22+
| Field | Type | Description |
23+
| ----------------------- | --------- | ----------------------------------------------------------------------------------------------------------- |
24+
| `feedId` | `bytes32` | Unique identifier for the Data Streams feed |
25+
| `validFromTimestamp` | `uint32` | Earliest timestamp when the price is valid (seconds) |
26+
| `observationsTimestamp` | `uint32` | Latest timestamp when the price is valid (seconds) |
27+
| `nativeFee` | `uint192` | Cost to verify report onchain (native token) |
28+
| `linkFee` | `uint192` | Cost to verify report onchain (LINK) |
29+
| `expiresAt` | `uint32` | Expiration date of the report (seconds) |
30+
| `lastUpdateTimestamp` | `uint64` | Timestamp of the last valid price update (nanoseconds) |
31+
| `price` | `int192` | Last traded price from the real-world equity market |
32+
| `marketStatus` | `uint32` | Status of the real-world equity market. <br/> Possible values: `0` (Unknown), `1` (Closed), `2` (Open) |
33+
| `currentMultiplier` | `int192` | Currently applied multiplier accounting for past corporate actions |
34+
| `newMultiplier` | `int192` | Multiplier to be applied at the activationDateTime <br/> (set to `0` if none is scheduled) |
35+
| `activationDateTime` | `uint32` | When the next corporate action takes effect <br/> (set to `0` if none is scheduled) (seconds) |
36+
| `tokenizedPrice` | `int192` | 24/7 tokenized equity price as traded on supported exchanges <br/> (In development; currently returns `0`). |
3737

3838
**Notes:**
3939

src/pages/api/ccip/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export interface ChainDetails {
3939
tokenPoolFactory?: string
4040
feeQuoter?: string
4141
rmnPermeable?: boolean
42+
mcms?: string
4243
}
4344

4445
export type ChainApiResponse = {

src/pages/api/ccip/utils.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ChainsConfig, Environment, loadReferenceData, Version } from "@config/d
44
import { SupportedChain } from "@config/index.ts"
55
import { directoryToSupportedChain } from "@features/utils/index.ts"
66
import { v4 as uuidv4 } from "uuid"
7-
import type { TokenMetadata } from "./types/index.ts"
7+
import type { TokenMetadata, ChainType, OutputKeyType } from "./types/index.ts"
88

99
export const prerender = false
1010

@@ -264,6 +264,16 @@ export const validateOutputKey = (outputKey?: string): "chainId" | "selector" |
264264
return outputKey as "chainId" | "selector" | "internalId"
265265
}
266266

267+
export const generateChainKey = (chainId: number | string, chainType: ChainType, outputKey: OutputKeyType): string => {
268+
const chainIdStr = chainId.toString()
269+
270+
if (outputKey === "chainId" && chainType !== "evm" && chainType !== "solana") {
271+
return `${chainType}-${chainIdStr}`
272+
}
273+
274+
return chainIdStr
275+
}
276+
267277
/**
268278
* Handles API errors and converts them to standardized responses
269279
* @param error - Error to handle

src/pages/api/ccip/v1/chains.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
validateEnvironment,
44
validateFilters,
55
validateOutputKey,
6+
generateChainKey,
67
createMetadata,
78
handleApiError,
89
successHeaders,
@@ -90,7 +91,12 @@ export const GET: APIRoute = async ({ request }) => {
9091
(acc, [family, chainList]) => {
9192
acc[family] = chainList.reduce(
9293
(familyAcc, chain) => {
93-
const key = outputKey ? chain[outputKey].toString() : chain.internalId
94+
const key =
95+
outputKey === "chainId"
96+
? generateChainKey(chain.chainId, chain.chainType, outputKey)
97+
: outputKey
98+
? chain[outputKey].toString()
99+
: chain.internalId
94100
familyAcc[key] = chain
95101
return familyAcc
96102
},

src/pages/api/services/chain-data.ts

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -305,17 +305,84 @@ class SolanaChainStrategy extends BaseChainStrategy {
305305
}
306306
}
307307

308-
// Strategy Factory
308+
class AptosChainStrategy extends BaseChainStrategy {
309+
private static readonly REQUIRED_FIELDS = {
310+
tokenAdminRegistry: (config: ChainsConfig[string]) => !config.tokenAdminRegistry?.address,
311+
mcms: (config: ChainsConfig[string]) => !config.mcms?.address,
312+
} as const
313+
314+
validateChainData(
315+
chainId: number | string | undefined,
316+
networkId: string,
317+
chainConfig: ChainsConfig[string],
318+
selectorEntry?: { selector: string; name: string },
319+
supportedChain?: SupportedChain
320+
): {
321+
isValid: boolean
322+
missingFields: string[]
323+
validatedData?: ChainDetails
324+
} {
325+
const baseValidation = this.validateBaseFields(chainId, networkId, chainConfig, selectorEntry, supportedChain)
326+
327+
if (!baseValidation.isValid || !baseValidation.baseData) {
328+
return {
329+
isValid: false,
330+
missingFields: baseValidation.missingFields,
331+
}
332+
}
333+
334+
const missingFields = this.validateAptosRequirements(chainConfig)
335+
336+
if (missingFields.length > 0) {
337+
logger.warn({
338+
message: "Aptos chain configuration incomplete",
339+
requestId: this.requestId,
340+
networkId,
341+
missingFields,
342+
})
343+
344+
return {
345+
isValid: false,
346+
missingFields,
347+
}
348+
}
349+
350+
const validatedData: ChainDetails = {
351+
...(baseValidation.baseData as ChainDetails),
352+
tokenAdminRegistry: chainConfig.tokenAdminRegistry?.address ?? "",
353+
mcms: chainConfig.mcms?.address ?? "",
354+
}
355+
356+
return {
357+
isValid: true,
358+
missingFields: [],
359+
validatedData,
360+
}
361+
}
362+
363+
private validateAptosRequirements(chainConfig: ChainsConfig[string]): string[] {
364+
return Object.entries(AptosChainStrategy.REQUIRED_FIELDS)
365+
.filter(([_, validator]) => validator(chainConfig))
366+
.map(([field]) => field)
367+
}
368+
}
369+
309370
class ChainStrategyFactory {
371+
private static readonly strategies = new Map<ChainType, new (requestId: string) => IChainProcessingStrategy>([
372+
["evm", EvmChainStrategy],
373+
["solana", SolanaChainStrategy],
374+
["aptos", AptosChainStrategy],
375+
])
376+
310377
static getStrategy(chainType: ChainType, requestId: string): IChainProcessingStrategy {
311-
switch (chainType) {
312-
case "evm":
313-
return new EvmChainStrategy(requestId)
314-
case "solana":
315-
return new SolanaChainStrategy(requestId)
316-
default:
317-
throw new Error(`Unsupported chain type: ${chainType}`)
378+
const StrategyClass = this.strategies.get(chainType)
379+
380+
if (!StrategyClass) {
381+
const supportedTypes = Array.from(this.strategies.keys()).join(", ")
382+
throw new Error(`Chain type "${chainType}" not supported. Available strategies: ${supportedTypes}`)
318383
}
384+
385+
return new StrategyClass(requestId)
319386
}
320387
}
321388

src/pages/api/services/token-data.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import { Version } from "@config/data/ccip/types.ts"
1111
import { SupportedChain } from "@config/index.ts"
1212
import { getAllSupportedTokens, getAllTokenLanes, getTokenData } from "@config/data/ccip/data.ts"
13-
import { resolveChainOrThrow } from "@api/ccip/utils.ts"
13+
import { resolveChainOrThrow, generateChainKey } from "@api/ccip/utils.ts"
1414
import { logger } from "@lib/logging/index.js"
1515
import { getChainId, getChainTypeAndFamily, getTitle } from "../../../features/utils/index.ts"
1616
import { getSelectorEntry } from "@config/data/ccip/selectors.ts"
@@ -134,17 +134,17 @@ export class TokenDataService {
134134
.map((destChainId) => {
135135
const destSupportedChain = resolveChainOrThrow(destChainId)
136136
const destNumericChainId = getChainId(destSupportedChain)
137-
const { chainType } = getChainTypeAndFamily(destSupportedChain)
137+
const { chainType: destChainType } = getChainTypeAndFamily(destSupportedChain)
138138

139139
if (!destNumericChainId) return destChainId
140140

141141
if (outputKey === "chainId") {
142-
return destNumericChainId.toString()
142+
return generateChainKey(destNumericChainId, destChainType, outputKey)
143143
} else if (outputKey === "selector") {
144-
const selectorEntry = getSelectorEntry(destNumericChainId, chainType)
144+
const selectorEntry = getSelectorEntry(destNumericChainId, destChainType)
145145
return selectorEntry?.selector || destChainId
146146
} else if (outputKey === "internalId") {
147-
const selectorEntry = getSelectorEntry(destNumericChainId, chainType)
147+
const selectorEntry = getSelectorEntry(destNumericChainId, destChainType)
148148
return selectorEntry?.name || destChainId
149149
}
150150
return destChainId
@@ -154,7 +154,7 @@ export class TokenDataService {
154154
// Get the appropriate key based on outputKey parameter
155155
let chainKey = chainId
156156
if (outputKey === "chainId") {
157-
chainKey = numericChainId.toString()
157+
chainKey = generateChainKey(numericChainId, chainType, outputKey)
158158
} else if (outputKey === "selector") {
159159
const selectorEntry = getSelectorEntry(numericChainId, chainType)
160160
if (selectorEntry) {

0 commit comments

Comments
 (0)