-
Notifications
You must be signed in to change notification settings - Fork 308
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BCI-3343: Add starknet gas price EA (#3311)
- Loading branch information
1 parent
5419d57
commit a9edfe2
Showing
29 changed files
with
387 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@chainlink/starknet-gas-price-adapter': major | ||
--- | ||
|
||
First version of starknet gas price adapter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@chainlink/starknet-gas-price-adapter': minor | ||
--- | ||
|
||
lint changes |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Binary file not shown.
Binary file not shown.
Binary file added
BIN
+16.3 KB
.yarn/cache/get-starknet-core-npm-4.0.0-next.5-ae89eba523-a305acc589.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# STARKNET_GAS_PRICE | ||
|
||
![0.0.0](https://img.shields.io/github/package-json/v/smartcontractkit/external-adapters-js?filename=packages/sources/starknet-gas-price/package.json) ![v3](https://img.shields.io/badge/framework%20version-v3-blueviolet) | ||
|
||
This document was generated automatically. Please see [README Generator](../../scripts#readme-generator) for more info. | ||
|
||
## Environment Variables | ||
|
||
| Required? | Name | Description | Type | Options | Default | | ||
| :-------: | :-------------------: | :---------------------------------------------------------------------------------------: | :----: | :-----: | :------: | | ||
| ✅ | STARKNET_RPC_URL | The RPC URL used to fetch the gas price | string | | | | ||
| | BACKGROUND_EXECUTE_MS | The amount of time the background execute should sleep before performing the next request | string | | `10_000` | | ||
|
||
--- | ||
|
||
## Data Provider Rate Limits | ||
|
||
There are no rate limits for this adapter. | ||
|
||
--- | ||
|
||
## Input Parameters | ||
|
||
| Required? | Name | Description | Type | Options | Default | | ||
| :-------: | :------: | :-----------------: | :----: | :----------------------------: | :--------: | | ||
| | endpoint | The endpoint to use | string | [gasprice](#gasprice-endpoint) | `gasprice` | | ||
|
||
## Gasprice Endpoint | ||
|
||
`gasprice` is the only supported name for this endpoint. | ||
|
||
### Input Params | ||
|
||
There are no input parameters for this endpoint. | ||
|
||
### Example | ||
|
||
Request: | ||
|
||
```json | ||
{ | ||
"data": { | ||
"endpoint": "gasprice" | ||
} | ||
} | ||
``` | ||
|
||
--- | ||
|
||
MIT License |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"name": "@chainlink/starknet-gas-price-adapter", | ||
"version": "0.0.0", | ||
"description": "Chainlink starknet-gas-price adapter.", | ||
"keywords": [ | ||
"Chainlink", | ||
"LINK", | ||
"blockchain", | ||
"oracle", | ||
"starknet-gas-price" | ||
], | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"files": [ | ||
"dist" | ||
], | ||
"repository": { | ||
"url": "https://github.com/smartcontractkit/external-adapters-js", | ||
"type": "git" | ||
}, | ||
"license": "MIT", | ||
"scripts": { | ||
"clean": "rm -rf dist && rm -f tsconfig.tsbuildinfo", | ||
"prepack": "yarn build", | ||
"build": "tsc -b", | ||
"server": "node -e 'require(\"./index.js\").server()'", | ||
"server:dist": "node -e 'require(\"./dist/index.js\").server()'", | ||
"start": "yarn server:dist" | ||
}, | ||
"devDependencies": { | ||
"@types/jest": "27.5.2", | ||
"@types/node": "16.18.96", | ||
"nock": "14.0.0-beta.6", | ||
"typescript": "5.0.4" | ||
}, | ||
"dependencies": { | ||
"@chainlink/external-adapter-framework": "0.33.8", | ||
"starknet": "6.9.0", | ||
"tslib": "2.4.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { AdapterConfig } from '@chainlink/external-adapter-framework/config' | ||
|
||
export const config = new AdapterConfig({ | ||
STARKNET_RPC_URL: { | ||
description: 'RPC Url For Starknet', | ||
type: 'string', | ||
required: true, | ||
sensitive: true, | ||
}, | ||
BACKGROUND_EXECUTE_MS: { | ||
description: | ||
'The amount of time the background execute should sleep before performing the next request', | ||
type: 'number', | ||
default: 10_000, | ||
}, | ||
}) |
29 changes: 29 additions & 0 deletions
29
packages/sources/starknet-gas-price/src/endpoint/gasprice.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { AdapterEndpoint } from '@chainlink/external-adapter-framework/adapter' | ||
import { InputParameters } from '@chainlink/external-adapter-framework/validation' | ||
import { config } from '../config' | ||
import { gasPriceTransport } from '../transport/gasprice' | ||
|
||
export const inputParameters = new InputParameters({}) | ||
|
||
// Endpoints contain a type parameter that allows specifying relevant types of an endpoint, for example, request payload type, Adapter response type and Adapter configuration (environment variables) type | ||
export type BaseEndpointTypes = { | ||
Parameters: typeof inputParameters.definition | ||
Response: { | ||
Data: { | ||
result: string | ||
} | ||
Result: string | ||
} | ||
Settings: typeof config.settings | ||
} | ||
|
||
export const endpoint = new AdapterEndpoint({ | ||
// Endpoint name | ||
name: 'gasprice', | ||
// Alternative endpoint names for this endpoint | ||
aliases: ['gas_price'], | ||
// Transport handles incoming requests, data processing and communication for this endpoint | ||
transport: gasPriceTransport, | ||
// Supported input parameters for this endpoint | ||
inputParameters, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { endpoint as gasprice } from './gasprice' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { expose, ServerInstance } from '@chainlink/external-adapter-framework' | ||
import { Adapter } from '@chainlink/external-adapter-framework/adapter' | ||
import { config } from './config' | ||
import { gasprice } from './endpoint' | ||
|
||
export const adapter = new Adapter({ | ||
//Requests will direct to this endpoint if the `endpoint` input parameter is not specified. | ||
defaultEndpoint: gasprice.name, | ||
// Adapter name | ||
name: 'STARKNET_GAS_PRICE', | ||
// Adapter configuration (environment variables) | ||
config, | ||
// List of supported endpoints | ||
endpoints: [gasprice], | ||
}) | ||
|
||
export const server = (): Promise<ServerInstance | undefined> => expose(adapter) |
91 changes: 91 additions & 0 deletions
91
packages/sources/starknet-gas-price/src/transport/gasprice.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { TransportDependencies } from '@chainlink/external-adapter-framework/transports' | ||
import { AdapterResponse, makeLogger, sleep } from '@chainlink/external-adapter-framework/util' | ||
import { SubscriptionTransport } from '@chainlink/external-adapter-framework/transports/abstract/subscription' | ||
import { EndpointContext } from '@chainlink/external-adapter-framework/adapter' | ||
import { BaseEndpointTypes, inputParameters } from '../endpoint/gasprice' | ||
import { RpcProvider, num, PendingBlock } from 'starknet' | ||
import { AdapterCustomError } from '@chainlink/external-adapter-framework/validation/error' | ||
|
||
const logger = makeLogger('Starknet Gas Price') | ||
|
||
export type GasPriceTransportTypes = BaseEndpointTypes | ||
|
||
type RequestParams = typeof inputParameters.validated | ||
|
||
export class GasPriceTransport extends SubscriptionTransport<GasPriceTransportTypes> { | ||
provider!: RpcProvider | ||
|
||
async initialize( | ||
dependencies: TransportDependencies<GasPriceTransportTypes>, | ||
adapterSettings: GasPriceTransportTypes['Settings'], | ||
endpointName: string, | ||
transportName: string, | ||
): Promise<void> { | ||
await super.initialize(dependencies, adapterSettings, endpointName, transportName) | ||
this.provider = new RpcProvider({ | ||
nodeUrl: adapterSettings.STARKNET_RPC_URL, | ||
}) | ||
} | ||
|
||
async backgroundHandler( | ||
context: EndpointContext<GasPriceTransportTypes>, | ||
entries: RequestParams[], | ||
) { | ||
await Promise.all(entries.map(async (param) => this.handleRequest(param))) | ||
await sleep(context.adapterSettings.BACKGROUND_EXECUTE_MS) | ||
} | ||
|
||
async handleRequest(param: RequestParams) { | ||
let response: AdapterResponse<GasPriceTransportTypes['Response']> | ||
try { | ||
response = await this._handleRequest() | ||
} catch (e) { | ||
logger.error(e) | ||
const errorMessage = e instanceof Error ? e.message : 'Unknown error occurred' | ||
response = { | ||
statusCode: 502, | ||
errorMessage, | ||
timestamps: { | ||
providerDataRequestedUnixMs: 0, | ||
providerDataReceivedUnixMs: 0, | ||
providerIndicatedTimeUnixMs: undefined, | ||
}, | ||
} | ||
} | ||
await this.responseCache.write(this.name, [{ params: param, response }]) | ||
} | ||
|
||
async _handleRequest(): Promise<AdapterResponse<GasPriceTransportTypes['Response']>> { | ||
const providerDataRequestedUnixMs = Date.now() | ||
let block: PendingBlock | ||
try { | ||
block = await this.provider.getBlock('pending') | ||
} catch (e) { | ||
throw new AdapterCustomError({ | ||
statusCode: 502, | ||
message: `RPCProvider GetBlock Failed: ${e}`, | ||
}) | ||
} | ||
|
||
const result = num.hexToDecimalString(block.l1_gas_price.price_in_fri) | ||
|
||
return { | ||
data: { | ||
result, | ||
}, | ||
statusCode: 200, | ||
result, | ||
timestamps: { | ||
providerDataRequestedUnixMs, | ||
providerDataReceivedUnixMs: Date.now(), | ||
providerIndicatedTimeUnixMs: undefined, | ||
}, | ||
} | ||
} | ||
|
||
getSubscriptionTtlFromConfig(adapterSettings: GasPriceTransportTypes['Settings']): number { | ||
return adapterSettings.WARMUP_SUBSCRIPTION_TTL | ||
} | ||
} | ||
|
||
export const gasPriceTransport = new GasPriceTransport() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"requests": [{}] | ||
} | ||
|
77 changes: 77 additions & 0 deletions
77
packages/sources/starknet-gas-price/test/integration/adapter.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import * as nock from 'nock' | ||
import { | ||
TestAdapter, | ||
setEnvVariables, | ||
} from '@chainlink/external-adapter-framework/util/testing-utils' | ||
import { RpcProvider, PendingBlock } from 'starknet' | ||
|
||
describe('execute', () => { | ||
let spy: jest.SpyInstance | ||
let testAdapter: TestAdapter | ||
let oldEnv: NodeJS.ProcessEnv | ||
|
||
beforeAll(async () => { | ||
oldEnv = JSON.parse(JSON.stringify(process.env)) | ||
process.env.BACKGROUND_EXECUTE_MS = '0' | ||
process.env.STARKNET_RPC_URL = 'https://test-rpc-url-starknet.com' | ||
|
||
const mockDate = new Date('2001-01-01T11:11:11.111Z') | ||
spy = jest.spyOn(Date, 'now').mockReturnValue(mockDate.getTime()) | ||
|
||
const adapter = (await import('./../../src')).adapter | ||
adapter.rateLimiting = undefined | ||
testAdapter = await TestAdapter.startWithMockedCache(adapter, { | ||
testAdapter: {} as TestAdapter<never>, | ||
}) | ||
}) | ||
|
||
afterAll(async () => { | ||
setEnvVariables(oldEnv) | ||
await testAdapter.api.close() | ||
nock.restore() | ||
nock.cleanAll() | ||
spy.mockRestore() | ||
}) | ||
|
||
describe('gasprice endpoint', () => { | ||
it('should return success', async () => { | ||
// mock the starknet.js provider directly | ||
jest.spyOn(RpcProvider.prototype, 'getBlock').mockResolvedValue({ | ||
status: 'PENDING', | ||
l1_da_mode: 'BLOB', | ||
l1_data_gas_price: { price_in_fri: '0x2daa35d3076ec4', price_in_wei: '0x3bde2d6cc47' }, | ||
l1_gas_price: { price_in_fri: '0x2d7e8782b50', price_in_wei: '0x3ba4e91d' }, | ||
parent_hash: '0x5c14708b125390d092c83f2561ed6278fce3c16540d0b9429b00eff32bdc7c2', | ||
sequencer_address: '0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8', | ||
starknet_version: '0.13.1.1', | ||
timestamp: 1717104546, | ||
transactions: [ | ||
'0x7fb1a6ab95d283a56cd0d30f0fdfe4eed15543da9529ede1698a8b1b0bb57e1', | ||
'0x460809d209b4174fb005c76a210c86d7d50d1b4209df935b8d2ce3bbafd19d5', | ||
'0x70e841662b27cffdbf4c0ce1446d8ff42f843a8424ef6e6fb90c5c0a4e2bfd4', | ||
'0xd330e47ca906e59c597f55dcc647aff2ddb85936b203a6fd3d98f09c5d6728', | ||
'0x782e010e65ea252a86ee7d4380c64d6c294c759e2e803d454325428c07ea37', | ||
'0x679c2c91d6224107d7faddfa9812362e716d18e5c34e5c6eac24199ae272136', | ||
'0x150e4259dd0d7e6c2cbf84420e16af0cb13c1cc8d20f671ff528658ac995ebf', | ||
'0x3283068f2b2fd0fcb5432dff3a0255cc8baece8dc6af6ec6d9f11331844c749', | ||
], | ||
} as unknown as PendingBlock) | ||
|
||
const expectedResult = { | ||
data: { result: '3126341413712' }, // price_in_fri: '0x2d7e8782b50' converted to decimal string representation | ||
statusCode: 200, | ||
result: '3126341413712', // price_in_fri: '0x2d7e8782b50' converted to decimal string representation | ||
timestamps: { | ||
providerDataRequestedUnixMs: 978347471111, // the mocked date in ms | ||
providerDataReceivedUnixMs: 978347471111, // the mocked date in ms | ||
}, | ||
} | ||
|
||
const data = {} | ||
const response = await testAdapter.request(data) | ||
expect(response.statusCode).toBe(200) | ||
// match checks that expected result is a subset of the actual response | ||
expect(response.json()).toMatchObject(expectedResult) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"extends": "../../tsconfig.base.json", | ||
"compilerOptions": { | ||
"outDir": "dist", | ||
"rootDir": "src" | ||
}, | ||
"include": ["src/**/*", "src/**/*.json"], | ||
"exclude": ["dist", "**/*.spec.ts", "**/*.test.ts"] | ||
} |
Oops, something went wrong.