diff --git a/src/content/cre/guides/workflow/using-confidential-http-client/making-requests-go.mdx b/src/content/cre/guides/workflow/using-confidential-http-client/making-requests-go.mdx index ab19387e39f..6aa8634bc0b 100644 --- a/src/content/cre/guides/workflow/using-confidential-http-client/making-requests-go.mdx +++ b/src/content/cre/guides/workflow/using-confidential-http-client/making-requests-go.mdx @@ -94,10 +94,10 @@ type Result struct { ### Step 4: Implement the request logic -Use `cre.RunInNodeMode` to make the confidential request. The `confidentialhttp.Client` requires a `NodeRuntime`: +Unlike the regular HTTP client, the Confidential HTTP client takes a `cre.Runtime` directly and does not require `cre.RunInNodeMode` wrapping: ```go -func makeConfidentialRequest(config Config, nodeRuntime cre.NodeRuntime) (Result, error) { +func makeConfidentialRequest(config Config, runtime cre.Runtime) (Result, error) { // 1. Define the request body with secret template placeholders payload := `{"auth": "{{.myApiKey}}", "action": "getTransaction", "id": "tx-123"}` @@ -113,17 +113,17 @@ func makeConfidentialRequest(config Config, nodeRuntime cre.NodeRuntime) (Result // 3. Create the client and send the request client := confidentialhttp.Client{} - resp, err := client.SendRequest(nodeRuntime, &confidentialhttp.ConfidentialHTTPRequest{ + resp, err := client.SendRequest(runtime, &confidentialhttp.ConfidentialHTTPRequest{ Request: &confidentialhttp.HTTPRequest{ - Url: config.URL, - Method: "POST", - Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: payload}, + Url: config.URL, + Method: "POST", + Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: payload}, MultiHeaders: headers, + EncryptOutput: false, }, VaultDonSecrets: []*confidentialhttp.SecretIdentifier{ {Key: "myApiKey"}, }, - EncryptOutput: false, }).Await() if err != nil { return Result{}, fmt.Errorf("confidential HTTP request failed: %w", err) @@ -141,14 +141,11 @@ func makeConfidentialRequest(config Config, nodeRuntime cre.NodeRuntime) (Result ### Step 5: Wire it into your workflow -Call the request function from your trigger handler using `cre.RunInNodeMode`: +Call the request function from your trigger handler: ```go func onCronTrigger(config *Config, runtime cre.Runtime, outputs *cron.Payload) (string, error) { - result, err := cre.RunInNodeMode(*config, runtime, - makeConfidentialRequest, - cre.ConsensusIdenticalAggregation[Result](), - ).Await() + result, err := makeConfidentialRequest(*config, runtime) if err != nil { return "", fmt.Errorf("failed to get result: %w", err) } @@ -212,18 +209,18 @@ By default, the API response is returned unencrypted (`EncryptOutput: false`). T 1. **Include the key in your `VaultDonSecrets`** and set `EncryptOutput: true`: ```go - resp, err := client.SendRequest(nodeRuntime, &confidentialhttp.ConfidentialHTTPRequest{ + resp, err := client.SendRequest(runtime, &confidentialhttp.ConfidentialHTTPRequest{ Request: &confidentialhttp.HTTPRequest{ - Url: config.URL, - Method: "POST", - Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: payload}, - MultiHeaders: headers, + Url: config.URL, + Method: "POST", + Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: payload}, + MultiHeaders: headers, + EncryptOutput: true, }, VaultDonSecrets: []*confidentialhttp.SecretIdentifier{ {Key: "myApiKey"}, {Key: "san_marino_aes_gcm_encryption_key"}, }, - EncryptOutput: true, }).Await() ``` @@ -309,10 +306,7 @@ func InitWorkflow(config *Config, logger *slog.Logger, secretsProvider cre.Secre } func onCronTrigger(config *Config, runtime cre.Runtime, outputs *cron.Payload) (string, error) { - result, err := cre.RunInNodeMode(*config, runtime, - makeConfidentialRequest, - cre.ConsensusIdenticalAggregation[Result](), - ).Await() + result, err := makeConfidentialRequest(*config, runtime) if err != nil { return "", fmt.Errorf("failed to get result: %w", err) } @@ -321,7 +315,7 @@ func onCronTrigger(config *Config, runtime cre.Runtime, outputs *cron.Payload) ( return result.TransactionID, nil } -func makeConfidentialRequest(config Config, nodeRuntime cre.NodeRuntime) (Result, error) { +func makeConfidentialRequest(config Config, runtime cre.Runtime) (Result, error) { payload := `{"auth": "{{.myApiKey}}", "action": "getTransaction", "id": "tx-123"}` headers := map[string]*confidentialhttp.HeaderValues{ @@ -334,18 +328,18 @@ func makeConfidentialRequest(config Config, nodeRuntime cre.NodeRuntime) (Result } client := confidentialhttp.Client{} - resp, err := client.SendRequest(nodeRuntime, &confidentialhttp.ConfidentialHTTPRequest{ + resp, err := client.SendRequest(runtime, &confidentialhttp.ConfidentialHTTPRequest{ Request: &confidentialhttp.HTTPRequest{ - Url: config.URL, - Method: "POST", - Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: payload}, - MultiHeaders: headers, + Url: config.URL, + Method: "POST", + Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: payload}, + MultiHeaders: headers, + EncryptOutput: true, }, VaultDonSecrets: []*confidentialhttp.SecretIdentifier{ {Key: "myApiKey"}, {Key: "san_marino_aes_gcm_encryption_key"}, }, - EncryptOutput: true, }).Await() if err != nil { return Result{}, fmt.Errorf("confidential HTTP request failed: %w", err) diff --git a/src/content/cre/guides/workflow/using-confidential-http-client/making-requests-ts.mdx b/src/content/cre/guides/workflow/using-confidential-http-client/making-requests-ts.mdx index 7f52d11df7d..342279fa336 100644 --- a/src/content/cre/guides/workflow/using-confidential-http-client/making-requests-ts.mdx +++ b/src/content/cre/guides/workflow/using-confidential-http-client/making-requests-ts.mdx @@ -87,25 +87,27 @@ type TransactionResult = { } ``` -### Step 4: Implement the fetch function +### Step 4: Implement the request and wire it into your workflow -Create the function that will be passed to `sendRequest()`. This function receives a `ConfidentialHTTPSendRequester` and your config as parameters: +Unlike the regular HTTP client, the Confidential HTTP client takes a `Runtime` directly and does not require `runInNodeMode` wrapping: ```typescript -import { type ConfidentialHTTPSendRequester, ok, json } from "@chainlink/cre-sdk" +import { CronCapability, ConfidentialHTTPClient, handler, ok, json, type Runtime, Runner } from "@chainlink/cre-sdk" + +const onCronTrigger = (runtime: Runtime): TransactionResult => { + const confHTTPClient = new ConfidentialHTTPClient() -const fetchTransaction = (sendRequester: ConfidentialHTTPSendRequester, config: Config): TransactionResult => { // 1. Send the confidential request - const response = sendRequester - .sendRequest({ + const response = confHTTPClient + .sendRequest(runtime, { request: { - url: config.url, + url: runtime.config.url, method: "GET", multiHeaders: { Authorization: { values: ["Basic {{.myApiKey}}"] }, }, }, - vaultDonSecrets: [{ key: "myApiKey", owner: config.owner }], + vaultDonSecrets: [{ key: "myApiKey", owner: runtime.config.owner }], }) .result() @@ -115,37 +117,13 @@ const fetchTransaction = (sendRequester: ConfidentialHTTPSendRequester, config: } // 3. Parse and return the result - return json(response) as TransactionResult -} -``` - -### Step 5: Wire it into your workflow - -In your trigger handler, call `confHTTPClient.sendRequest()` with your fetch function and a consensus method: - -```typescript -import { - CronCapability, - ConfidentialHTTPClient, - handler, - consensusIdenticalAggregation, - type Runtime, - Runner, -} from "@chainlink/cre-sdk" - -const onCronTrigger = (runtime: Runtime): string => { - const confHTTPClient = new ConfidentialHTTPClient() - - const result = confHTTPClient - .sendRequest(runtime, fetchTransaction, consensusIdenticalAggregation())(runtime.config) - .result() - + const result = json(response) as TransactionResult runtime.log(`Transaction result: ${result.transactionId} — ${result.status}`) - return result.transactionId + return result } ``` -### Step 6: Simulate +### Step 5: Simulate Run the simulation: @@ -197,17 +175,20 @@ export AES_KEY_ALL="your-256-bit-hex-encoded-key" 1. **Include the key in your `vaultDonSecrets`** and set `encryptOutput: true`: ```typescript - const response = sendRequester - .sendRequest({ + const response = confHTTPClient + .sendRequest(runtime, { request: { - url: config.url, + url: runtime.config.url, method: "GET", multiHeaders: { Authorization: { values: ["Basic {{.myApiKey}}"] }, }, + encryptOutput: true, }, - vaultDonSecrets: [{ key: "myApiKey", owner: config.owner }, { key: "san_marino_aes_gcm_encryption_key" }], - encryptOutput: true, + vaultDonSecrets: [ + { key: "myApiKey", owner: runtime.config.owner }, + { key: "san_marino_aes_gcm_encryption_key" }, + ], }) .result() ``` @@ -229,17 +210,7 @@ The SDK response helpers `ok()`, `text()`, and `json()` work with Confidential H Here's the full workflow code for a confidential HTTP request with secret injection: ```typescript -import { - CronCapability, - ConfidentialHTTPClient, - handler, - consensusIdenticalAggregation, - ok, - json, - type ConfidentialHTTPSendRequester, - type Runtime, - Runner, -} from "@chainlink/cre-sdk" +import { CronCapability, ConfidentialHTTPClient, handler, ok, json, type Runtime, Runner } from "@chainlink/cre-sdk" import { z } from "zod" // Config schema @@ -257,18 +228,20 @@ type TransactionResult = { status: string } -// Fetch function — receives a ConfidentialHTTPSendRequester and config -const fetchTransaction = (sendRequester: ConfidentialHTTPSendRequester, config: Config): TransactionResult => { - const response = sendRequester - .sendRequest({ +// Main workflow handler +const onCronTrigger = (runtime: Runtime): TransactionResult => { + const confHTTPClient = new ConfidentialHTTPClient() + + const response = confHTTPClient + .sendRequest(runtime, { request: { - url: config.url, + url: runtime.config.url, method: "GET", multiHeaders: { Authorization: { values: ["Basic {{.myApiKey}}"] }, }, }, - vaultDonSecrets: [{ key: "myApiKey", owner: config.owner }], + vaultDonSecrets: [{ key: "myApiKey", owner: runtime.config.owner }], }) .result() @@ -276,19 +249,9 @@ const fetchTransaction = (sendRequester: ConfidentialHTTPSendRequester, config: throw new Error(`HTTP request failed with status: ${response.statusCode}`) } - return json(response) as TransactionResult -} - -// Main workflow handler -const onCronTrigger = (runtime: Runtime): string => { - const confHTTPClient = new ConfidentialHTTPClient() - - const result = confHTTPClient - .sendRequest(runtime, fetchTransaction, consensusIdenticalAggregation())(runtime.config) - .result() - + const result = json(response) as TransactionResult runtime.log(`Transaction result: ${result.transactionId} — ${result.status}`) - return result.transactionId + return result } // Initialize workflow diff --git a/src/content/cre/llms-full-go.txt b/src/content/cre/llms-full-go.txt index 53d3e8a5d5e..10bf2354f54 100644 --- a/src/content/cre/llms-full-go.txt +++ b/src/content/cre/llms-full-go.txt @@ -10787,10 +10787,10 @@ type Result struct { ### Step 4: Implement the request logic -Use `cre.RunInNodeMode` to make the confidential request. The `confidentialhttp.Client` requires a `NodeRuntime`: +Unlike the regular HTTP client, the Confidential HTTP client takes a `cre.Runtime` directly and does not require `cre.RunInNodeMode` wrapping: ```go -func makeConfidentialRequest(config Config, nodeRuntime cre.NodeRuntime) (Result, error) { +func makeConfidentialRequest(config Config, runtime cre.Runtime) (Result, error) { // 1. Define the request body with secret template placeholders payload := `{"auth": "{{.myApiKey}}", "action": "getTransaction", "id": "tx-123"}` @@ -10806,17 +10806,17 @@ func makeConfidentialRequest(config Config, nodeRuntime cre.NodeRuntime) (Result // 3. Create the client and send the request client := confidentialhttp.Client{} - resp, err := client.SendRequest(nodeRuntime, &confidentialhttp.ConfidentialHTTPRequest{ + resp, err := client.SendRequest(runtime, &confidentialhttp.ConfidentialHTTPRequest{ Request: &confidentialhttp.HTTPRequest{ - Url: config.URL, - Method: "POST", - Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: payload}, + Url: config.URL, + Method: "POST", + Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: payload}, MultiHeaders: headers, + EncryptOutput: false, }, VaultDonSecrets: []*confidentialhttp.SecretIdentifier{ {Key: "myApiKey"}, }, - EncryptOutput: false, }).Await() if err != nil { return Result{}, fmt.Errorf("confidential HTTP request failed: %w", err) @@ -10834,14 +10834,11 @@ func makeConfidentialRequest(config Config, nodeRuntime cre.NodeRuntime) (Result ### Step 5: Wire it into your workflow -Call the request function from your trigger handler using `cre.RunInNodeMode`: +Call the request function from your trigger handler: ```go func onCronTrigger(config *Config, runtime cre.Runtime, outputs *cron.Payload) (string, error) { - result, err := cre.RunInNodeMode(*config, runtime, - makeConfidentialRequest, - cre.ConsensusIdenticalAggregation[Result](), - ).Await() + result, err := makeConfidentialRequest(*config, runtime) if err != nil { return "", fmt.Errorf("failed to get result: %w", err) } @@ -10905,18 +10902,18 @@ By default, the API response is returned unencrypted (`EncryptOutput: false`). T 2. **Include the key in your `VaultDonSecrets`** and set `EncryptOutput: true`: ```go - resp, err := client.SendRequest(nodeRuntime, &confidentialhttp.ConfidentialHTTPRequest{ + resp, err := client.SendRequest(runtime, &confidentialhttp.ConfidentialHTTPRequest{ Request: &confidentialhttp.HTTPRequest{ - Url: config.URL, - Method: "POST", - Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: payload}, - MultiHeaders: headers, + Url: config.URL, + Method: "POST", + Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: payload}, + MultiHeaders: headers, + EncryptOutput: true, }, VaultDonSecrets: []*confidentialhttp.SecretIdentifier{ {Key: "myApiKey"}, {Key: "san_marino_aes_gcm_encryption_key"}, }, - EncryptOutput: true, }).Await() ``` @@ -11002,10 +10999,7 @@ func InitWorkflow(config *Config, logger *slog.Logger, secretsProvider cre.Secre } func onCronTrigger(config *Config, runtime cre.Runtime, outputs *cron.Payload) (string, error) { - result, err := cre.RunInNodeMode(*config, runtime, - makeConfidentialRequest, - cre.ConsensusIdenticalAggregation[Result](), - ).Await() + result, err := makeConfidentialRequest(*config, runtime) if err != nil { return "", fmt.Errorf("failed to get result: %w", err) } @@ -11014,7 +11008,7 @@ func onCronTrigger(config *Config, runtime cre.Runtime, outputs *cron.Payload) ( return result.TransactionID, nil } -func makeConfidentialRequest(config Config, nodeRuntime cre.NodeRuntime) (Result, error) { +func makeConfidentialRequest(config Config, runtime cre.Runtime) (Result, error) { payload := `{"auth": "{{.myApiKey}}", "action": "getTransaction", "id": "tx-123"}` headers := map[string]*confidentialhttp.HeaderValues{ @@ -11027,18 +11021,18 @@ func makeConfidentialRequest(config Config, nodeRuntime cre.NodeRuntime) (Result } client := confidentialhttp.Client{} - resp, err := client.SendRequest(nodeRuntime, &confidentialhttp.ConfidentialHTTPRequest{ + resp, err := client.SendRequest(runtime, &confidentialhttp.ConfidentialHTTPRequest{ Request: &confidentialhttp.HTTPRequest{ - Url: config.URL, - Method: "POST", - Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: payload}, - MultiHeaders: headers, + Url: config.URL, + Method: "POST", + Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: payload}, + MultiHeaders: headers, + EncryptOutput: true, }, VaultDonSecrets: []*confidentialhttp.SecretIdentifier{ {Key: "myApiKey"}, {Key: "san_marino_aes_gcm_encryption_key"}, }, - EncryptOutput: true, }).Await() if err != nil { return Result{}, fmt.Errorf("confidential HTTP request failed: %w", err) @@ -14418,10 +14412,9 @@ The [Confidential HTTP](/cre/capabilities/confidential-http-go) Client lets you ## Quick reference -| Method | Description | -| -------------------------------------------------------------- | ---------------------------------------------------------- | -| [`confidentialhttp.SendRequest`](#confidentialhttpsendrequest) | High-level helper with automatic `RunInNodeMode` wrapping | -| [`client.SendRequest`](#clientsendrequest) | Low-level method requiring manual `RunInNodeMode` wrapping | +| Method | Description | +| ------------------------------------------ | ---------------------------------- | +| [`client.SendRequest`](#clientsendrequest) | Makes a confidential HTTP request. | ## Core types @@ -14433,21 +14426,21 @@ The top-level request type that combines an HTTP request with Vault DON secrets | ----------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `Request` | `*HTTPRequest` | The HTTP request to execute inside the enclave. See [`HTTPRequest`](#confidentialhttphttprequest). | | `VaultDonSecrets` | `[]*SecretIdentifier` | List of secrets to fetch from the Vault DON and make available in the enclave. See [`SecretIdentifier`](#confidentialhttpsecretidentifier). | -| `EncryptOutput` | `bool` | If `true`, encrypts the response body before it leaves the enclave. See [Response encryption](#response-encryption). Default: `false`. | ### `confidentialhttp.HTTPRequest` Defines the HTTP request that will be executed inside the enclave. -| Field | Type | Description | -| ---------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------- | -| `Url` | `string` | The URL of the API endpoint. | -| `Method` | `string` | The HTTP method (e.g., `"GET"`, `"POST"`). | -| `Body` | `isHTTPRequest_Body` | The request body. Use `HTTPRequest_BodyString` for string templates or `HTTPRequest_BodyBytes` for raw bytes. | -| `MultiHeaders` | `map[string]*HeaderValues` | Request headers. Supports multiple values per key and template syntax for secret injection. | -| `TemplatePublicValues` | `map[string]string` | Public (non-secret) values used to fill template placeholders in the body and headers. | -| `CustomRootCaCertPem` | `[]byte` | Optional custom root CA certificate (PEM format) for verifying the external server's TLS certificate. | -| `Timeout` | `*durationpb.Duration` | Optional request timeout. | +| Field | Type | Description | +| ---------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| `Url` | `string` | The URL of the API endpoint. | +| `Method` | `string` | The HTTP method (e.g., `"GET"`, `"POST"`). | +| `Body` | `isHTTPRequest_Body` | The request body. Use `HTTPRequest_BodyString` for string templates or `HTTPRequest_BodyBytes` for raw bytes. | +| `MultiHeaders` | `map[string]*HeaderValues` | Request headers. Supports multiple values per key and template syntax for secret injection. | +| `TemplatePublicValues` | `map[string]string` | Public (non-secret) values used to fill template placeholders in the body and headers. | +| `CustomRootCaCertPem` | `[]byte` | Optional custom root CA certificate (PEM format) for verifying the external server's TLS certificate. | +| `Timeout` | `*durationpb.Duration` | Optional request timeout. | +| `EncryptOutput` | `bool` | If `true`, encrypts the response body before it leaves the enclave. See [Response encryption](#response-encryption). Default: `false`. | #### Setting the request body @@ -14499,75 +14492,20 @@ Represents multiple values for a single HTTP header key. ## Making requests -### `confidentialhttp.SendRequest` - -The high-level helper function for making confidential HTTP requests. Automatically handles the `cre.RunInNodeMode` pattern. - -**Signature:** - -```go -func SendRequest[C, T any]( - config C, - runtime cre.Runtime, - client *Client, - fn func(config C, logger *slog.Logger, sendRequester *SendRequester) (T, error), - ca cre.ConsensusAggregation[T], -) cre.Promise[T] -``` - -**Parameters:** - -- `config`: Your workflow's configuration struct, passed to `fn`. -- `runtime`: The top-level `cre.Runtime` from your trigger callback. -- `client`: An initialized `*confidentialhttp.Client`. -- `fn`: Your request logic function that receives `config`, `logger`, and `sendRequester`. -- `ca`: The [consensus aggregation method](/cre/reference/sdk/consensus). - -**Example:** - -```go -func fetchData(config *Config, logger *slog.Logger, sendRequester *confidentialhttp.SendRequester) (*Result, error) { - resp, err := sendRequester.SendRequest(&confidentialhttp.ConfidentialHTTPRequest{ - Request: &confidentialhttp.HTTPRequest{ - Url: config.URL, - Method: "GET", - MultiHeaders: map[string]*confidentialhttp.HeaderValues{ - "Authorization": {Values: []string{"Basic {{.apiKey}}"}}, - }, - }, - VaultDonSecrets: []*confidentialhttp.SecretIdentifier{ - {Key: "apiKey"}, - }, - }).Await() - if err != nil { - return nil, err - } - // Parse resp.Body... - return &Result{}, nil -} - -// In your trigger callback -client := &confidentialhttp.Client{} -result, err := confidentialhttp.SendRequest(config, runtime, client, - fetchData, - cre.ConsensusIdenticalAggregation[*Result](), -).Await() -``` - ### `client.SendRequest` -The lower-level method for making confidential HTTP requests. Must be manually wrapped in `cre.RunInNodeMode`. +Makes a confidential HTTP request. The request executes inside a secure enclave, so unlike the regular HTTP client, there is no need to wrap this call in `cre.RunInNodeMode`. **Signature:** ```go -func (c *Client) SendRequest(runtime cre.NodeRuntime, input *ConfidentialHTTPRequest) cre.Promise[*HTTPResponse] +func (c *Client) SendRequest(runtime cre.Runtime, input *ConfidentialHTTPRequest) cre.Promise[*HTTPResponse] ``` **Parameters:** -- `runtime`: A `cre.NodeRuntime` provided by `cre.RunInNodeMode`. -- `input`: A `*ConfidentialHTTPRequest` containing the request, secrets, and encryption settings. +- `runtime`: The `cre.Runtime` from your trigger callback. +- `input`: A `*ConfidentialHTTPRequest` containing the request and secrets. **Returns:** @@ -14576,30 +14514,26 @@ func (c *Client) SendRequest(runtime cre.NodeRuntime, input *ConfidentialHTTPReq **Example:** ```go -result, err := cre.RunInNodeMode(config, runtime, - func(config Config, nodeRuntime cre.NodeRuntime) (Result, error) { - client := confidentialhttp.Client{} - resp, err := client.SendRequest(nodeRuntime, &confidentialhttp.ConfidentialHTTPRequest{ - Request: &confidentialhttp.HTTPRequest{ - Url: config.URL, - Method: "POST", - Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: `{"auth": "{{.apiKey}}"}`}, - MultiHeaders: map[string]*confidentialhttp.HeaderValues{ - "Content-Type": {Values: []string{"application/json"}}, - }, - }, - VaultDonSecrets: []*confidentialhttp.SecretIdentifier{ - {Key: "apiKey"}, - }, - }).Await() - if err != nil { - return Result{}, err - } - // Parse and return... - return Result{}, nil +client := &confidentialhttp.Client{} +resp, err := client.SendRequest(runtime, &confidentialhttp.ConfidentialHTTPRequest{ + Request: &confidentialhttp.HTTPRequest{ + Url: config.URL, + Method: "POST", + Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: `{"auth": "{{.apiKey}}"}`}, + MultiHeaders: map[string]*confidentialhttp.HeaderValues{ + "Content-Type": {Values: []string{"application/json"}}, + "Authorization": {Values: []string{"Basic {{.apiKey}}"}}, + }, + EncryptOutput: false, }, - cre.ConsensusIdenticalAggregation[Result](), -).Await() + VaultDonSecrets: []*confidentialhttp.SecretIdentifier{ + {Key: "apiKey"}, + }, +}).Await() +if err != nil { + return Result{}, err +} +// Parse resp.Body... ``` **Guide:** [Making Confidential Requests](/cre/guides/workflow/using-confidential-http-client/making-requests-go) diff --git a/src/content/cre/llms-full-ts.txt b/src/content/cre/llms-full-ts.txt index 3f7a88df5f9..66946df5a57 100644 --- a/src/content/cre/llms-full-ts.txt +++ b/src/content/cre/llms-full-ts.txt @@ -9725,25 +9725,27 @@ type TransactionResult = { } ``` -### Step 4: Implement the fetch function +### Step 4: Implement the request and wire it into your workflow -Create the function that will be passed to `sendRequest()`. This function receives a `ConfidentialHTTPSendRequester` and your config as parameters: +Unlike the regular HTTP client, the Confidential HTTP client takes a `Runtime` directly and does not require `runInNodeMode` wrapping: ```typescript -import { type ConfidentialHTTPSendRequester, ok, json } from "@chainlink/cre-sdk" +import { CronCapability, ConfidentialHTTPClient, handler, ok, json, type Runtime, Runner } from "@chainlink/cre-sdk" + +const onCronTrigger = (runtime: Runtime): TransactionResult => { + const confHTTPClient = new ConfidentialHTTPClient() -const fetchTransaction = (sendRequester: ConfidentialHTTPSendRequester, config: Config): TransactionResult => { // 1. Send the confidential request - const response = sendRequester - .sendRequest({ + const response = confHTTPClient + .sendRequest(runtime, { request: { - url: config.url, + url: runtime.config.url, method: "GET", multiHeaders: { Authorization: { values: ["Basic {{.myApiKey}}"] }, }, }, - vaultDonSecrets: [{ key: "myApiKey", owner: config.owner }], + vaultDonSecrets: [{ key: "myApiKey", owner: runtime.config.owner }], }) .result() @@ -9753,37 +9755,13 @@ const fetchTransaction = (sendRequester: ConfidentialHTTPSendRequester, config: } // 3. Parse and return the result - return json(response) as TransactionResult -} -``` - -### Step 5: Wire it into your workflow - -In your trigger handler, call `confHTTPClient.sendRequest()` with your fetch function and a consensus method: - -```typescript -import { - CronCapability, - ConfidentialHTTPClient, - handler, - consensusIdenticalAggregation, - type Runtime, - Runner, -} from "@chainlink/cre-sdk" - -const onCronTrigger = (runtime: Runtime): string => { - const confHTTPClient = new ConfidentialHTTPClient() - - const result = confHTTPClient - .sendRequest(runtime, fetchTransaction, consensusIdenticalAggregation())(runtime.config) - .result() - + const result = json(response) as TransactionResult runtime.log(`Transaction result: ${result.transactionId} — ${result.status}`) - return result.transactionId + return result } ``` -### Step 6: Simulate +### Step 5: Simulate Run the simulation: @@ -9835,17 +9813,20 @@ export AES_KEY_ALL="your-256-bit-hex-encoded-key" 1. **Include the key in your `vaultDonSecrets`** and set `encryptOutput: true`: ```typescript - const response = sendRequester - .sendRequest({ + const response = confHTTPClient + .sendRequest(runtime, { request: { - url: config.url, + url: runtime.config.url, method: "GET", multiHeaders: { Authorization: { values: ["Basic {{.myApiKey}}"] }, }, + encryptOutput: true, }, - vaultDonSecrets: [{ key: "myApiKey", owner: config.owner }, { key: "san_marino_aes_gcm_encryption_key" }], - encryptOutput: true, + vaultDonSecrets: [ + { key: "myApiKey", owner: runtime.config.owner }, + { key: "san_marino_aes_gcm_encryption_key" }, + ], }) .result() ``` @@ -9867,17 +9848,7 @@ The SDK response helpers `ok()`, `text()`, and `json()` work with Confidential H Here's the full workflow code for a confidential HTTP request with secret injection: ```typescript -import { - CronCapability, - ConfidentialHTTPClient, - handler, - consensusIdenticalAggregation, - ok, - json, - type ConfidentialHTTPSendRequester, - type Runtime, - Runner, -} from "@chainlink/cre-sdk" +import { CronCapability, ConfidentialHTTPClient, handler, ok, json, type Runtime, Runner } from "@chainlink/cre-sdk" import { z } from "zod" // Config schema @@ -9895,18 +9866,20 @@ type TransactionResult = { status: string } -// Fetch function — receives a ConfidentialHTTPSendRequester and config -const fetchTransaction = (sendRequester: ConfidentialHTTPSendRequester, config: Config): TransactionResult => { - const response = sendRequester - .sendRequest({ +// Main workflow handler +const onCronTrigger = (runtime: Runtime): TransactionResult => { + const confHTTPClient = new ConfidentialHTTPClient() + + const response = confHTTPClient + .sendRequest(runtime, { request: { - url: config.url, + url: runtime.config.url, method: "GET", multiHeaders: { Authorization: { values: ["Basic {{.myApiKey}}"] }, }, }, - vaultDonSecrets: [{ key: "myApiKey", owner: config.owner }], + vaultDonSecrets: [{ key: "myApiKey", owner: runtime.config.owner }], }) .result() @@ -9914,19 +9887,9 @@ const fetchTransaction = (sendRequester: ConfidentialHTTPSendRequester, config: throw new Error(`HTTP request failed with status: ${response.statusCode}`) } - return json(response) as TransactionResult -} - -// Main workflow handler -const onCronTrigger = (runtime: Runtime): string => { - const confHTTPClient = new ConfidentialHTTPClient() - - const result = confHTTPClient - .sendRequest(runtime, fetchTransaction, consensusIdenticalAggregation())(runtime.config) - .result() - + const result = json(response) as TransactionResult runtime.log(`Transaction result: ${result.transactionId} — ${result.status}`) - return result.transactionId + return result } // Initialize workflow @@ -13560,10 +13523,9 @@ The [Confidential HTTP](/cre/capabilities/confidential-http-ts) Client lets you ## Quick reference -| Method | Description | -| --------------------------------------------------- | -------------------------------------------------------------------------------------- | -| [`sendRequest` (high-level)](#sendrequest) | **Recommended.** Makes a confidential HTTP request with built-in consensus and typing. | -| [`sendRequest` (low-level)](#low-level-sendrequest) | Makes a confidential HTTP request manually inside a `runInNodeMode` block. | +| Method | Description | +| ----------------------------- | ---------------------------------- | +| [`sendRequest`](#sendrequest) | Makes a confidential HTTP request. | ## Core types @@ -13580,22 +13542,22 @@ The top-level request type that combines an HTTP request with Vault DON secrets | ----------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | | `request` | `HTTPRequest` \| `HTTPRequestJson` | The HTTP request to execute inside the enclave. See [`HTTPRequest`](#httprequest--httprequestjson). | | `vaultDonSecrets` | `SecretIdentifier[]` \| `SecretIdentifierJson[]` | List of secrets to fetch from the Vault DON and make available in the enclave. See [`SecretIdentifier`](#secretidentifier--secretidentifierjson). | -| `encryptOutput` | `boolean` | If `true`, encrypts the response body before it leaves the enclave. See [Response encryption](#response-encryption). Default: `false`. | ### `HTTPRequest` / `HTTPRequestJson` Defines the HTTP request that will be executed inside the enclave. -| Field | Type | Description | -| ---------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------- | -| `url` | `string` | The URL of the API endpoint. | -| `method` | `string` | The HTTP method (e.g., `"GET"`, `"POST"`). | -| `bodyString` | `string` (optional) | The request body as a string template. Use this for secret injection with `{{.secretName}}` placeholders. | -| `bodyBytes` | `Uint8Array` \| `string` (optional) | The request body as raw bytes (base64-encoded in JSON format). | -| `multiHeaders` | `{ [key: string]: HeaderValues }` (optional) | Request headers. Supports multiple values per key and template syntax for secret injection. | -| `templatePublicValues` | `{ [key: string]: string }` (optional) | Public (non-secret) values used to fill template placeholders in the body and headers. | -| `customRootCaCertPem` | `Uint8Array` \| `string` (optional) | Optional custom root CA certificate (PEM format) for verifying the external server's TLS certificate. | -| `timeout` | `Duration` \| `DurationJson` (optional) | Optional request timeout (e.g., `"5s"`). | +| Field | Type | Description | +| ---------------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| `url` | `string` | The URL of the API endpoint. | +| `method` | `string` | The HTTP method (e.g., `"GET"`, `"POST"`). | +| `bodyString` | `string` (optional) | The request body as a string template. Use this for secret injection with `{{.secretName}}` placeholders. | +| `bodyBytes` | `Uint8Array` \| `string` (optional) | The request body as raw bytes (base64-encoded in JSON format). | +| `multiHeaders` | `{ [key: string]: HeaderValues }` (optional) | Request headers. Supports multiple values per key and template syntax for secret injection. | +| `templatePublicValues` | `{ [key: string]: string }` (optional) | Public (non-secret) values used to fill template placeholders in the body and headers. | +| `customRootCaCertPem` | `Uint8Array` \| `string` (optional) | Optional custom root CA certificate (PEM format) for verifying the external server's TLS certificate. | +| `timeout` | `Duration` \| `DurationJson` (optional) | Optional request timeout (e.g., `"5s"`). | +| `encryptOutput` | `boolean` (optional) | If `true`, encrypts the response body before it leaves the enclave. See [Response encryption](#response-encryption). Default: `false`. |