Skip to content
Merged
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
Expand Up @@ -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"}`

Expand All @@ -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)
Expand All @@ -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)
}
Expand Down Expand Up @@ -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()
```

Expand Down Expand Up @@ -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)
}
Expand All @@ -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{
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Config>): 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()
Expand All @@ -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<Config>): string => {
const confHTTPClient = new ConfidentialHTTPClient()

const result = confHTTPClient
.sendRequest(runtime, fetchTransaction, consensusIdenticalAggregation<TransactionResult>())(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:

Expand Down Expand Up @@ -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()
```
Expand All @@ -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
Expand All @@ -257,38 +228,30 @@ 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<Config>): 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()

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

return json(response) as TransactionResult
}

// Main workflow handler
const onCronTrigger = (runtime: Runtime<Config>): string => {
const confHTTPClient = new ConfidentialHTTPClient()

const result = confHTTPClient
.sendRequest(runtime, fetchTransaction, consensusIdenticalAggregation<TransactionResult>())(runtime.config)
.result()

const result = json(response) as TransactionResult
runtime.log(`Transaction result: ${result.transactionId} — ${result.status}`)
return result.transactionId
return result
}

// Initialize workflow
Expand Down
Loading
Loading