Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"schedule": "0 */1 * * * *",
"url": "https://postman-echo.com/headers",
"owner": ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {
type ConfidentialHTTPSendRequester,
consensusIdenticalAggregation,
cre,
json,
ok,
Runner,
type Runtime,
safeJsonStringify,
} from '@chainlink/cre-sdk'
import { z } from 'zod'

const configSchema = z.object({
schedule: z.string(),
owner: z.string(),
url: z.string(),
})

type Config = z.infer<typeof configSchema>

type ResponseValues = {
result: {
headers: {
'secret-header': string
}
}
}

const fetchResult = (sendRequester: ConfidentialHTTPSendRequester, config: Config) => {
const { responses } = sendRequester
.sendRequests({
input: {
requests: [
{
url: config.url,
method: 'GET',
headers: ['secret-header: {{.SECRET_HEADER}}'],
},
],
},
vaultDonSecrets: [
{
key: 'SECRET_HEADER',
owner: config.owner,
},
],
})
.result()
const response = responses[0]

if (!ok(response)) {
throw new Error(`HTTP request failed with status: ${response.statusCode}`)
}

return json(response) as ResponseValues
}

const onCronTrigger = (runtime: Runtime<Config>) => {
runtime.log('Confidential HTTP workflow triggered.')

const confHTTPClient = new cre.capabilities.ConfidentialHTTPClient()
const result = confHTTPClient
.sendRequests(
runtime,
fetchResult,
consensusIdenticalAggregation(),
)(runtime.config)
.result()

runtime.log(`Successfully fetched result: ${safeJsonStringify(result)}`)

return {
result,
}
}

const initWorkflow = (config: Config) => {
const cron = new cre.capabilities.CronCapability()

return [cre.handler(cron.trigger({ schedule: config.schedule }), onCronTrigger)]
}

export async function main() {
const runner = await Runner.newRunner<Config>({ configSchema })

await runner.run(initWorkflow)
}

main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# ==========================================================================
# CRE WORKFLOW SETTINGS FILE
# ==========================================================================
# This file defines environment-specific workflow settings used by the CRE CLI.
#
# Each top-level key is a target (e.g., `production`, `production-testnet`, etc.).
# You can also define your own custom targets, such as `my-target`, and
# point the CLI to it via an environment variable.
#
# Note: If any setting in this file conflicts with a setting in the CRE Project Settings File,
# the value defined here in the workflow settings file will take precedence.
#
# Below is an example `my-target`:
#
# my-target:
# user-workflow:
# # Optional: The address of the workflow owner (wallet or MSIG contract).
# # Used to establish ownership for encrypting the workflow's secrets.
# # If omitted, defaults to an empty string.
# workflow-owner-address: "0x1234567890abcdef1234567890abcdef12345678"
#
# # Required: The name of the workflow to register with the Workflow Registry contract.
# workflow-name: "MyExampleWorkflow"

# ==========================================================================
local-simulation:
user-workflow:
workflow-owner-address: "(optional) Multi-signature contract address"
workflow-name: "http-confidential-fetch-with-secrets"
workflow-artifacts:
workflow-path: "./index.ts"
config-path: "./config.json"

# ==========================================================================
production-testnet:
user-workflow:
workflow-owner-address: "(optional) Multi-signature contract address"
workflow-name: "http-confidential-fetch-with-secrets"
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,18 @@ export function text(
* @returns The parsed JSON
* @throws Error if the body is not valid JSON
*/
export function json(response: Response): unknown
export function json(response: Response | ResponseTemplate): unknown
/**
* Parses the response body as JSON
* @param responseFn - Function that returns an object with result function that returns Response
* @returns Object with result function that returns the parsed JSON
* @throws Error if the body is not valid JSON
*/
export function json(responseFn: () => { result: Response }): {
export function json(responseFn: () => { result: Response | ResponseTemplate }): {
result: () => unknown
}
export function json(
responseOrFn: Response | (() => { result: Response }),
responseOrFn: Response | ResponseTemplate | (() => { result: Response | ResponseTemplate }),
): unknown | { result: () => unknown } {
if (typeof responseOrFn === 'function') {
return {
Expand Down